feat: add subcommands for importing and showing tags

This commit is contained in:
2026-08-22 17:02:43 +02:00
parent e739ed3294
commit fa31b6f48d
+33 -29
View File
@@ -1,4 +1,4 @@
use clap::Parser; use clap::{Parser, Subcommand};
use lofty::file::TaggedFileExt; use lofty::file::TaggedFileExt;
use lofty::probe::Probe; use lofty::probe::Probe;
use lofty::tag::Accessor; use lofty::tag::Accessor;
@@ -9,60 +9,64 @@ use std::path::PathBuf;
#[derive(Parser)] #[derive(Parser)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
struct Args { struct Args {
file: PathBuf, #[command(subcommand)]
command: Commands,
}
#[arg(short)] #[derive(Subcommand)]
import: bool, enum Commands {
Import { file: PathBuf },
#[arg(short)] Show { file: PathBuf },
show: bool,
} }
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse(); let args = Args::parse();
let file_path = args.file;
match &args.command {
Commands::Import { file } => {
println!("Importing file: {:?}", file);
let tag = get_metadata(file.to_path_buf());
let _ = move_files(file.clone(), tag.clone());
}
Commands::Show { file } => {
println!("Show file: {:?}", file);
let tag = get_metadata(file.to_path_buf());
println!("{}", tag.title().as_deref().unwrap_or("None"));
for item in tag.items() {
println!("{:?}", item)
}
let album_artist = tag.get_string(lofty::tag::ItemKey::AlbumArtist);
println!("AlbumArtist: {:?}", album_artist);
}
}
Ok(())
}
fn get_metadata(file_path: PathBuf) -> lofty::tag::Tag {
let tagged_file = Probe::open(&file_path) let tagged_file = Probe::open(&file_path)
.expect("ERROR: Bad path provided!") .expect("ERROR: Bad path provided!")
.read() .read()
.expect("ERROR: Failed to read file!"); .expect("ERROR: Failed to read file!");
let id3v2 = tagged_file.primary_tag();
let tag = match tagged_file.primary_tag() { let tag = match tagged_file.primary_tag() {
Some(primary_tag) => primary_tag, Some(primary_tag) => primary_tag,
None => tagged_file.first_tag().expect("ERROR: No tags found!"), None => tagged_file.first_tag().expect("ERROR: No tags found!"),
}; };
tag.clone()
println!("{}", tag.title().as_deref().unwrap_or("None"));
let album_artist = tag.get_string(lofty::tag::ItemKey::AlbumArtist);
println!("AlbumArtist: {:?}", album_artist);
if let Some(tag) = id3v2 {
for item in tag.items() {
println!("{:?}", item);
}
}
if args.import {
let _ = move_files(file_path, tag.clone());
}
Ok(())
} }
fn move_files(file_path: PathBuf, tag: Tag) -> Result<(), Box<dyn std::error::Error>> { fn move_files(file_path: PathBuf, tag: Tag) -> Result<(), Box<dyn std::error::Error>> {
let target_dir = PathBuf::from("./test"); let target_dir = PathBuf::from("./test");
let artist = tag.artist(); let artist = tag.artist();
let mut final_target = PathBuf::new(); let mut final_target = PathBuf::new();
if let Some(artist_path) = artist { if let Some(artist_path) = artist {
final_target = target_dir.join(artist_path.as_ref()).join(&file_path); final_target = target_dir.join(artist_path.as_ref()).join(&file_path);
let dir_to_create = target_dir.join(artist_path.as_ref()); let dir_to_create = target_dir.join(artist_path.as_ref());
let _ = create_dir_all(dir_to_create); let _ = create_dir_all(dir_to_create);
} }
println!("{:?}", final_target); println!("{:?}", final_target);
rename(file_path, final_target)?; rename(file_path, final_target)?;
Ok(()) Ok(())