Mass renames and tagging

master
Wynd 2025-05-05 23:58:41 +03:00
parent f9522d3503
commit fd8af1daa8
3 changed files with 50 additions and 10 deletions

View File

@ -13,7 +13,16 @@ pub struct CliArgs {
pub enum Commands {
Init,
Untag(UntagArgs),
Tag(TagArgs),
Tag {
#[clap(flatten)]
args: TagArgs,
#[arg(short, long, requires = "file_tags", value_delimiter = ' ', num_args = 1..)]
files: Vec<PathBuf>,
#[arg(short('t'), long("tags"), requires = "files", value_delimiter = ' ', num_args = 1..)]
file_tags: Vec<String>,
},
Tags(TagsArgs),
Files(FilesArgs),
}
@ -31,13 +40,15 @@ pub enum TagsCommands {
List,
Add { add: Vec<String> },
Remove { remove: Vec<String> },
Rename { old: String, new: String },
Rename { renames: Vec<String> },
}
#[derive(Debug, Args, PartialEq, Eq)]
pub struct TagArgs {
pub file: PathBuf,
// #[clap(conflicts_with = "files")]
pub file: Option<PathBuf>,
// #[clap(conflicts_with = "files")]
pub tags: Vec<String>,
}

View File

@ -13,7 +13,11 @@ fn main() -> anyhow::Result<()> {
match args.commands {
cli::Commands::Init => init_db().map_err(|_| anyhow!("Database already exists!")),
cli::Commands::Tag(args) => tags::handle_tag(args),
cli::Commands::Tag {
args,
files,
file_tags,
} => tags::handle_tag(args, files, file_tags),
cli::Commands::Untag(args) => tags::handle_untag(args),
cli::Commands::Tags(args) => tags::handle_tags(args),
cli::Commands::Files(args) => tags::handle_files(args),

View File

@ -95,10 +95,17 @@ pub fn handle_files(args: FilesArgs) -> Result<()> {
Ok(())
}
pub fn handle_tag(args: TagArgs) -> Result<()> {
pub fn handle_tag(args: TagArgs, files: Vec<PathBuf>, file_tags: Vec<String>) -> Result<()> {
let mut conn = try_database()?;
tag_file(&mut conn, args.file, args.tags)?;
if let Some(file) = args.file {
tag_file(&mut conn, &file, &args.tags)?;
} else {
// TODO: Maybe rework this at some point so its more optimized for batch insertion ?
for file in &files {
tag_file(&mut conn, file, &file_tags)?;
}
}
Ok(())
}
@ -130,14 +137,32 @@ pub fn handle_tags(args: TagsArgs) -> Result<()> {
}
Some(cli::TagsCommands::Add { add }) => add_tags(&mut conn, add),
Some(cli::TagsCommands::Remove { remove }) => remove_tags(&mut conn, remove),
Some(cli::TagsCommands::Rename { old, new }) => rename_tag(&conn, old, new),
Some(cli::TagsCommands::Rename { renames }) => rename_tag(&conn, renames),
}
}
fn rename_tag(conn: &Connection, old: String, new: String) -> Result<()> {
fn rename_tag(conn: &Connection, renames: Vec<String>) -> Result<()> {
if renames.is_empty() {
return Err(anyhow!("No input found!"));
} else if renames.len() % 2 != 0 {
return Err(anyhow!(
"Attempting to rename an uneven amount of entries: {}",
renames.len()
));
}
let mut stmt = conn.prepare("UPDATE tag SET name = ? WHERE name = ?")?;
stmt.execute([&new, &old])?;
let mut i = 0;
while i < renames.len() {
// TODO: Merge this when let chaining is stabilized in 1.88
if let Some(old) = renames.get(i) {
if let Some(new) = renames.get(i + 1) {
stmt.execute([&new, &old])?;
}
}
i += 2;
}
Ok(())
}
@ -217,7 +242,7 @@ fn add_tags(conn: &mut Connection, tags: Vec<String>) -> Result<()> {
Ok(())
}
fn tag_file(conn: &mut Connection, file: PathBuf, tags: Vec<String>) -> Result<()> {
fn tag_file(conn: &mut Connection, file: &PathBuf, tags: &Vec<String>) -> Result<()> {
let file = file
.to_str()
.ok_or(anyhow!("Unable to find path {:?}", file))?