Compare commits
6 Commits
fd358f5d3f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d21571561 | |||
| 821d301de3 | |||
| 6b5034c544 | |||
| 43a75c0b92 | |||
| 130287caa7 | |||
| 3df07d7622 |
1
misc_scripts/mount_truenas_music
Normal file
1
misc_scripts/mount_truenas_music
Normal file
@@ -0,0 +1 @@
|
||||
sudo mount -t cifs -o uid=arthurr,username=arthurr //truenas.local/Music /home/arthurr/TruenasMusic/
|
||||
@@ -1,4 +1,4 @@
|
||||
# TO BE NAMED
|
||||
# Quick Magic Finder
|
||||
|
||||
A quick way to search up Magic the Gathering (TM) cards for Linux (maybe MacOS? Don't have one, so haven't tried).
|
||||
|
||||
@@ -11,9 +11,9 @@ This repo has 2 main parts to it:
|
||||
* The `magic_finder` rust code, which does the "heavy lifting" of updating a database, searching through it for cards, and finding close names (kind of)
|
||||
* The supporting scripts which use [`rofi`](https://github.com/davatorium/rofi)
|
||||
|
||||
`magic_finder` can be used without the rofi parts if you wanted a command for loading showing basic mtg card info.
|
||||
`magic_finder` can be used without the rofi parts if you wanted a command for loading showing basic mtg card info from the CLI.
|
||||
|
||||
The `rofi` part is so that I can quickly and easily, with a couple of commands, get the card info I want. Basically just adds a very simple and easy GUI to the `magic_finder` part.
|
||||
The `rofi` part is so that I can quickly and easily get the card info I want. Basically just adds a very simple and easy GUI to the `magic_finder` part. I've written 2 wrapper scripts to enable this.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -37,20 +37,20 @@ I am sorry in advance, this is a bit of a pain becuase of my lack of knowledge o
|
||||
|
||||
**TODO - don't forget that I need to install sqlite3-lib/dev/something - or maybe I add the feature flag "bundled"**
|
||||
|
||||
*TODO - don't forget about adding the shortcut to the overall wrapper script*
|
||||
|
||||
## Before you use this
|
||||
|
||||
## Update
|
||||
Basically the same as the "Before you use this" secion. Go to the [Scryfall Bulk Download](https://scryfall.com/docs/api/bulk-data) page and get the Oracle Cards download.
|
||||
|
||||
Then run the `update_with_rofi.sh` script, locate the downloaded file, and it should Just Work (TM). If not, try updating this repo. If it still doesn't work, log a ticket. It's probably going to something with Scryfall updating their schema that I haven't accounted for.
|
||||
Then run the `update_with_rofi.sh` script, locate the downloaded file, and it should Just Work (TM). If not, try updating this repo. If it still doesn't work, log a ticket. It's probably going to something with Scryfall updating their schema that I haven't accounted for. Alternatively, run `COMMAND --update <path to file>` where `<path to file>` is the full path to where you downloaded the file.
|
||||
|
||||
Alternatively, run `COMMAND --update <path to file>` where `<path to file>` is the full path to where you downloaded the file.
|
||||
|
||||
This will delete the previous db - that shouldn't be a problem though, because you shouldn't use that unless you really know what you're doing.
|
||||
NOTE: Updating *will* delete the previous db - that shouldn't be a problem though, because you shouldn't use that unless you really know what you're doing.
|
||||
|
||||
## Why this exists
|
||||
|
||||
I often watch Magic the Gathering (TM) videos while coding, working, writing, whatever, and, often, I don't know what card they're talking about. They'll often say the card name (sometimes a nickname - this doesn't help with that), and show it on the screen briefly (or in a tiny/obscured view), and I'll miss what it actually does. When this happens, I need to open a tab on my browser, go to [Scryfall](scryfall.com), type in the name, (sometimes) click the specific card, and the view it. This takes 2-3 page loads, changing my active window and just a bit of a pain.
|
||||
I like watch Magic the Gathering (TM) videos, expecially while coding, working, writing, whatever. Often, I don't know what card they're talking about. They'll often say the card name (sometimes a nickname - this tool doesn't help with that), and show it on the screen briefly (or in a tiny/obscured view), and I'll miss what it actually does. When this happens, I need to open a tab on my browser, go to [Scryfall](scryfall.com), type in the name, (sometimes) click the specific card, and the view it. This takes 2-3 page loads, changing my active window and just a bit of a pain.
|
||||
|
||||
This tool, especially using `rofi` enables me to hit `Ctrl+M`, type in the card name, navigate to the card (if needed) with my keyboard, and display the card. No browser, no HTTP, lower context switch, displayed right there, and goes away when I press anything else.
|
||||
|
||||
@@ -90,11 +90,19 @@ Fingers crossed that all compiled and stuff... then copy the bin
|
||||
cp build/rofi ~/bin
|
||||
```
|
||||
|
||||
## TODO & Features That Could be Good
|
||||
## FIXME, TODO & Features That Could be Good
|
||||
* Remove the non-card cards. Examples I've come across are:
|
||||
** Planes: Black Lotus Lounge
|
||||
** Art Cards: https://scryfall.com/card/altr/15/%C3%A9owyn-fearless-knight-%C3%A9owyn-fearless-knight?utm_source=api
|
||||
* Allow exiting the script early (i.e. I hit CTRL+g just exits everything)
|
||||
* Misspelled cards, if only 1 hit that makes sense, could just work
|
||||
* Display the actual card image (probably won't do this)
|
||||
* Some kind of auto-magic direct link between the return codes set out in `main.r`s and the `rofi` scripts. Currently I need to manually make sure they're the same between the `rust` code and the `sh` code.
|
||||
I'm guessing would involve cargo build scripts (or just a find+replace?)
|
||||
* Add some classic nicknames (might be difficult to find them all). examples include:
|
||||
** Bob - Dark Confidant
|
||||
** AK - Accumulated Knowledge
|
||||
** find more here: https://mtg.wiki/page/List_of_Magic_slang/Card_nicknames
|
||||
|
||||
## Thanks
|
||||
|
||||
|
||||
@@ -1,44 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
CARDS=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser $@)
|
||||
RETURN=$?
|
||||
echo $RETURN
|
||||
|
||||
if [ $RETURN -eq 0 ]; then
|
||||
|
||||
SELECTION=$(rofi -dmenu -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARD_OUTPUT=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser --exact $SELECTION)
|
||||
|
||||
# If you double check the first rofi selection it seems to prevent the error window from popping up
|
||||
# I think this is because it registers the second click as a click outside the window which exits
|
||||
# the rofi -e message
|
||||
sleep 0.05
|
||||
|
||||
rofi -e "$CARD_OUTPUT"
|
||||
fi
|
||||
|
||||
if [ $RETURN -eq 105 ]; then
|
||||
|
||||
SELECTION=$(rofi -dmenu -p "Did you mean?" -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARDS=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser $SELECTION)
|
||||
|
||||
SELECTION=$(rofi -dmenu -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARD_OUTPUT=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser --exact $SELECTION)
|
||||
|
||||
sleep 0.05
|
||||
|
||||
rofi -e "$CARD_OUTPUT"
|
||||
|
||||
fi
|
||||
SEARCH_STRING=$(rofi -l 0 -dmenu)
|
||||
/home/arthurr/code/mini_projects/scryfall_deser/scripts/search_with_rofi_with_args.sh $SEARCH_STRING
|
||||
|
||||
74
scryfall_deser/scripts/search_with_rofi_with_args.sh
Executable file
74
scryfall_deser/scripts/search_with_rofi_with_args.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Note to self in this... The whitespace seemed to fuck the ifs up. Not sure why.
|
||||
# This is why it's all flat and ugly
|
||||
|
||||
CARDS=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser $@)
|
||||
RETURN=$?
|
||||
echo $RETURN
|
||||
|
||||
#######################
|
||||
## Exact card found - just print the card
|
||||
#######################
|
||||
if [ $RETURN -eq 200 ]; then
|
||||
|
||||
rofi -e "$CARDS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
#######################
|
||||
## Cards to select from
|
||||
#######################
|
||||
if [ $RETURN -eq 0 ]; then
|
||||
|
||||
SELECTION=$(rofi -dmenu -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARD_OUTPUT=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser --exact $SELECTION)
|
||||
|
||||
# If you double check the first rofi selection it seems to prevent the error window from popping up
|
||||
# I think this is because it registers the second click as a click outside the window which exits
|
||||
# the rofi -e message
|
||||
sleep 0.05
|
||||
|
||||
rofi -e "$CARD_OUTPUT"
|
||||
fi
|
||||
|
||||
##########################
|
||||
## Not even one card that matched - try a close string
|
||||
##########################
|
||||
if [ $RETURN -eq 105 ]; then
|
||||
|
||||
# TODO do something different with no matching string at all - perhaps even a different ExitCode?
|
||||
|
||||
SELECTION=$(rofi -dmenu -p "Did you mean?" -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARDS=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser $SELECTION)
|
||||
|
||||
SELECTION=$(rofi -dmenu -i << EOF
|
||||
$CARDS
|
||||
EOF
|
||||
)
|
||||
|
||||
CARD_OUTPUT=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser --exact $SELECTION)
|
||||
|
||||
sleep 0.05
|
||||
|
||||
rofi -e "$CARD_OUTPUT"
|
||||
|
||||
fi
|
||||
|
||||
###############################
|
||||
## No seach string input at all
|
||||
###############################
|
||||
if [ $RETURN -eq 101 ]; then
|
||||
|
||||
rofi -e "No search string found"
|
||||
|
||||
fi
|
||||
@@ -1,5 +1,6 @@
|
||||
use deunicode::deunicode;
|
||||
use rusqlite;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
@@ -75,6 +76,26 @@ impl fmt::Display for DbCard {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for DbCard {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.name.cmp(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for DbCard {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for DbCard {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for DbCard {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DbCard {
|
||||
pub name: String,
|
||||
@@ -105,6 +126,8 @@ pub fn get_card_by_name(name: &str, name_type: GetNameType) -> Option<DbCard> {
|
||||
FROM cards WHERE lowercase_name = (?1)"
|
||||
}
|
||||
};
|
||||
dbg!(name);
|
||||
dbg!(&sql);
|
||||
let mut stmt = conn.prepare(sql).unwrap();
|
||||
let mut rows = stmt.query([name]).unwrap();
|
||||
match rows.next().unwrap() {
|
||||
|
||||
@@ -17,12 +17,16 @@ impl Termination for MtgCardExit {
|
||||
MtgCardExit::EmptySearchString => ExitCode::from(101),
|
||||
MtgCardExit::NoExactMatchCard => ExitCode::from(102),
|
||||
MtgCardExit::DidYouMean => ExitCode::from(105),
|
||||
MtgCardExit::ExactCardFound => ExitCode::from(200),
|
||||
MtgCardExit::UpdateSuccess => ExitCode::from(201),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum MtgCardExit {
|
||||
Success,
|
||||
UpdateSuccess,
|
||||
ExactCardFound,
|
||||
EmptySearchString,
|
||||
NoExactMatchCard,
|
||||
DidYouMean,
|
||||
@@ -51,7 +55,7 @@ fn exact_search(search_strings: Vec<String>) -> MtgCardExit {
|
||||
}
|
||||
Some(c) => {
|
||||
println!("{}", c);
|
||||
MtgCardExit::Success
|
||||
MtgCardExit::ExactCardFound
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,11 +78,12 @@ fn main() -> MtgCardExit {
|
||||
init_db();
|
||||
let mut path = get_local_cache_folder();
|
||||
path.push(update);
|
||||
// FIXME - if you pass a bad file or something, it just deletes the db
|
||||
update_db_with_file(path);
|
||||
return MtgCardExit::Success;
|
||||
return MtgCardExit::UpdateSuccess;
|
||||
}
|
||||
if args.search_text.is_empty() {
|
||||
println!("You need to put some card text to search");
|
||||
dbg!("You need to put some card text to search");
|
||||
return MtgCardExit::EmptySearchString;
|
||||
}
|
||||
|
||||
@@ -87,7 +92,9 @@ fn main() -> MtgCardExit {
|
||||
return res;
|
||||
}
|
||||
|
||||
let matching_cards = find_matching_cards_scryfall_style(&args.search_text);
|
||||
let mut matching_cards = find_matching_cards_scryfall_style(&args.search_text);
|
||||
dbg!(&args.search_text);
|
||||
dbg!(&matching_cards);
|
||||
|
||||
if matching_cards.is_empty() {
|
||||
let mtg_words = get_all_mtg_words();
|
||||
@@ -106,10 +113,13 @@ fn main() -> MtgCardExit {
|
||||
}
|
||||
return MtgCardExit::DidYouMean;
|
||||
} else if matching_cards.len() == 1 {
|
||||
let card = get_card_by_name(&matching_cards[0].name, GetNameType::LowercaseName).unwrap();
|
||||
// FIXME - theres a bug in here - try searching Nalf
|
||||
let card = get_card_by_name(&matching_cards[0].name, GetNameType::Name).unwrap();
|
||||
println!("{}", card);
|
||||
return MtgCardExit::Success;
|
||||
// TODO update this to be more meaningful
|
||||
return MtgCardExit::ExactCardFound;
|
||||
} else {
|
||||
matching_cards.sort();
|
||||
for card in matching_cards {
|
||||
println!(
|
||||
"{}",
|
||||
@@ -118,6 +128,7 @@ fn main() -> MtgCardExit {
|
||||
.name
|
||||
);
|
||||
}
|
||||
// TODO update this to be more meaningful
|
||||
return MtgCardExit::Success;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user