Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ddd3bd64b |
+3
-1
@@ -31,7 +31,9 @@ pub fn write_tags(
|
||||
) -> TagResult<()> {
|
||||
let path = Path::new(file_path);
|
||||
|
||||
let tagged_file = Probe::open(path)?.options(ParseOptions::default()).read()?;
|
||||
let tagged_file = Probe::open(path)?
|
||||
.options(ParseOptions::new().read_properties(false))
|
||||
.read()?;
|
||||
|
||||
// Determine the tag type to use
|
||||
let tag_type = tagged_file
|
||||
|
||||
+17
-25
@@ -1,27 +1,18 @@
|
||||
use std::fmt;
|
||||
|
||||
use sea_orm::{ActiveValue::Set, DatabaseConnection, NotSet};
|
||||
|
||||
use sea_orm::{ActiveValue::NotSet, ActiveValue::Set, DatabaseConnection};
|
||||
use shanty_data::MetadataFetcher as MetadataProvider;
|
||||
use shanty_db::entities::track;
|
||||
use shanty_db::queries;
|
||||
|
||||
use crate::error::TagResult;
|
||||
use crate::file_tags;
|
||||
use crate::matcher::{self, ScoredMatch};
|
||||
use shanty_data::MetadataFetcher as MetadataProvider;
|
||||
|
||||
/// Configuration for a tagging operation.
|
||||
pub struct TagConfig {
|
||||
/// If true, show what would change without writing to DB or files.
|
||||
pub dry_run: bool,
|
||||
/// If true, write updated tags back to the music files.
|
||||
pub write_tags: bool,
|
||||
/// Minimum match confidence (0.0 - 1.0).
|
||||
pub confidence: f64,
|
||||
}
|
||||
|
||||
/// Statistics from a completed tagging run.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct TagStats {
|
||||
pub tracks_processed: u64,
|
||||
pub tracks_matched: u64,
|
||||
@@ -30,8 +21,8 @@ pub struct TagStats {
|
||||
pub tracks_errored: u64,
|
||||
}
|
||||
|
||||
impl fmt::Display for TagStats {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl std::fmt::Display for TagStats {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"processed: {}, matched: {}, updated: {}, skipped: {}, errors: {}",
|
||||
@@ -198,30 +189,33 @@ fn log_match(track: &track::Model, best: &ScoredMatch) {
|
||||
confidence = format!("{:.2}", best.confidence),
|
||||
matched_title = %best.recording.title,
|
||||
matched_artist = %best.recording.artist,
|
||||
release = best.best_release.as_ref().map(|r| r.title.as_str()).unwrap_or("(none)"),
|
||||
"match found"
|
||||
"matched"
|
||||
);
|
||||
}
|
||||
|
||||
/// Run tagging on all untagged tracks or a specific track.
|
||||
/// Run tagging on a single track (by ID) or all tracks needing metadata.
|
||||
pub async fn run_tagging(
|
||||
conn: &DatabaseConnection,
|
||||
provider: &impl MetadataProvider,
|
||||
config: &TagConfig,
|
||||
track_id: Option<i32>,
|
||||
) -> TagResult<TagStats> {
|
||||
let tracks: Vec<track::Model> = if let Some(id) = track_id {
|
||||
let mut stats = TagStats {
|
||||
tracks_processed: 0,
|
||||
tracks_matched: 0,
|
||||
tracks_updated: 0,
|
||||
tracks_skipped: 0,
|
||||
tracks_errored: 0,
|
||||
};
|
||||
|
||||
let tracks = if let Some(id) = track_id {
|
||||
vec![queries::tracks::get_by_id(conn, id).await?]
|
||||
} else {
|
||||
queries::tracks::get_needing_metadata(conn).await?
|
||||
};
|
||||
|
||||
tracing::info!(count = tracks.len(), "tracks to process");
|
||||
let mut stats = TagStats::default();
|
||||
|
||||
for track in &tracks {
|
||||
stats.tracks_processed += 1;
|
||||
|
||||
match tag_track(conn, provider, track, config).await {
|
||||
Ok(true) => {
|
||||
stats.tracks_matched += 1;
|
||||
@@ -229,11 +223,9 @@ pub async fn run_tagging(
|
||||
stats.tracks_updated += 1;
|
||||
}
|
||||
}
|
||||
Ok(false) => {
|
||||
stats.tracks_skipped += 1;
|
||||
}
|
||||
Ok(false) => stats.tracks_skipped += 1,
|
||||
Err(e) => {
|
||||
tracing::error!(id = track.id, path = %track.file_path, "tagging error: {e}");
|
||||
tracing::error!(id = track.id, error = %e, "tagging failed");
|
||||
stats.tracks_errored += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user