Commit Diff


commit - b44df3563bdf09df96415f324d6d11bf7d9c4c8e
commit + 48dfccd5d56b01f40f86c515b5feb6c54358d7c0
blob - 641b8a25183b7843c731e7945436862cc9db33b1
blob + 61e57e39f84f71ceebfdfa6d867277ce13a87bc6
--- README.md
+++ README.md
@@ -6,7 +6,6 @@ A command-line tool that analyzes audio files to detec
 
 * Detect BPM and Key of audio files
 * Write detected BPM and Key to metadata tags
-* Generate CSV reports of analyzed tracks
 * Save track metadata to a database
 
 ## Building
@@ -32,11 +31,10 @@ cargo build --release
 *   `-w`, `--write`: Write detected BPM and Key to audio file metadata.
 *   `-f`, `--force`: Re-analyze files even if they already have BPM/Key tags.
 *   `-j`, `--jobs <JOBS>`: Number of threads to use (0 = all cores).
-*   `-r`, `--report`: Generate a CSV report with timestamped filename.
 *   `-S`, `--save`: Save track reports (artist, track, BPM, key) to the database.
 *   `-l`, `--list`: List all track reports stored in the database.
-*   `--query <PATH>`: Look up a track report by file path.
-*   `--db-path <PATH>`: Path to the database directory (default: `~/.local/share/virittaa.db`).
+*   `--query <KEY>`: Look up a track report by artist - track key.
+*   `--db-path <PATH>`: Path to the database directory (default: `~/.local/share/virittaa`).
 *   `-h`, `--help`: Print help information.
 *   `-V`, `--version`: Print version information.
 
@@ -55,24 +53,19 @@ cargo build --release
 # Limit to 4 threads
 ./target/release/virittaa -j 4 /path/to/music/
 
-# Generate a CSV report
-./target/release/virittaa --report /path/to/music/
-
 # Analyze and save reports to database
 ./target/release/virittaa --save /path/to/music/
 
 # Write tags and save to database with custom path
-./target/release/virittaa -w --save --db-path ~/my_library.db /path/to/music/
+./target/release/virittaa -w --save --db-path ~/my_library /path/to/music/
 
-# Generate CSV report and save to database
-./target/release/virittaa -r --save /path/to/music/
-
 # List all tracks in the database
 ./target/release/virittaa --list
 
-# Look up a specific track by file path
-./target/release/virittaa --query /path/to/track.flac
+# Look up a specific track
+./target/release/virittaa --query "Aphex Twin - Xtal"
 
 # Query using a custom database path
