diff options
Diffstat (limited to 'import/src')
| -rw-r--r-- | import/src/lib.rs | 65 | ||||
| -rw-r--r-- | import/src/plugins/acoustid.rs | 6 | ||||
| -rw-r--r-- | import/src/plugins/infojson.rs | 6 | ||||
| -rw-r--r-- | import/src/plugins/media_info.rs | 2 | ||||
| -rw-r--r-- | import/src/plugins/misc.rs | 18 | ||||
| -rw-r--r-- | import/src/plugins/mod.rs | 2 | ||||
| -rw-r--r-- | import/src/plugins/tags.rs | 2 | ||||
| -rw-r--r-- | import/src/plugins/tmdb.rs | 20 | ||||
| -rw-r--r-- | import/src/plugins/trakt.rs | 18 |
9 files changed, 65 insertions, 74 deletions
diff --git a/import/src/lib.rs b/import/src/lib.rs index 4ad7f25..7980451 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -39,15 +39,14 @@ use std::{ }; use tokio::{runtime::Handle, sync::Semaphore, task::spawn_blocking}; -#[rustfmt::skip] -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize, Default, Clone)] pub struct Config { media_path: PathBuf, api: ApiSecrets, - num_threads: usize + num_threads: usize, } -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct ApiSecrets { pub acoustid: Option<String>, pub tmdb: Option<String>, @@ -58,15 +57,6 @@ pub struct ApiSecrets { pub trakt: Option<String>, } -pub static CONF_PRELOAD: Mutex<Option<Config>> = Mutex::new(None); -static CONF: LazyLock<Config> = LazyLock::new(|| { - CONF_PRELOAD - .lock() - .unwrap() - .take() - .expect("import config not preloaded. logic error") -}); - pub const USER_AGENT: &str = concat!( "jellything/", env!("CARGO_PKG_VERSION"), @@ -81,6 +71,7 @@ pub fn is_importing() -> bool { #[derive(Clone)] pub struct ImportConfig { + pub config: Config, pub cache: Arc<Cache>, pub db: Arc<dyn Database>, } @@ -141,19 +132,19 @@ impl ImportConfig { } } -pub async fn import_wrap(db: ImportConfig, incremental: bool) -> Result<()> { +pub async fn import_wrap(ic: ImportConfig, incremental: bool) -> Result<()> { let _sem = IMPORT_SEM.try_acquire().context("already importing")?; let rt = Handle::current(); let tp = ThreadPoolBuilder::new() .thread_name(|n| format!("import #{n}")) - .num_threads(CONF.num_threads) + .num_threads(ic.config.num_threads) .build()?; let jh = spawn_blocking(move || { tp.install(move || { reporting::start_import(); - reporting::catch(import(db, &rt, incremental)); + reporting::catch(import(ic, &rt, incremental)); reporting::end_import(); }) }); @@ -163,12 +154,12 @@ pub async fn import_wrap(db: ImportConfig, incremental: bool) -> Result<()> { Ok(()) } -fn import(dba: ImportConfig, rt: &Handle, incremental: bool) -> Result<()> { - let plugins = init_plugins(&CONF.api); +fn import(ic: ImportConfig, rt: &Handle, incremental: bool) -> Result<()> { + let plugins = init_plugins(&ic.config.api); let files = Mutex::new(Vec::new()); import_traverse( - &CONF.media_path, - &dba, + &ic.config.media_path, + &ic, incremental, None, InheritedFlags::default(), @@ -180,7 +171,7 @@ fn import(dba: ImportConfig, rt: &Handle, incremental: bool) -> Result<()> { files.into_par_iter().for_each(|(path, parent, iflags)| { reporting::set_task(format!("unknown: {path:?}")); - import_file(&dba, &rt, &nodes, &plugins, &path, parent, iflags); + import_file(&ic, &rt, &nodes, &plugins, &path, parent, iflags); IMPORT_PROGRESS .blocking_write() .as_mut() @@ -201,7 +192,7 @@ fn import(dba: ImportConfig, rt: &Handle, incremental: bool) -> Result<()> { swap(nodes.get_mut().unwrap(), &mut cur_nodes); cur_nodes.into_par_iter().for_each(|node| { reporting::set_task(format!("unknown: {node}")); - process_node(&dba, &rt, &plugins, &nodes, node); + process_node(&ic, &rt, &plugins, &nodes, node); IMPORT_PROGRESS .blocking_write() .as_mut() @@ -223,7 +214,7 @@ pub struct InheritedFlags { fn import_traverse( path: &Path, - dba: &ImportConfig, + ic: &ImportConfig, incremental: bool, parent: Option<RowNum>, mut iflags: InheritedFlags, @@ -232,7 +223,7 @@ fn import_traverse( if path.is_dir() { reporting::set_task(format!("indexing {path:?}")); - let slug = get_node_slug(path).unwrap(); + let slug = get_node_slug(ic, path).unwrap(); // Some flags need to applied immediatly because they are inherited if let Ok(content) = read_to_string(path.join("flags")) { @@ -246,7 +237,7 @@ fn import_traverse( } } - let row = dba.update_node_slug(&slug, |mut node| { + let row = ic.update_node_slug(&slug, |mut node| { if let Some(parent) = parent { node = node.as_object().extend(NO_PARENT, [parent]); } @@ -262,7 +253,7 @@ fn import_traverse( path.read_dir()?.par_bridge().try_for_each(|e| { let path = e?.path(); reporting::catch( - import_traverse(&path, dba, incremental, Some(row), iflags, out) + import_traverse(&path, ic, incremental, Some(row), iflags, out) .context(anyhow!("index {:?}", path.file_name().unwrap())), ); anyhow::Ok(()) @@ -274,7 +265,7 @@ fn import_traverse( && let Some(parent) = parent { if incremental { - if compare_mtime(dba, path)? { + if compare_mtime(ic, path)? { return Ok(()); } } @@ -290,7 +281,7 @@ fn import_traverse( } fn import_file( - dba: &ImportConfig, + ic: &ImportConfig, rt: &Handle, pending_nodes: &Mutex<HashSet<RowNum>>, plugins: &[Box<dyn ImportPlugin>], @@ -300,7 +291,7 @@ fn import_file( ) { let mut all_ok = true; let ct = PluginContext { - dba, + ic, rt, iflags, pending_nodes, @@ -329,9 +320,9 @@ fn import_file( } if filename.ends_with("mkv") || filename.ends_with("mka") || filename.ends_with("mks") { - let slug = get_node_slug(path).unwrap(); + let slug = get_node_slug(ic, path).unwrap(); - let Some(row) = reporting::catch(dba.update_node_slug(&slug, |mut node| { + let Some(row) = reporting::catch(ic.update_node_slug(&slug, |mut node| { node = node.as_object().extend(NO_PARENT, [parent]); if iflags.hidden { node = node.as_object().insert(NO_VISIBILITY, VISI_HIDDEN); @@ -370,7 +361,7 @@ fn import_file( reporting::set_task(format!("demuxer meta: {path:?}")); let Some(seg) = reporting::catch( - read_media_metadata(&ct.dba.cache, path).context(anyhow!("media {path:?}")), + read_media_metadata(&ct.ic.cache, path).context(anyhow!("media {path:?}")), ) else { return; }; @@ -400,7 +391,7 @@ fn import_file( } if all_ok { - reporting::catch(update_mtime(dba, path).context("updating mtime")); + reporting::catch(update_mtime(ic, path).context("updating mtime")); } } @@ -427,7 +418,7 @@ fn process_node( reporting::catch( p.process( &PluginContext { - dba, + ic: dba, rt, iflags: InheritedFlags::default(), pending_nodes, @@ -491,13 +482,13 @@ fn update_mtime(dba: &ImportConfig, path: &Path) -> Result<()> { Ok(()) } -fn get_node_slug(path: &Path) -> Option<String> { - if path == CONF.media_path { +fn get_node_slug(ic: &ImportConfig, path: &Path) -> Option<String> { + if path == ic.config.media_path { return Some("library".to_string()); } let filename = path.file_name()?.to_string_lossy(); let filestem = filename.split_once(".").unwrap_or((&filename, "")).0; - if path.parent()? == &CONF.media_path { + if path.parent()? == &ic.config.media_path { Some(format!("{filestem}")) } else { let parent_filename = path.parent()?.file_name()?.to_string_lossy(); diff --git a/import/src/plugins/acoustid.rs b/import/src/plugins/acoustid.rs index f55faad..58a2657 100644 --- a/import/src/plugins/acoustid.rs +++ b/import/src/plugins/acoustid.rs @@ -183,10 +183,10 @@ impl ImportPlugin for AcoustID { if !ct.iflags.use_acoustid { return Ok(()); } - let fp = acoustid_fingerprint(&ct.dba.cache, path)?; + let fp = acoustid_fingerprint(&ct.ic.cache, path)?; - if let Some((atid, mbid)) = self.get_atid_mbid(&ct.dba.cache, &fp, &ct.rt)? { - ct.dba.db.transaction(&mut |txn| { + if let Some((atid, mbid)) = self.get_atid_mbid(&ct.ic.cache, &fp, &ct.rt)? { + ct.ic.db.transaction(&mut |txn| { let ob = txn.get(node)?.unwrap(); let ob = ob.as_object(); let ob = ob.insert( diff --git a/import/src/plugins/infojson.rs b/import/src/plugins/infojson.rs index 3a48ce8..a48fca5 100644 --- a/import/src/plugins/infojson.rs +++ b/import/src/plugins/infojson.rs @@ -175,7 +175,7 @@ impl ImportPlugin for Infojson { let data = serde_json::from_reader::<_, YVideo>(BufReader::new(File::open(path)?))?; let title = clean_uploader_name(&data.title); - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { let mut node = txn.get(parent)?.unwrap(); node = node.as_object().insert(NO_KIND, KIND_CHANNEL); node = node.as_object().insert(NO_TITLE, title); @@ -210,7 +210,7 @@ impl ImportPlugin for Infojson { .find(is_info_json) .map(|att| { let data = ct - .dba + .ic .cache .read(str::from_utf8(&att.data).unwrap())? .ok_or(anyhow!("info json cache missing"))?; @@ -236,7 +236,7 @@ impl ImportPlugin for Infojson { KIND_VIDEO }; - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { let mut node = txn.get(row)?.unwrap(); node = node.as_object().insert(NO_KIND, kind); node = node.as_object().insert(NO_TITLE, &infojson.title); diff --git a/import/src/plugins/media_info.rs b/import/src/plugins/media_info.rs index 05beb8f..11da365 100644 --- a/import/src/plugins/media_info.rs +++ b/import/src/plugins/media_info.rs @@ -25,7 +25,7 @@ impl ImportPlugin for MediaInfo { } fn media(&self, ct: &PluginContext, row: RowNum, path: &Path, seg: &Segment) -> Result<()> { let size = path.metadata()?.len(); - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { let mut node = txn.get(row)?.unwrap(); if let Some(tracks) = &seg.tracks { node = node.as_object().extend_object( diff --git a/import/src/plugins/misc.rs b/import/src/plugins/misc.rs index d929935..ea5054e 100644 --- a/import/src/plugins/misc.rs +++ b/import/src/plugins/misc.rs @@ -30,7 +30,7 @@ impl ImportPlugin for ImageFiles { _ => return Ok(()), }; info!("import {:?} at {path:?}", Inspector(&TAGREG, slot)); - let asset = ct.dba.cache.store( + let asset = ct.ic.cache.store( format!( "media/literal/{}-{}.image", HashKey(path), @@ -42,7 +42,7 @@ impl ImportPlugin for ImageFiles { Ok(data) }, )?; - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { let mut node = txn.get(row)?.unwrap(); node = node .as_object() @@ -77,7 +77,7 @@ impl ImportPlugin for ImageAttachments { return Ok(()); }; - ct.dba.update_node(row, |node| { + ct.ic.update_node(row, |node| { node.as_object() .update(NO_PICTURES, |picts| picts.insert(PICT_COVER, &cover)) })?; @@ -96,12 +96,12 @@ impl ImportPlugin for General { } fn instruction(&self, ct: &PluginContext, node: RowNum, line: &str) -> Result<()> { if line == "hidden" { - ct.dba.update_node(node, |node| { + ct.ic.update_node(node, |node| { node.as_object().insert(NO_VISIBILITY, VISI_HIDDEN) })?; } if line == "reduced" { - ct.dba.update_node(node, |node| { + ct.ic.update_node(node, |node| { node.as_object().insert(NO_VISIBILITY, VISI_REDUCED) })?; } @@ -119,16 +119,16 @@ impl ImportPlugin for General { "episode" => KIND_EPISODE, _ => bail!("unknown node kind"), }; - ct.dba + ct.ic .update_node(node, |node| node.as_object().insert(NO_KIND, kind))?; } if let Some(title) = line.strip_prefix("title=") { - ct.dba + ct.ic .update_node(node, |node| node.as_object().insert(NO_TITLE, title))?; } if let Some(index) = line.strip_prefix("index=") { let index = index.parse().context("parse index")?; - ct.dba + ct.ic .update_node(node, |node| node.as_object().insert(NO_INDEX, index))?; } Ok(()) @@ -187,7 +187,7 @@ impl ImportPlugin for EpisodeIndex { .parse::<u64>() .context("parse season num")?; - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { node = node.as_object().insert(NO_SEASON_INDEX, season); node = node.as_object().insert(NO_INDEX, episode); node = node.as_object().insert(NO_KIND, KIND_EPISODE); diff --git a/import/src/plugins/mod.rs b/import/src/plugins/mod.rs index b351a17..d99fa9b 100644 --- a/import/src/plugins/mod.rs +++ b/import/src/plugins/mod.rs @@ -23,7 +23,7 @@ use std::{collections::HashSet, path::Path, sync::Mutex}; use tokio::runtime::Handle; pub struct PluginContext<'a> { - pub dba: &'a ImportConfig, + pub ic: &'a ImportConfig, pub rt: &'a Handle, pub iflags: InheritedFlags, pub pending_nodes: &'a Mutex<HashSet<RowNum>>, diff --git a/import/src/plugins/tags.rs b/import/src/plugins/tags.rs index d1e6a81..bd7d0bc 100644 --- a/import/src/plugins/tags.rs +++ b/import/src/plugins/tags.rs @@ -33,7 +33,7 @@ impl ImportPlugin for Tags { }) .unwrap_or_default(); - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { if let Some(title) = &seg.info.title { node = node.as_object().insert(NO_TITLE, title); } diff --git a/import/src/plugins/tmdb.rs b/import/src/plugins/tmdb.rs index e9e92d4..b7bd797 100644 --- a/import/src/plugins/tmdb.rs +++ b/import/src/plugins/tmdb.rs @@ -192,7 +192,7 @@ impl ImportPlugin for Tmdb { } impl Tmdb { fn process_primary(&self, ct: &PluginContext, node: RowNum) -> Result<()> { - let data = ct.dba.get_node(node)?.unwrap(); + let data = ct.ic.get_node(node)?.unwrap(); let data = data.as_object(); let (tmdb_kind, tmdb_id): (_, u64) = if let Some(id) = data @@ -211,17 +211,17 @@ impl Tmdb { return Ok(()); }; - let details = self.details(&ct.dba.cache, tmdb_kind, tmdb_id, ct.rt)?; + let details = self.details(&ct.ic.cache, tmdb_kind, tmdb_id, ct.rt)?; let backdrop = details .backdrop_path .as_ref() - .map(|path| self.image(&ct.dba.cache, &path, ct.rt)) + .map(|path| self.image(&ct.ic.cache, &path, ct.rt)) .transpose() .context("backdrop image")?; let poster = details .poster_path .as_ref() - .map(|path| self.image(&ct.dba.cache, &path, ct.rt)) + .map(|path| self.image(&ct.ic.cache, &path, ct.rt)) .transpose() .context("poster image")?; @@ -232,7 +232,7 @@ impl Tmdb { .transpose()? .flatten(); - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { if let Some(title) = &details.title { node = node.as_object().insert(NO_TITLE, &title); } @@ -261,14 +261,14 @@ impl Tmdb { Ok(()) } fn process_episode(&self, ct: &PluginContext, node: RowNum) -> Result<()> { - let data = ct.dba.get_node(node)?.unwrap(); + let data = ct.ic.get_node(node)?.unwrap(); let data = data.as_object(); let (Some(episode), Some(season)) = (data.get(NO_INDEX), data.get(NO_SEASON_INDEX)) else { return Ok(()); }; let mut series_id = None; - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { for parent in data.iter(NO_PARENT) { let parent_data = txn.get(parent)?.ok_or(anyhow!("parent missing"))?; if let Some(id) = parent_data @@ -286,15 +286,15 @@ impl Tmdb { let Some(series_id) = series_id else { return Ok(()); }; - let details = self.episode_details(&ct.dba.cache, series_id, season, episode, ct.rt)?; + let details = self.episode_details(&ct.ic.cache, series_id, season, episode, ct.rt)?; let cover = details .still_path .as_ref() - .map(|path| self.image(&ct.dba.cache, &path, ct.rt)) + .map(|path| self.image(&ct.ic.cache, &path, ct.rt)) .transpose() .context("still image download")?; let release_date = parse_release_date(&details.air_date)?; - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { node = node.as_object().insert(NO_TITLE, &details.name); node = node.as_object().insert(NO_DESCRIPTION, &details.overview); if let Some(release_date) = release_date { diff --git a/import/src/plugins/trakt.rs b/import/src/plugins/trakt.rs index ebbe879..b67bb42 100644 --- a/import/src/plugins/trakt.rs +++ b/import/src/plugins/trakt.rs @@ -416,7 +416,7 @@ impl ImportPlugin for Trakt { "episode" => IDENT_TRAKT_EPISODE, _ => bail!("unknown trakt kind"), }; - ct.dba.update_node(node, |node| { + ct.ic.update_node(node, |node| { node.as_object() .update(NO_IDENTIFIERS, |idents| idents.insert(ty, id)) })?; @@ -432,7 +432,7 @@ impl ImportPlugin for Trakt { impl Trakt { fn process_primary(&self, ct: &PluginContext, node: RowNum) -> Result<()> { - let data = ct.dba.get_node(node)?.unwrap(); + let data = ct.ic.get_node(node)?.unwrap(); let data = data.as_object(); let (trakt_kind, trakt_id): (_, u64) = if let Some(id) = data .get(NO_IDENTIFIERS) @@ -450,7 +450,7 @@ impl Trakt { return Ok(()); }; - let details = self.lookup(&ct.dba.cache, trakt_kind, trakt_id, ct.rt)?; + let details = self.lookup(&ct.ic.cache, trakt_kind, trakt_id, ct.rt)?; // let people = self.people(trakt_kind, trakt_id, ct.rt)?; // let mut people_map = BTreeMap::<CreditCategory, Vec<Appearance>>::new(); @@ -479,7 +479,7 @@ impl Trakt { // } // } - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { node = node.as_object().insert(NO_KIND, trakt_kind.as_node_kind()); node = node.as_object().insert(NO_TITLE, &details.title); if let Some(overview) = &details.overview { @@ -518,7 +518,7 @@ impl Trakt { Ok(()) } fn process_episode(&self, ct: &PluginContext, node: RowNum) -> Result<()> { - let node_data = ct.dba.get_node(node)?.unwrap(); + let node_data = ct.ic.get_node(node)?.unwrap(); let node_data = node_data.as_object(); let (Some(episode), Some(season)) = @@ -527,7 +527,7 @@ impl Trakt { return Ok(()); }; let mut show_id = None; - ct.dba.db.transaction(&mut |txn| { + ct.ic.db.transaction(&mut |txn| { for parent in node_data.iter(NO_PARENT) { let parent_data = txn.get(parent)?.ok_or(anyhow!("parent missing"))?; if let Some(id) = parent_data @@ -546,11 +546,11 @@ impl Trakt { return Ok(()); }; - let seasons = self.show_seasons(&ct.dba.cache, show_id, ct.rt)?; + let seasons = self.show_seasons(&ct.ic.cache, show_id, ct.rt)?; if seasons.iter().any(|x| x.number == season) { - let episodes = self.show_season_episodes(&ct.dba.cache, show_id, season, ct.rt)?; + let episodes = self.show_season_episodes(&ct.ic.cache, show_id, season, ct.rt)?; if let Some(episode) = episodes.get(episode.saturating_sub(1) as usize) { - ct.dba.update_node(node, |mut node| { + ct.ic.update_node(node, |mut node| { node = node.as_object().insert(NO_KIND, KIND_EPISODE); node = node.as_object().insert(NO_INDEX, episode.number); node = node.as_object().insert(NO_TITLE, &episode.title); |