diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2020-06-06 18:58:52 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2020-06-06 18:58:52 -0400 |
| commit | 0f0d4477a4eab8ec0b99c134154ce0fedb4d6400 (patch) | |
| tree | 34b28406cde6489726a65b67bc00e1eea78f018f | |
| parent | 52adceb6be36c121d3cfb16e7bf29ec4889dc6ec (diff) | |
Clean up for release.
| -rw-r--r-- | Cargo.toml | 14 | ||||
| -rw-r--r-- | src/birka-cli.rs | 10 | ||||
| -rw-r--r-- | src/database.rs | 107 | ||||
| -rw-r--r-- | static/css/style.css | 6 |
4 files changed, 76 insertions, 61 deletions
@@ -15,21 +15,17 @@ dirs = "2.0.2" rusqlite = "0.21.0" # Until RFC #2887 is merged, image and rocket are deps of the CLI tool as well. -image = "0.23.4" -rocket = "0.4.4" +image = "0.23" +rocket = "0.4" +rocket_contrib = { version = "0.4", default-features = false, features = ["handlebars_templates", "json", "serve"] } serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -[dependencies.rocket_contrib] -version = "0.4.4" -default-features = false -features = ["handlebars_templates", "json", "serve"] - [[bin]] name = "birka-cli" path = "src/birka-cli.rs" [[bin]] -name = "birka" -path = "src/main.rs" +name = "birka-web" +path = "src/birka-web.rs" diff --git a/src/birka-cli.rs b/src/birka-cli.rs index e74fcd7..3fd5420 100644 --- a/src/birka-cli.rs +++ b/src/birka-cli.rs @@ -18,10 +18,12 @@ #[macro_use] extern crate anyhow; extern crate dirs; +#[macro_use] +extern crate rusqlite; mod database; -use database::{hash_file, TagDatabase}; +use database::TagDatabase; use std::env; use std::path::Path; @@ -35,9 +37,9 @@ fn main() { let tb = if let Ok(val) = env::var("TB_PATH") { TagDatabase::new(&val) } else if let Some(dir) = dirs::config_dir() { - TagDatabase::new(dir.join("birka.db").to_str().unwrap()) + TagDatabase::new(&dir.join("birka.db")) } else { - TagDatabase::new(Path::new("/tmp").join("pometka.db").to_str().unwrap()) + TagDatabase::new(&Path::new("/tmp").join("birka.db")) } .unwrap(); @@ -49,7 +51,7 @@ fn main() { std::process::exit(1); } let path = Path::new(&args[2]).canonicalize().unwrap(); - let hash = hash_file(&path).unwrap(); + let hash = database::hash_file(&path).unwrap(); let id = tb.import_image(&path, &hash).unwrap(); for arg in args[3..].iter() { tb.add_tag(arg).unwrap(); diff --git a/src/database.rs b/src/database.rs index b83fc9b..14ff853 100644 --- a/src/database.rs +++ b/src/database.rs @@ -17,25 +17,79 @@ use anyhow::Result; use blake2::{Blake2b, Digest}; -use rusqlite::{params, Connection}; +use rusqlite::Connection; + +use std::convert::AsRef; use std::io; use std::path::Path; -/// A connection to бирка-тян's tag database. +/// A connection to the tag database. #[derive(Debug)] pub struct TagDatabase(Connection); /// Tag query with a sense of "state" for pagination. #[derive(Debug)] pub struct Query<'a> { - pub tags: &'a [&'a str], - pub last_id: Option<i64>, - pub limit: Option<i64>, + tags: &'a [&'a str], + last_id: Option<i64>, + limit: Option<i64>, +} + +impl<'a> Query<'a> { + /// Construct a new query for images tagged with `tags`. + /// + /// When given to the database, this query will return at most `limit` + /// results, if specified, and will return only images newer than `last_id`, + /// if specified. + pub fn new(tags: &'a [&'a str], last_id: Option<i64>, limit: Option<i64>) -> Self { + Query { + tags, + last_id, + limit, + } + } +} + +/// The result of an image query in бирка-тян's tag database. +#[derive(Debug)] +pub struct Image { + pub id: i64, + pub blake2: String, + pub filename: String, + pub orig_dir: String, +} + +/// Return a base64-encoded BLAKE2b hash identifying the file at `path`. +pub fn hash_file(path: &Path) -> Result<String> { + let mut file = std::fs::File::open(path)?; + let mut hasher = Blake2b::new(); + io::copy(&mut file, &mut hasher)?; + Ok(base64::encode(&hasher.result())) +} + +/// Split the path into a tuple containing the parent directory and the filename. +pub fn split_path(path: &Path) -> Result<(String, String)> { + if path.is_dir() { + bail!("`path` does not name a file."); + } + + let file_name = path + .file_name() + .and_then(|os| os.to_str()) + .ok_or(anyhow!("Couldn't parse file name."))?; + + // Convert `path` to a string and strip off the `file_name` we've just + // obtained to yield the name of the parent directory. + let path = path.to_str().ok_or(anyhow!("Couldn't parse path."))?; + let split_index = path.len() - file_name.len(); + let parent_directory = &path[0..split_index]; + + Ok((file_name.to_string(), parent_directory.to_string())) } impl TagDatabase { /// Instantiate a new `TagDatabase` whose backing database is at `path`. - pub fn new(path: &str) -> Result<Self> { + pub fn new<T: AsRef<Path>>(path: &T) -> Result<Self> { let tb = TagDatabase(Connection::open(path)?); tb.initialize_tables()?; Ok(tb) @@ -90,29 +144,9 @@ impl TagDatabase { .query_row(params![tag], |row| Ok(row.get::<_, i64>(0)))??) } - /// Split the path into a tuple containing the parent directory and the filename. - fn split_path(&self, path: &Path) -> Result<(String, String)> { - if path.is_dir() { - bail!("`path` does not name a file."); - } - - let file_name = path - .file_name() - .and_then(|os| os.to_str()) - .ok_or(anyhow!("Couldn't parse file name."))?; - - // Convert `path` to a string and strip off the `file_name` we've just - // obtained to yield the name of the parent directory. - let path = path.to_str().ok_or(anyhow!("Couldn't parse path."))?; - let split_index = path.len() - file_name.len(); - let parent_directory = &path[0..split_index]; - - Ok((file_name.to_string(), parent_directory.to_string())) - } - /// Insert the image at `path` into the data. pub fn import_image(&self, path: &Path, hash: &str) -> Result<i64> { - let (file_name, parent_directory) = self.split_path(path)?; + let (file_name, parent_directory) = split_path(path)?; Ok(self .0 .prepare("INSERT INTO images (blake2, filename, orig_dir) VALUES(?,?,?)")? @@ -121,7 +155,7 @@ impl TagDatabase { /// Return the internal id for the image at `path`. pub fn image_id(&self, path: &Path) -> Result<i64> { - let (file_name, path) = self.split_path(path)?; + let (file_name, path) = split_path(path)?; Ok(self .0 .prepare("SELECT id FROM images WHERE orig_dir = ? AND filename = ?")? @@ -290,23 +324,6 @@ impl TagDatabase { } } -/// The result of an image query in бирка-тян's tag database. -#[derive(Debug)] -pub struct Image { - pub id: i64, - pub blake2: String, - pub filename: String, - pub orig_dir: String, -} - -/// Return a base64-encoded BLAKE2b hash identifying the file at `path`. -pub fn hash_file(path: &Path) -> Result<String> { - let mut file = std::fs::File::open(path)?; - let mut hasher = Blake2b::new(); - io::copy(&mut file, &mut hasher)?; - Ok(base64::encode(&hasher.result())) -} - #[cfg(test)] mod tests { use super::*; diff --git a/static/css/style.css b/static/css/style.css index f50fa36..b32823e 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1,12 +1,12 @@ body { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(6, 1fr); grid-gap: 10px; grid-auto-rows: minmax(50px, auto); } header { - grid-column: 1 / 3; + grid-column: 1 / 6; grid-row: 1; } @@ -16,5 +16,5 @@ aside { } main { - grid-column: 2 /3; + grid-column: 2 / 6; grid-row: 2 |