-./target/release/virittaa --list --db-path ~/my_library.db
+./target/release/virittaa --list --db-path ~/my_library
 ```
+
blob - bce429dfac171434fc9ac9cdece3b7077f7f7484
blob + f9fd7179629407b9551c025aa363cb8b9baa2382
--- src/db.rs
+++ src/db.rs
@@ -11,17 +11,17 @@ pub struct TrackReport {
     pub key: Option<String>,
 }
 
-pub struct ReportDb {
+pub struct LibraryDb {
     db: Db,
 }
 
-impl ReportDb {
+impl LibraryDb {
     /// # Errors
     ///
     /// Returns an error if the database cannot be opened or created.
     pub fn open(path: &Path) -> Result<Self> {
         let db = sled::open(path)
-            .with_context(|| format!("Failed to open sled database at {}", path.display()))?;
+            .with_context(|| format!("Failed to open database at {}", path.display()))?;
         Ok(Self { db })
     }
 
blob - 0a1533ae0b599386f86b310ee344d752e8228253
blob + 3499129f3a8755f0aa9864b858f3ba81bc57e87c
--- src/main.rs
+++ src/main.rs
@@ -10,8 +10,8 @@ use rayon::prelude::*;
 use std::path::PathBuf;
 use walkdir::WalkDir;
 
-use crate::db::ReportDb;
-use crate::file_io::{process_file, write_report};
+use crate::db::LibraryDb;
+use crate::file_io::process_file;
 use crate::types::TrackError;
 
 use crate::constants::SUPPORTED_EXTENSIONS;
@@ -30,10 +30,12 @@ fn main() -> Result<()> {
     let matches = Command::new("virittaa")
         .version(clap::crate_version!())
         .about("Analyze audio files to detect BPM and Key")
-        .arg(Arg::new("path").num_args(1..).help(
-            "One or more files or directories to analyze (not required with --list or --query)",
-        ))
         .arg(
+            Arg::new("path")
+                .num_args(1..)
+                .help("One or more files or directories to analyze (not required with --list or --query)"),
+        )
+        .arg(
             Arg::new("write")
                 .short('w')
                 .long("write")
@@ -56,18 +58,11 @@ fn main() -> Result<()> {
                 .value_parser(clap::value_parser!(usize)),
         )
         .arg(
-            Arg::new("report")
-                .short('r')
-                .long("report")
-                .action(clap::ArgAction::SetTrue)
-                .help("Generate a CSV report file in the current directory"),
-        )
-        .arg(
             Arg::new("save")
                 .short('S')
                 .long("save")
                 .action(clap::ArgAction::SetTrue)
-                .help("Save track metadata to a database"),
+                .help("Save track reports (artist, track, BPM, key) to a database"),
         )
         .arg(
             Arg::new("list")
@@ -79,19 +74,18 @@ fn main() -> Result<()> {
         .arg(
             Arg::new("query")
                 .long("query")
-                .help("Look up a track report by file path"),
+                .help("Look up a track report by artist - track key"),
         )
         .arg(
             Arg::new("db-path")
                 .long("db-path")
-                .help("Path to the database directory for saved reports (default: ~/.local/share/virittaa.db)"),
+                .help("Path to the database directory for saved reports (default: ~/.local/share/virittaa)"),
         )
         .get_matches();
 
     let write_tags = matches.get_flag("write");
     let force = matches.get_flag("force");
     let jobs = *matches.get_one::<usize>("jobs").unwrap();
-    let generate_report = matches.get_flag("report");
     let save_to_db = matches.get_flag("save");
     let list_db = matches.get_flag("list");
     let query_path = matches.get_one::<String>("query").map(String::as_str);
@@ -99,17 +93,17 @@ fn main() -> Result<()> {
         p.clone()
     } else {
         let mut dir = dirs::data_local_dir().unwrap_or_else(|| std::path::PathBuf::from("."));
-        dir.push("virittaa.db");
+        dir.push("virittaa");
         dir.to_string_lossy().to_string()
     };
 
     // Read-only DB operations that don't need file paths
     if list_db || query_path.is_some() {
-        let db = ReportDb::open(std::path::Path::new(&db_path))?;
+        let db = LibraryDb::open(std::path::Path::new(&db_path))?;
 
         if let Some(path) = query_path {
             match db.get(path)? {
-                Some(report) => println!("{path}: {}", db::format_report(&report)),
+                Some(report) => println!("{}", db::format_report(&report)),
                 None => eprintln!("No report found for: {path}"),
             }
         } else {
@@ -142,7 +136,7 @@ fn main() -> Result<()> {
     }
 
     let report_db = if save_to_db {
-        Some(ReportDb::open(std::path::Path::new(&db_path))?)
+        Some(LibraryDb::open(std::path::Path::new(&db_path))?)
     } else {
         None
     };
@@ -179,9 +173,19 @@ fn main() -> Result<()> {
     let results: Vec<_> = results.into_iter().map(|r| r.unwrap()).collect();
     let errors: Vec<_> = errors.into_iter().map(|r| r.unwrap_err()).collect();
 
+    if !errors.is_empty() {
+        for err in &errors {
+            eprintln!("Error: {} - {}", err.path.display(), err.reason);
+        }
+    }
+
     if let Some(db) = &report_db {
         for track in &results {
-            let key = track.path.to_string_lossy();
+            let key = format!(
+                "{} - {}",
+                track.artist.as_deref().unwrap_or("Unknown"),
+                track.track.as_deref().unwrap_or("Unknown")
+            );
             let report = db::TrackReport {
                 artist: track.artist.clone(),
                 track: track.track.clone(),
@@ -196,9 +200,5 @@ fn main() -> Result<()> {
         }
     }
 
-    if generate_report {
-        write_report(&results, &errors)?;
-    }
-
     Ok(())
 }