diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-24 04:31:48 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-01-24 04:31:48 +0100 |
| commit | b2e88a8beabf04adc28947cf82996e8692a68b71 (patch) | |
| tree | 23d66c8672b69cce7835ffabae4092669062ada8 /import | |
| parent | 774f64c0789529884dd7a5232f190e347ad29532 (diff) | |
| download | jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.bz2 jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.zst | |
move things around; kv crate
Diffstat (limited to 'import')
| -rw-r--r-- | import/src/lib.rs | 100 | ||||
| -rw-r--r-- | import/src/plugins/acoustid.rs | 4 | ||||
| -rw-r--r-- | import/src/plugins/infojson.rs | 6 | ||||
| -rw-r--r-- | import/src/plugins/media_info.rs | 4 | ||||
| -rw-r--r-- | import/src/plugins/misc.rs | 12 | ||||
| -rw-r--r-- | import/src/plugins/mod.rs | 14 | ||||
| -rw-r--r-- | import/src/plugins/tags.rs | 4 | ||||
| -rw-r--r-- | import/src/plugins/tmdb.rs | 8 | ||||
| -rw-r--r-- | import/src/plugins/trakt.rs | 10 |
9 files changed, 82 insertions, 80 deletions
diff --git a/import/src/lib.rs b/import/src/lib.rs index 56da625..7d48867 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -9,17 +9,17 @@ pub mod plugins; pub mod reporting; use crate::{ - plugins::{ImportContext, ImportPlugin, infojson::is_info_json, init_plugins, misc::is_cover}, + plugins::{PluginContext, ImportPlugin, infojson::is_info_json, init_plugins, misc::is_cover}, reporting::IMPORT_PROGRESS, }; use anyhow::{Context, Result, anyhow}; -use jellycache::{HashKey, cache_memory, cache_store}; +use jellycache::{Cache, HashKey}; use jellycommon::{ jellyobject::{self, ObjectBuffer, Path as TagPath, fields}, *, }; use jellydb::{ - backends::Database, + kv::Database, query::{Filter, Query, Sort}, table::{RowNum, Table}, }; @@ -84,7 +84,8 @@ pub fn is_importing() -> bool { } #[derive(Clone)] -pub struct DatabaseTables { +pub struct ImportConfig { + pub cache: Arc<Cache>, pub db: Arc<dyn Database>, pub nodes: Arc<Table>, pub import_meta: Arc<Table>, @@ -102,7 +103,7 @@ fn node_slug_query(slug: &str) -> Query { } } -impl DatabaseTables { +impl ImportConfig { pub fn update_node( &self, node: RowNum, @@ -148,7 +149,7 @@ impl DatabaseTables { } } -pub async fn import_wrap(db: DatabaseTables, incremental: bool) -> Result<()> { +pub async fn import_wrap(db: ImportConfig, incremental: bool) -> Result<()> { let _sem = IMPORT_SEM.try_acquire().context("already importing")?; let rt = Handle::current(); @@ -170,7 +171,7 @@ pub async fn import_wrap(db: DatabaseTables, incremental: bool) -> Result<()> { Ok(()) } -fn import(dba: DatabaseTables, rt: &Handle, incremental: bool) -> Result<()> { +fn import(dba: ImportConfig, rt: &Handle, incremental: bool) -> Result<()> { let plugins = init_plugins(&CONF.api); let files = Mutex::new(Vec::new()); import_traverse( @@ -230,7 +231,7 @@ pub struct InheritedFlags { fn import_traverse( path: &Path, - dba: &DatabaseTables, + dba: &ImportConfig, incremental: bool, parent: Option<RowNum>, mut iflags: InheritedFlags, @@ -297,7 +298,7 @@ fn import_traverse( } fn import_file( - dba: &DatabaseTables, + dba: &ImportConfig, rt: &Handle, pending_nodes: &Mutex<HashSet<RowNum>>, plugins: &[Box<dyn ImportPlugin>], @@ -306,7 +307,7 @@ fn import_file( iflags: InheritedFlags, ) { let mut all_ok = true; - let ct = ImportContext { + let ct = PluginContext { dba, rt, iflags, @@ -412,7 +413,7 @@ fn import_file( } fn process_node( - dba: &DatabaseTables, + dba: &ImportConfig, rt: &Handle, plugins: &[Box<dyn ImportPlugin>], pending_nodes: &Mutex<HashSet<RowNum>>, @@ -433,7 +434,7 @@ fn process_node( reporting::catch( p.process( - &ImportContext { + &PluginContext { dba, rt, iflags: InheritedFlags::default(), @@ -447,7 +448,7 @@ fn process_node( } } -fn compare_mtime(dba: &DatabaseTables, path: &Path) -> Result<bool> { +fn compare_mtime(dba: &ImportConfig, path: &Path) -> Result<bool> { let meta = path.metadata()?; let mtime = meta.modified()?.duration_since(UNIX_EPOCH)?.as_secs(); let mut was_changed = false; @@ -474,7 +475,7 @@ fn compare_mtime(dba: &DatabaseTables, path: &Path) -> Result<bool> { Ok(was_changed) } -fn update_mtime(dba: &DatabaseTables, path: &Path) -> Result<()> { +fn update_mtime(dba: &ImportConfig, path: &Path) -> Result<()> { let meta = path.metadata()?; let mtime = meta.modified()?.duration_since(UNIX_EPOCH)?.as_secs(); dba.db.write_transaction(&mut |txn| { @@ -522,46 +523,47 @@ fn get_node_slug(path: &Path) -> Option<String> { } } -pub fn read_media_metadata(path: &Path) -> Result<Arc<matroska::Segment>> { - cache_memory( - &format!("media/metadata/{}.json", HashKey(path)), - move || { - let media = File::open(path)?; - let mut media = create_demuxer_autodetect(Box::new(media))? - .ok_or(anyhow!("media format unknown"))?; +pub fn read_media_metadata(cache: &Cache, path: &Path) -> Result<Arc<matroska::Segment>> { + cache + .cache_memory( + &format!("media/metadata/{}.json", HashKey(path)), + move || { + let media = File::open(path)?; + let mut media = create_demuxer_autodetect(Box::new(media))? + .ok_or(anyhow!("media format unknown"))?; - let info = media.info()?; - let tracks = media.tracks()?; - let tags = media.tags()?; - let mut attachments = media.attachments()?; - let chapters = media.chapters()?; + let info = media.info()?; + let tracks = media.tracks()?; + let tags = media.tags()?; + let mut attachments = media.attachments()?; + let chapters = media.chapters()?; - // Replace data of useful attachments with cache key; delete data of all others - if let Some(attachments) = &mut attachments { - for att in &mut attachments.files { - if let Some(fname) = is_useful_attachment(&att) { - let key = cache_store( - format!("media/attachment/{}-{fname}", HashKey(path)), - || Ok(att.data.clone()), - )?; - att.data = key.as_bytes().to_vec(); - } else { - att.data.clear(); + // Replace data of useful attachments with cache key; delete data of all others + if let Some(attachments) = &mut attachments { + for att in &mut attachments.files { + if let Some(fname) = is_useful_attachment(&att) { + let key = cache.cache_store( + format!("media/attachment/{}-{fname}", HashKey(path)), + || Ok(att.data.clone()), + )?; + att.data = key.as_bytes().to_vec(); + } else { + att.data.clear(); + } } } - } - Ok(Segment { - info, - tracks, - tags: tags.into_iter().collect(), - attachments, - chapters, - ..Default::default() - }) - }, - ) - .context("reading media metadata") + Ok(Segment { + info, + tracks, + tags: tags.into_iter().collect(), + attachments, + chapters, + ..Default::default() + }) + }, + ) + .context("reading media metadata") } pub fn is_useful_attachment(a: &AttachedFile) -> Option<&'static str> { diff --git a/import/src/plugins/acoustid.rs b/import/src/plugins/acoustid.rs index 9edcb63..9891927 100644 --- a/import/src/plugins/acoustid.rs +++ b/import/src/plugins/acoustid.rs @@ -5,7 +5,7 @@ */ use crate::{ USER_AGENT, - plugins::{ImportContext, ImportPlugin, PluginInfo}, + plugins::{PluginContext, ImportPlugin, PluginInfo}, }; use anyhow::{Context, Result}; use jellycache::{HashKey, cache_memory}; @@ -169,7 +169,7 @@ impl ImportPlugin for AcoustID { ..Default::default() } } - fn media(&self, ct: &ImportContext, node: RowNum, path: &Path, _seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, node: RowNum, path: &Path, _seg: &Segment) -> Result<()> { if !ct.iflags.use_acoustid { return Ok(()); } diff --git a/import/src/plugins/infojson.rs b/import/src/plugins/infojson.rs index 3e6bdb8..d62983d 100644 --- a/import/src/plugins/infojson.rs +++ b/import/src/plugins/infojson.rs @@ -3,7 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; +use crate::plugins::{PluginContext, ImportPlugin, PluginInfo}; use anyhow::{Context, Result, anyhow}; use chrono::{Utc, format::Parsed}; use jellycache::cache_read; @@ -171,7 +171,7 @@ impl ImportPlugin for Infojson { ..Default::default() } } - fn file(&self, ct: &ImportContext, parent: RowNum, path: &Path) -> Result<()> { + fn file(&self, ct: &PluginContext, parent: RowNum, path: &Path) -> Result<()> { let filename = path.file_name().unwrap().to_string_lossy(); if filename != "channel.info.json" { return Ok(()); @@ -208,7 +208,7 @@ impl ImportPlugin for Infojson { }) } - fn media(&self, ct: &ImportContext, row: RowNum, _path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, row: RowNum, _path: &Path, seg: &Segment) -> Result<()> { let infojson = seg .attachments .iter() diff --git a/import/src/plugins/media_info.rs b/import/src/plugins/media_info.rs index b750070..9b79efa 100644 --- a/import/src/plugins/media_info.rs +++ b/import/src/plugins/media_info.rs @@ -4,7 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; +use crate::plugins::{PluginContext, ImportPlugin, PluginInfo}; use anyhow::Result; use jellycommon::{ jellyobject::{Object, ObjectBuffer}, @@ -23,7 +23,7 @@ impl ImportPlugin for MediaInfo { ..Default::default() } } - fn media(&self, ct: &ImportContext, row: RowNum, path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, row: RowNum, path: &Path, seg: &Segment) -> Result<()> { let size = path.metadata()?.len(); ct.dba.db.write_transaction(&mut |txn| { let mut node = ct.dba.nodes.get(txn, row)?.unwrap(); diff --git a/import/src/plugins/misc.rs b/import/src/plugins/misc.rs index ff08d87..babbcec 100644 --- a/import/src/plugins/misc.rs +++ b/import/src/plugins/misc.rs @@ -3,7 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; +use crate::plugins::{PluginContext, ImportPlugin, PluginInfo}; use anyhow::{Context, Result, bail}; use jellycache::{HashKey, cache_store}; use jellycommon::{jellyobject::inspect::Inspector, *}; @@ -22,7 +22,7 @@ impl ImportPlugin for ImageFiles { ..Default::default() } } - fn file(&self, ct: &ImportContext, row: RowNum, path: &Path) -> Result<()> { + fn file(&self, ct: &PluginContext, row: RowNum, path: &Path) -> Result<()> { let filename = path.file_name().unwrap().to_string_lossy(); let slot = match filename.as_ref() { "poster.jpeg" | "poster.webp" | "poster.png" => PICT_COVER, @@ -66,7 +66,7 @@ impl ImportPlugin for ImageAttachments { ..Default::default() } } - fn media(&self, ct: &ImportContext, row: RowNum, _path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, row: RowNum, _path: &Path, seg: &Segment) -> Result<()> { let Some(cover) = seg .attachments .iter() @@ -94,7 +94,7 @@ impl ImportPlugin for General { ..Default::default() } } - fn instruction(&self, ct: &ImportContext, node: RowNum, line: &str) -> Result<()> { + fn instruction(&self, ct: &PluginContext, node: RowNum, line: &str) -> Result<()> { if line == "hidden" { ct.dba.update_node(node, |node| { node.as_object().insert(NO_VISIBILITY, VISI_HIDDEN) @@ -144,7 +144,7 @@ impl ImportPlugin for Children { ..Default::default() } } - fn file(&self, ct: &ImportContext, parent: RowNum, path: &Path) -> Result<()> { + fn file(&self, ct: &PluginContext, parent: RowNum, path: &Path) -> Result<()> { // TODO use idents // let filename = path.file_name().unwrap().to_string_lossy(); // if filename.as_ref() == "children" { @@ -176,7 +176,7 @@ impl ImportPlugin for EpisodeIndex { ..Default::default() } } - fn media(&self, ct: &ImportContext, node: RowNum, path: &Path, _seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, node: RowNum, path: &Path, _seg: &Segment) -> Result<()> { let filename = path.file_name().unwrap().to_string_lossy(); if let Some(cap) = RE_EPISODE_FILENAME.captures(&filename) { if let Some(episode) = cap.name("episode").map(|m| m.as_str()) { diff --git a/import/src/plugins/mod.rs b/import/src/plugins/mod.rs index 91be437..d70c6e1 100644 --- a/import/src/plugins/mod.rs +++ b/import/src/plugins/mod.rs @@ -15,15 +15,15 @@ pub mod vgmdb; pub mod wikidata; pub mod wikimedia_commons; -use crate::{ApiSecrets, DatabaseTables, InheritedFlags}; +use crate::{ApiSecrets, ImportConfig, InheritedFlags}; use anyhow::Result; use jellydb::table::RowNum; use jellyremuxer::matroska::Segment; use std::{collections::HashSet, path::Path, sync::Mutex}; use tokio::runtime::Handle; -pub struct ImportContext<'a> { - pub dba: &'a DatabaseTables, +pub struct PluginContext<'a> { + pub dba: &'a ImportConfig, pub rt: &'a Handle, pub iflags: InheritedFlags, pub pending_nodes: &'a Mutex<HashSet<RowNum>>, @@ -40,19 +40,19 @@ pub struct PluginInfo { pub trait ImportPlugin: Send + Sync { fn info(&self) -> PluginInfo; - fn file(&self, ct: &ImportContext, parent: RowNum, path: &Path) -> Result<()> { + fn file(&self, ct: &PluginContext, parent: RowNum, path: &Path) -> Result<()> { let _ = (ct, parent, path); Ok(()) } - fn media(&self, ct: &ImportContext, node: RowNum, path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, node: RowNum, path: &Path, seg: &Segment) -> Result<()> { let _ = (ct, node, path, seg); Ok(()) } - fn instruction(&self, ct: &ImportContext, node: RowNum, line: &str) -> Result<()> { + fn instruction(&self, ct: &PluginContext, node: RowNum, line: &str) -> Result<()> { let _ = (ct, node, line); Ok(()) } - fn process(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process(&self, ct: &PluginContext, node: RowNum) -> Result<()> { let _ = (ct, node); Ok(()) } diff --git a/import/src/plugins/tags.rs b/import/src/plugins/tags.rs index bfafbe8..e0652d4 100644 --- a/import/src/plugins/tags.rs +++ b/import/src/plugins/tags.rs @@ -4,7 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; +use crate::plugins::{PluginContext, ImportPlugin, PluginInfo}; use anyhow::Result; use jellycommon::*; use jellydb::table::RowNum; @@ -20,7 +20,7 @@ impl ImportPlugin for Tags { ..Default::default() } } - fn media(&self, ct: &ImportContext, node: RowNum, _path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &PluginContext, node: RowNum, _path: &Path, seg: &Segment) -> Result<()> { let tags = seg .tags .first() diff --git a/import/src/plugins/tmdb.rs b/import/src/plugins/tmdb.rs index 6b70d46..cf50938 100644 --- a/import/src/plugins/tmdb.rs +++ b/import/src/plugins/tmdb.rs @@ -5,7 +5,7 @@ */ use crate::{ USER_AGENT, - plugins::{ImportContext, ImportPlugin, PluginInfo}, + plugins::{PluginContext, ImportPlugin, PluginInfo}, }; use anyhow::{Context, Result, anyhow, bail}; use chrono::{Utc, format::Parsed}; @@ -162,14 +162,14 @@ impl ImportPlugin for Tmdb { ..Default::default() } } - fn process(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process(&self, ct: &PluginContext, node: RowNum) -> Result<()> { self.process_primary(ct, node)?; self.process_episode(ct, node)?; Ok(()) } } impl Tmdb { - fn process_primary(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process_primary(&self, ct: &PluginContext, node: RowNum) -> Result<()> { let data = ct.dba.get_node(node)?.unwrap(); let data = data.as_object(); @@ -238,7 +238,7 @@ impl Tmdb { })?; Ok(()) } - fn process_episode(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process_episode(&self, ct: &PluginContext, node: RowNum) -> Result<()> { let data = ct.dba.get_node(node)?.unwrap(); let data = data.as_object(); diff --git a/import/src/plugins/trakt.rs b/import/src/plugins/trakt.rs index 7530449..3569454 100644 --- a/import/src/plugins/trakt.rs +++ b/import/src/plugins/trakt.rs @@ -5,7 +5,7 @@ */ use crate::{ USER_AGENT, - plugins::{ImportContext, ImportPlugin, PluginInfo}, + plugins::{PluginContext, ImportPlugin, PluginInfo}, }; use anyhow::{Context, Result, anyhow, bail}; use jellycache::{HashKey, cache_memory}; @@ -380,7 +380,7 @@ impl ImportPlugin for Trakt { ..Default::default() } } - fn instruction(&self, ct: &ImportContext, node: RowNum, line: &str) -> Result<()> { + fn instruction(&self, ct: &PluginContext, node: RowNum, line: &str) -> Result<()> { use jellycommon::*; if let Some(value) = line.strip_prefix("trakt-").or(line.strip_prefix("trakt=")) { let (ty, id) = value.split_once(":").unwrap_or(("movie", value)); @@ -398,7 +398,7 @@ impl ImportPlugin for Trakt { } Ok(()) } - fn process(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process(&self, ct: &PluginContext, node: RowNum) -> Result<()> { self.process_primary(ct, node)?; self.process_episode(ct, node)?; Ok(()) @@ -406,7 +406,7 @@ impl ImportPlugin for Trakt { } impl Trakt { - fn process_primary(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process_primary(&self, ct: &PluginContext, node: RowNum) -> Result<()> { let data = ct.dba.get_node(node)?.unwrap(); let data = data.as_object(); let (trakt_kind, trakt_id): (_, u64) = if let Some(id) = data @@ -492,7 +492,7 @@ impl Trakt { })?; Ok(()) } - fn process_episode(&self, ct: &ImportContext, node: RowNum) -> Result<()> { + fn process_episode(&self, ct: &PluginContext, node: RowNum) -> Result<()> { let node_data = ct.dba.get_node(node)?.unwrap(); let node_data = node_data.as_object(); |