diff options
| -rw-r--r-- | Cargo.lock | 135 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/main.rs | 69 |
3 files changed, 194 insertions, 11 deletions
@@ -7,6 +7,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" [[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] name = "base64" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -31,12 +55,46 @@ dependencies = [ ] [[package]] +name = "blake2b_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] name = "byte-tools" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] name = "crypto-mac" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -56,6 +114,28 @@ dependencies = [ ] [[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if", + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +dependencies = [ + "cfg-if", + "libc", + "redox_users", + "winapi", +] + +[[package]] name = "fallible-iterator" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -77,6 +157,23 @@ dependencies = [ ] [[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] name = "libc" version = "0.2.70" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -126,12 +223,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "redox_users" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + +[[package]] name = "roru" version = "0.1.0" dependencies = [ "anyhow", - "base64", + "base64 0.12.1", "blake2", + "dirs", "rusqlite", ] @@ -151,6 +266,18 @@ dependencies = [ ] [[package]] +name = "rust-argon2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" +dependencies = [ + "base64 0.11.0", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] name = "subtle" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -179,6 +306,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11,6 +11,7 @@ license = "AGPL-3.0+" anyhow = "1.0.31" base64 = "0.12.1" blake2 = "0.8" +dirs = "2.0.2" [dependencies.rusqlite] version = "0.21.0" diff --git a/src/main.rs b/src/main.rs index 4b3fcc1..db43ea9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,10 +17,12 @@ #[macro_use] extern crate anyhow; +extern crate dirs; use anyhow::Result; use blake2::{Blake2b, Digest}; use rusqlite::{params, Connection}; +use std::env; use std::io; use std::path::Path; @@ -167,7 +169,10 @@ impl TagBase { /// Return the intersection of the sets of images matching each of `tags`. fn images_by_tags(&self, tags: &[&str]) -> Result<Vec<Image>> { - let ids = tags.iter().map(|tag| self.tag_id(tag)); + let ids: Vec<i64> = tags + .iter() + .filter_map(|tag| self.tag_id(tag).ok()) + .collect(); let mut tags = Vec::from(tags); tags.dedup(); @@ -181,16 +186,16 @@ impl TagBase { ON images.id = mapping.image", ) } else { - (1..tags.len() + 1) - .zip(tags) + (1..ids.len() + 1) + .zip(ids) .map(|pair| { - let (n, tag) = pair; + let (n, id) = pair; format!( "INNER JOIN mapping as m{n} ON images.id = m{n}.image AND {id} = m{n}.tag", n = n, - id = tag + id = id ) }) .collect::<Vec<String>>() @@ -314,9 +319,53 @@ mod tests { } fn main() { - let tb = TagBase::new("/tmp/test.db").unwrap(); - let path = Path::new("/home/jakob/Sync/06fc9ae71549eb4d.jpeg"); - let hash = hash_file(path).unwrap(); - tb.import_image(path, &hash).unwrap(); - println!("{:?}", tb); + let args: Vec<String> = env::args().collect(); + if args.len() < 2 { + eprintln!("usage: {} ACTION [ARGS ...]", args[0]); + std::process::exit(1); + } + + let tb = if let Ok(val) = env::var("TB_PATH") { + TagBase::new(&val) + } else { + if let Some(dir) = dirs::config_dir() { + TagBase::new(dir.join("pometka.db").to_str().unwrap()) + } else { + TagBase::new(Path::new("/tmp").join("pometka.db").to_str().unwrap()) + } + } + .unwrap(); + + let action = &args[1]; + match action.to_lowercase().as_str() { + "add" => { + if args.len() < 3 { + eprintln!("usage: {} add PATH [TAGS ...]", args[0]); + std::process::exit(1); + } + let path = Path::new(&args[2]); + let hash = hash_file(path).unwrap(); + let id = tb.import_image(path, &hash).unwrap(); + for arg in args[3..].iter() { + tb.add_tag(arg).unwrap(); + tb.tag_image(id, arg).unwrap(); + } + } + "query" => { + let tags = args[2..].iter().map(|s| s.as_str()).collect::<Vec<&str>>(); + for tag in tags.iter() { + if let Err(_) = tb.tag_id(tag) { + eprintln!("unknown tag: {}", tag); + std::process::exit(1); + } + } + for image in tb.images_by_tags(&tags[..]).unwrap() { + println!("{}/{}", image.orig_dir, image.filename); + } + } + _ => { + eprintln!("Unknown action '{}'", action); + std::process::exit(1); + } + } } |