Files
music-sort/src/main.rs
T

121 lines
3.3 KiB
Rust
Executable File

use clap::{Parser, Subcommand};
//use ini::Ini;
use lofty::file::TaggedFileExt;
use lofty::probe::Probe;
use std::ffi::OsStr;
use std::fs::read_dir;
use std::path::PathBuf;
mod move_files;
use move_files::move_files;
mod edit;
use edit::edit;
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Args {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Import {
files: Vec<PathBuf>,
#[arg(short, long, default_value_t = false)]
copy: bool,
},
Show {
files: Vec<PathBuf>,
},
Edit {
files: Vec<PathBuf>,
},
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
//let mut conf = Ini::new();
//conf.with_section(Some("General"))
// .set("target_directory", "");
////conf.write_to_file("conf.ini").unwrap();
//
//let conf = Ini::load_from_file("conf.ini").unwrap();
//
//let section = conf.section(Some("General")).unwrap();
//println!("target_dir={:?}", section.get("target_directory"));
//
//for (_sec, prop) in &conf {
// for (key, value) in prop.iter() {
// println!("{:?}:{:?}", key, value);
// }
//}
//
let args = Args::parse();
let extra_files = ["jpg", "png", "pdf", "log", "cue", "mp4", "lrc", "txt"].map(str::to_string);
match &args.command {
Commands::Import { files, copy } => {
for file in files {
if file.is_dir() {
println!("Importing folder: {:?}", file);
for music_file in read_dir(file)? {
let path = music_file?.path();
if path
.extension()
.and_then(|ext| ext.to_str())
.is_some_and(|ext| extra_files.iter().any(|x| x == ext))
{
continue;
}
let tag = get_metadata(&path);
if let Err(e) =
move_files(path.clone(), tag, extra_files.clone(), *copy, true)
{
eprintln!("Failed to import {:?}: {}", path, e);
}
}
} else {
println!("Importing file: {:?}", file);
let tag = get_metadata(file);
move_files(file.clone(), tag.clone(), extra_files.clone(), *copy, false)?;
}
}
}
Commands::Show { files } => {
for file in files {
println!("Show file: {:?}", file);
let tag = get_metadata(file);
for item in tag.items() {
println!("{:?}", item)
}
}
}
Commands::Edit { files } => {
edit(files.to_vec(), extra_files)?;
}
}
Ok(())
}
pub fn get_metadata<P: AsRef<OsStr>>(file_path: P) -> lofty::tag::Tag {
let tagged_file = Probe::open(file_path.as_ref())
.expect("ERROR: Bad path provided!")
.read()
.expect("ERROR: Failed to read file!");
let tag = match tagged_file.primary_tag() {
Some(primary_tag) => primary_tag,
None => tagged_file.first_tag().expect("ERROR: No tags found!"),
};
tag.clone()
}