summaryrefslogtreecommitdiff
path: root/src/kona-cli.rs
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2020-07-26 19:23:37 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2020-07-26 19:23:37 -0400
commitb311644824bc0bff9603fea69d979fa6bb4b97e0 (patch)
tree221b0b6a5f1a90f953ecf03445fe6aed17ffee6b /src/kona-cli.rs
parent45b48fd9b9ee21759701d3d4f445d8bf141d3f9e (diff)
Rebrand (again).
Diffstat (limited to 'src/kona-cli.rs')
-rw-r--r--src/kona-cli.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/kona-cli.rs b/src/kona-cli.rs
new file mode 100644
index 0000000..04adfc8
--- /dev/null
+++ b/src/kona-cli.rs
@@ -0,0 +1,121 @@
+// Copyright © 2020 Jakob L. Kreuze <zerodaysfordays@sdf.org>
+//
+// This file is part of Kona.
+//
+// Kona is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or (at
+// your option) any later version.
+//
+// Kona is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+// License for more details.
+//
+// You should have received a copy of the GNU Affero General Public
+// License along with Kona. If not, see <http://www.gnu.org/licenses/>.
+
+#[macro_use]
+extern crate anyhow;
+extern crate dirs;
+#[macro_use]
+extern crate rusqlite;
+
+mod database;
+
+use database::TagDatabase;
+use std::env;
+use std::path::Path;
+
+fn main() {
+ let mut args: Vec<String> = env::args().collect();
+ if args.len() < 2 || args.iter().any(|arg| arg == "-h" || arg == "--help") {
+ println!("usage: {} ACTION [ARGS ...]", args[0]);
+ println!();
+ println!("\t-o, --output [PATH]: Path to the tag database.");
+ println!();
+ println!("\tACTION: add [PATH] [TAGS ...]: index an image, optionally tagged.");
+ println!("\tACTION: remove [PATH]: remove an image from the database.");
+ println!("\tACTION: add_tags [PATH] [TAGS ...]: add tags to an indexed image.");
+ println!("\tACTION: remove_tags [PATH] [TAGS ...]: remove tags from an indexed image.");
+ println!("\tACTION: query [QUERY_STRING]: list images in the database.");
+ std::process::exit(1);
+ }
+
+ let tb = if let Some(i) = args.iter().position(|x| x == "-o" || x == "--output") {
+ // Ensure that a path follows the "-o" argument.
+ if i + 1 >= args.len() {
+ eprintln!("{} requires an argument", args[i]);
+ std::process::exit(1);
+ }
+
+ args.remove(i);
+ TagDatabase::new(args.remove(i + 1))
+ } else if let Ok(path) = std::env::var("TB_PATH") {
+ TagDatabase::new(path)
+ } else {
+ TagDatabase::new("./kona.db")
+ }
+ .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]).canonicalize().unwrap();
+ if path.is_dir() {
+ eprintln!("'{}' is a directory", args[2]);
+ }
+
+ tb.add_file(&path, &args[3..].to_vec()).unwrap();
+ }
+ "remove" => {
+ if args.len() < 3 {
+ eprintln!("usage: {} remove PATH", args[0]);
+ std::process::exit(1);
+ }
+
+ let file = tb.file_by_path(&args[2]).unwrap();
+ tb.remove_file(file.id).unwrap();
+ }
+ "add_tags" => {
+ if args.len() < 3 {
+ eprintln!("usage: {} add_tags PATH [TAGS ...]", args[0]);
+ std::process::exit(1);
+ }
+ let file = tb.file_by_path(&args[2]).unwrap();
+ tb.tag_file(file.id, &args[3..].to_vec()).unwrap();
+ }
+ "remove_tags" => {
+ if args.len() < 3 {
+ eprintln!("usage: {} remove_tags PATH [TAGS ...]", args[0]);
+ std::process::exit(1);
+ }
+ let file = tb.file_by_path(&args[2]).unwrap();
+ tb.untag_file(file.id, &args[3..].to_vec()).unwrap();
+ }
+ "query" => {
+ let query = if args.len() < 3 {
+ database::parse_query("").unwrap()
+ } else {
+ database::parse_query(&args[2]).unwrap()
+ };
+ for file in tb.query(&query, None).unwrap() {
+ println!("{}", file.path);
+ }
+ }
+ "tags" => {
+ for (count, tag) in tb.top_tags(None).unwrap() {
+ println!("{}: {}", count, tag);
+ }
+ }
+ _ => {
+ eprintln!("Unknown action '{}'", action);
+ std::process::exit(1);
+ }
+ }
+}