Added an arg for listing untagged files and added amount of files tagged with certain tags
parent
fb7f87fbbe
commit
f0b43360d8
|
@ -51,4 +51,7 @@ pub struct UntagArgs {
|
|||
#[derive(Debug, Args, PartialEq, Eq)]
|
||||
pub struct FilesArgs {
|
||||
pub query: Option<String>,
|
||||
|
||||
#[arg(long, short, exclusive = true, default_value_t = false)]
|
||||
pub all: bool,
|
||||
}
|
||||
|
|
67
src/tags.rs
67
src/tags.rs
|
@ -1,12 +1,16 @@
|
|||
use std::{
|
||||
fs,
|
||||
io::{self, Write},
|
||||
path::PathBuf,
|
||||
path::{self, PathBuf},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
|
||||
use rusqlite::{Connection, params, params_from_iter, types::Value};
|
||||
use rusqlite::{Connection, params_from_iter, types::Value};
|
||||
|
||||
pub const TERM_RESET: &str = "\x1b[0m";
|
||||
pub const TERM_BOLD: &str = "\x1b[1m";
|
||||
|
||||
use crate::{
|
||||
cli::{self, FilesArgs, TagArgs, TagsArgs, UntagArgs},
|
||||
|
@ -23,11 +27,19 @@ pub fn handle_files(args: FilesArgs) -> Result<()> {
|
|||
|
||||
let mut show_tags = true;
|
||||
|
||||
if let Some(query) = args.query {
|
||||
let mut paths: Vec<PathBuf> = vec![];
|
||||
if args.all {
|
||||
paths = fs::read_dir(".")?
|
||||
.filter_map(|f| f.ok())
|
||||
.filter(|f| f.metadata().is_ok() && f.metadata().unwrap().is_file())
|
||||
.map(|f| f.path())
|
||||
.collect();
|
||||
} else if let Some(query) = args.query {
|
||||
let path = PathBuf::from_str(&query).unwrap_or_default();
|
||||
match path.exists() {
|
||||
true => {
|
||||
sql.push_str(&format!(" WHERE path IN ('{}')", query));
|
||||
paths = vec![path];
|
||||
}
|
||||
false => {
|
||||
sql.push_str(&format!(" WHERE tag.name LIKE '%{}%'", query));
|
||||
|
@ -36,17 +48,30 @@ pub fn handle_files(args: FilesArgs) -> Result<()> {
|
|||
};
|
||||
}
|
||||
|
||||
let mut all_paths: Vec<String> = paths
|
||||
.iter_mut()
|
||||
.map(|f| f.to_string_lossy().replace("./", "").to_string())
|
||||
.collect();
|
||||
|
||||
sql.push_str(" GROUP BY path");
|
||||
|
||||
let mut stmt = conn.prepare(&sql)?;
|
||||
let result: Vec<(String, String)> = stmt
|
||||
let tagged_files: Vec<(String, String)> = stmt
|
||||
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let mut w = io::stdout();
|
||||
if !result.is_empty() {
|
||||
for (file, tags) in result {
|
||||
if !tagged_files.is_empty() {
|
||||
if args.all {
|
||||
writeln!(&mut w, "{TERM_BOLD}Tagged Files: {TERM_RESET}")?;
|
||||
}
|
||||
for (file, tags) in tagged_files {
|
||||
// Remove already tagged files
|
||||
if let Some(idx) = all_paths.iter().position(|v| *v == file) {
|
||||
all_paths.swap_remove(idx);
|
||||
}
|
||||
|
||||
if show_tags {
|
||||
writeln!(&mut w, "{}: {}", file, tags)?;
|
||||
} else {
|
||||
|
@ -56,6 +81,15 @@ pub fn handle_files(args: FilesArgs) -> Result<()> {
|
|||
} else {
|
||||
writeln!(&mut w, "No files registered!")?;
|
||||
}
|
||||
|
||||
if args.all && !all_paths.is_empty() {
|
||||
writeln!(&mut w, "\n{TERM_BOLD}Untagged Files: {TERM_RESET}")?;
|
||||
for path in all_paths {
|
||||
let path_str = path;
|
||||
writeln!(&mut w, "{}", path_str)?;
|
||||
}
|
||||
}
|
||||
|
||||
w.flush()?;
|
||||
|
||||
Ok(())
|
||||
|
@ -86,7 +120,7 @@ pub fn handle_tags(args: TagsArgs) -> Result<()> {
|
|||
let tags = list_tags(&conn)?;
|
||||
if !tags.is_empty() {
|
||||
for tag in tags {
|
||||
writeln!(&mut w, "{}", tag)?;
|
||||
writeln!(&mut w, "{} - {}", tag.0, tag.1)?;
|
||||
}
|
||||
} else {
|
||||
writeln!(&mut w, "No tags registered!")?;
|
||||
|
@ -108,13 +142,20 @@ fn rename_tag(conn: &Connection, old: String, new: String) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn list_tags(conn: &Connection) -> Result<Vec<String>> {
|
||||
let mut stmt = conn.prepare("SELECT name FROM tag")?;
|
||||
let result = stmt.query_map([], |row| row.get(0))?.flatten();
|
||||
fn list_tags(conn: &Connection) -> Result<Vec<(String, i32)>> {
|
||||
let mut stmt = conn.prepare(
|
||||
r#"SELECT name, COUNT() as count FROM tag
|
||||
INNER JOIN file_tag ON file_tag.tag_id = tag.id
|
||||
GROUP BY name
|
||||
ORDER BY count DESC"#,
|
||||
)?;
|
||||
let result = stmt
|
||||
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||
.flatten();
|
||||
|
||||
let mut tags = Vec::new();
|
||||
for name in result {
|
||||
tags.push(name);
|
||||
let mut tags: Vec<(String, i32)> = Vec::new();
|
||||
for entry in result {
|
||||
tags.push(entry);
|
||||
}
|
||||
|
||||
Ok(tags)
|
||||
|
|
Loading…
Reference in New Issue