diff options
Diffstat (limited to 'import/src/lib.rs')
-rw-r--r-- | import/src/lib.rs | 98 |
1 files changed, 57 insertions, 41 deletions
diff --git a/import/src/lib.rs b/import/src/lib.rs index 452d9b9..bd01fc9 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -4,7 +4,7 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ #![feature(duration_constants)] -use acoustid::AcoustID; +use acoustid::{acoustid_fingerprint, AcoustID}; use anyhow::{anyhow, bail, Context, Result}; use infojson::YVideo; use jellybase::{ @@ -89,12 +89,21 @@ fn import(db: &Database, incremental: bool) -> Result<()> { incremental, NodeID::MIN, "", - Visibility::Visible, + InheritedFlags { + visibility: Visibility::Visible, + use_acoustid: false, + }, )?; Ok(()) } +#[derive(Debug, Clone, Copy)] +struct InheritedFlags { + visibility: Visibility, + use_acoustid: bool, +} + fn import_traverse( path: &Path, db: &Database, @@ -103,7 +112,7 @@ fn import_traverse( incremental: bool, parent: NodeID, parent_slug_fragment: &str, - mut visibility: Visibility, + mut iflags: InheritedFlags, ) -> Result<()> { if path.is_dir() { let slug_fragment = if path == CONF.media_path { @@ -122,8 +131,9 @@ fn import_traverse( if let Ok(content) = read_to_string(path.join("flags")) { for flag in content.lines() { match flag.trim() { - "hidden" => visibility = visibility.min(Visibility::Hidden), - "reduced" => visibility = visibility.min(Visibility::Reduced), + "hidden" => iflags.visibility = iflags.visibility.min(Visibility::Hidden), + "reduced" => iflags.visibility = iflags.visibility.min(Visibility::Reduced), + "use_acoustid" => iflags.use_acoustid = true, _ => (), } } @@ -134,7 +144,7 @@ fn import_traverse( n.parents.insert(parent); } n.slug = slug; - n.visibility = visibility; + n.visibility = iflags.visibility; Ok(()) })?; @@ -148,7 +158,7 @@ fn import_traverse( incremental, id, &slug_fragment, - visibility, + iflags, ) { IMPORT_ERRORS .blocking_write() @@ -170,7 +180,7 @@ fn import_traverse( } } - import_file(db, apis, rthandle, path, parent, visibility)?; + import_file(db, apis, rthandle, path, parent, iflags)?; db.set_import_file_mtime(path, mtime)?; } Ok(()) @@ -182,7 +192,7 @@ fn import_file( rthandle: &Handle, path: &Path, parent: NodeID, - visibility: Visibility, + iflags: InheritedFlags, ) -> Result<()> { let filename = path.file_name().unwrap().to_string_lossy(); match filename.as_ref() { @@ -265,9 +275,7 @@ fn import_file( Ok(()) })?; } - _ => { - import_media_file(db, apis, rthandle, path, parent, visibility).context("media file")? - } + _ => import_media_file(db, apis, rthandle, path, parent, iflags).context("media file")?, } Ok(()) @@ -279,7 +287,7 @@ fn import_media_file( rthandle: &Handle, path: &Path, parent: NodeID, - visibility: Visibility, + iflags: InheritedFlags, ) -> Result<()> { info!("media file {path:?}"); let Some(m) = (*checked_matroska_metadata(path)?).to_owned() else { @@ -348,11 +356,44 @@ fn import_media_file( let node = NodeID::from_slug(&slug); let meta = path.metadata()?; + let mut eids = BTreeMap::new(); + + for (key, value) in &tags { + match key.as_str() { + "MUSICBRAINZ_TRACKID" => eids.insert("musicbrainz.track".to_string(), value.to_owned()), + "MUSICBRAINZ_ARTISTID" => { + eids.insert("musicbrainz.artist".to_string(), value.to_owned()) + } + "MUSICBRAINZ_ALBUMID" => eids.insert("musicbrainz.album".to_string(), value.to_owned()), + "MUSICBRAINZ_ALBUMARTISTID" => { + eids.insert("musicbrainz.albumartist".to_string(), value.to_owned()) + } + "MUSICBRAINZ_RELEASEGROUPID" => { + eids.insert("musicbrainz.releasegroup".to_string(), value.to_owned()) + } + "ISRC" => eids.insert("isrc".to_string(), value.to_owned()), + "BARCODE" => eids.insert("barcode".to_string(), value.to_owned()), + _ => None, + }; + } + + if iflags.use_acoustid { + let fp = rthandle.block_on(acoustid_fingerprint(path))?; + if let Some((atid, mbid)) = rthandle.block_on( + apis.acoustid + .as_ref() + .ok_or(anyhow!("need acoustid"))? + .get_atid_mbid(&fp), + )? { + eids.insert("acoustid.track".to_string(), atid); + eids.insert("musicbrainz.track".to_string(), mbid); + }; + } db.update_node_init(node, |node| { node.slug = slug; node.title = info.title.or(node.title.clone()); - node.visibility = visibility; + node.visibility = iflags.visibility; node.poster = m.cover.or(node.poster.clone()); node.description = tags .remove("DESCRIPTION") @@ -361,6 +402,8 @@ fn import_media_file( node.tagline = tags.remove("COMMENT").or(node.tagline.clone()); node.parents.insert(parent); + node.external_ids.extend(eids); + if let Some(ct) = tags.get("CONTENT_TYPE") { node.kind = match ct.to_lowercase().trim() { "movie" | "documentary" | "film" => NodeKind::Movie, @@ -369,33 +412,6 @@ fn import_media_file( } } - for (key, value) in &tags { - match key.as_str() { - "MUSICBRAINZ_TRACKID" => node - .external_ids - .insert("musicbrainz.track".to_string(), value.to_owned()), - "MUSICBRAINZ_ARTISTID" => node - .external_ids - .insert("musicbrainz.artist".to_string(), value.to_owned()), - "MUSICBRAINZ_ALBUMID" => node - .external_ids - .insert("musicbrainz.album".to_string(), value.to_owned()), - "MUSICBRAINZ_ALBUMARTISTID" => node - .external_ids - .insert("musicbrainz.albumartist".to_string(), value.to_owned()), - "MUSICBRAINZ_RELEASEGROUPID" => node - .external_ids - .insert("musicbrainz.releasegroup".to_string(), value.to_owned()), - "ISRC" => node - .external_ids - .insert("isrc".to_string(), value.to_owned()), - "BARCODE" => node - .external_ids - .insert("barcode".to_string(), value.to_owned()), - _ => None, - }; - } - let tracks = tracks .entries .into_iter() |