aboutsummaryrefslogtreecommitdiff
path: root/import/src/lib.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-12-10 17:52:41 +0100
committermetamuffin <metamuffin@disroot.org>2025-12-10 17:52:41 +0100
commite4f865e9da9d6660399e22a6fbeb5b84a749b07a (patch)
tree4af69589e8850d8a2b0c88a10e43efe8c79cb8dc /import/src/lib.rs
parenta0cfd77b4d19c43a28c4d82072e6ff136e336af3 (diff)
downloadjellything-e4f865e9da9d6660399e22a6fbeb5b84a749b07a.tar
jellything-e4f865e9da9d6660399e22a6fbeb5b84a749b07a.tar.bz2
jellything-e4f865e9da9d6660399e22a6fbeb5b84a749b07a.tar.zst
refactor import plugins part 2
Diffstat (limited to 'import/src/lib.rs')
-rw-r--r--import/src/lib.rs113
1 files changed, 30 insertions, 83 deletions
diff --git a/import/src/lib.rs b/import/src/lib.rs
index 36c65d3..8ad6790 100644
--- a/import/src/lib.rs
+++ b/import/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(duration_constants)]
pub mod plugins;
+pub mod reporting;
use crate::plugins::{
acoustid::AcoustID,
@@ -21,8 +22,8 @@ use crate::plugins::{
use anyhow::{Context, Result, anyhow};
use jellycache::{HashKey, cache_memory, cache_store};
use jellycommon::{
- Appearance, Asset, CreditCategory, IdentifierType, Node, NodeID, NodeKind, PictureSlot,
- RatingType, Visibility,
+ Appearance, Asset, CreditCategory, IdentifierType, NodeID, NodeKind, PictureSlot, RatingType,
+ Visibility,
};
use jellydb::Database;
use jellyimport_fallback_generator::generate_fallback;
@@ -41,11 +42,7 @@ use std::{
sync::{Arc, LazyLock, Mutex},
time::UNIX_EPOCH,
};
-use tokio::{
- runtime::Handle,
- sync::{RwLock, Semaphore},
- task::spawn_blocking,
-};
+use tokio::{runtime::Handle, sync::Semaphore, task::spawn_blocking};
#[rustfmt::skip]
#[derive(Debug, Deserialize, Serialize, Default)]
@@ -81,8 +78,6 @@ pub const USER_AGENT: &str = concat!(
);
static IMPORT_SEM: LazyLock<Semaphore> = LazyLock::new(|| Semaphore::new(1));
-pub static IMPORT_ERRORS: RwLock<Vec<String>> = RwLock::const_new(Vec::new());
-pub static IMPORT_PROGRESS: RwLock<Option<(usize, usize, String)>> = RwLock::const_new(None);
static RE_EPISODE_FILENAME: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r#"([sS](?<season>\d+))?([eE](?<episode>\d+))( (.+))?"#).unwrap());
@@ -114,10 +109,9 @@ pub async fn import_wrap(db: Database, incremental: bool) -> Result<()> {
let _sem = IMPORT_SEM.try_acquire().context("already importing")?;
let jh = spawn_blocking(move || {
- *IMPORT_ERRORS.blocking_write() = Vec::new();
- if let Err(e) = import(&db, incremental) {
- IMPORT_ERRORS.blocking_write().push(format!("{e:#}"));
- }
+ reporting::start_import();
+ reporting::catch(import(&db, incremental));
+ reporting::end_import();
});
let _ = jh.await;
@@ -139,6 +133,7 @@ fn import(db: &Database, incremental: bool) -> Result<()> {
let rthandle = Handle::current();
let mut files = Vec::new();
+
import_traverse(
&CONF.media_path,
db,
@@ -157,8 +152,8 @@ fn import(db: &Database, incremental: bool) -> Result<()> {
});
// let meta = path.metadata()?;
- // let mtime = meta.modified()?.duration_since(UNIX_EPOCH)?.as_secs();
- // db.set_import_file_mtime(path, mtime)?;
+ // let mtime = meta.modified()?.duration_since(UNIX_EPOCH)?.as_secs();
+ // db.set_import_file_mtime(path, mtime)?;
Ok(())
}
@@ -179,6 +174,8 @@ fn import_traverse(
out: &mut Vec<(PathBuf, NodeID, InheritedFlags)>,
) -> Result<()> {
if path.is_dir() {
+ reporting::set_task(format!("indexing {path:?}"));
+
let slug_fragment = if path == CONF.media_path {
"library".to_string()
} else {
@@ -214,12 +211,10 @@ fn import_traverse(
for e in path.read_dir()? {
let path = e?.path();
- if let Err(e) = import_traverse(&path, db, incremental, id, &slug_fragment, iflags, out)
- {
- IMPORT_ERRORS
- .blocking_write()
- .push(format!("{path:?} import failed: {e:#}"));
- }
+ reporting::catch(
+ import_traverse(&path, db, incremental, id, &slug_fragment, iflags, out)
+ .context(anyhow!("index {slug_fragment:?}")),
+ );
}
return Ok(());
}
@@ -248,54 +243,19 @@ fn import_file(
path: &Path,
parent: NodeID,
iflags: InheritedFlags,
-) -> Result<()> {
+) {
let filename = path.file_name().unwrap().to_string_lossy();
- match filename.as_ref() {
- "node.yaml" => {
- info!("import node info at {path:?}");
- let data = serde_yaml::from_str::<Node>(&read_to_string(path)?)?;
- db.update_node_init(parent, |node| {
- fn merge_option<T>(a: &mut Option<T>, b: Option<T>) {
- if b.is_some() {
- *a = b;
- }
- }
- if data.kind != NodeKind::Unknown {
- node.kind = data.kind;
- }
- merge_option(&mut node.title, data.title);
- merge_option(&mut node.tagline, data.tagline);
- merge_option(&mut node.description, data.description);
- merge_option(&mut node.index, data.index);
- merge_option(&mut node.release_date, data.release_date);
-
- Ok(())
- })?;
- }
- "flags" => {
- let content = read_to_string(path)?;
- for flag in content.lines() {
- apply_node_flag(db, rthandle, apis, parent, flag.trim())?;
- }
- }
- "children" => {
- info!("import children at {path:?}");
- for line in read_to_string(path)?.lines() {
- let line = line.trim();
- if line.starts_with("#") || line.is_empty() {
- continue;
- }
- db.update_node_init(NodeID::from_slug(line), |n| {
- n.slug = line.to_owned();
- n.parents.insert(parent);
- Ok(())
- })?;
- }
- }
- _ => import_media_file(db, apis, rthandle, path, parent, iflags).context("media file")?,
+ if filename == "flags" {
+ let Some(content) =
+ reporting::catch(read_to_string(path).context(anyhow!("read flags at {path:?}")))
+ else {
+ return;
+ };
+ for flag in content.lines() {}
+ }
+ if filename.ends_with("mkv") || filename.ends_with("mka") || filename.ends_with("mks") {
+ import_media_file(db, apis, rthandle, path, parent, iflags).context("media file");
}
-
- Ok(())
}
pub fn read_media_metadata(path: &Path) -> Result<Arc<matroska::Segment>> {
@@ -447,26 +407,13 @@ fn import_media_file(
}
}
- for tok in filename_toks {
- apply_node_flag(db, rthandle, apis, node, tok)?;
- }
+ // for tok in filename_toks {
+ // apply_node_flag(db, rthandle, apis, node, tok)?;
+ // }
Ok(())
}
-fn apply_node_flag(
- db: &Database,
- rthandle: &Handle,
- apis: &Apis,
- node: NodeID,
- flag: &str,
-) -> Result<()> {
- if let Some(mbid) = flag.strip_prefix("mbrec-").or(flag.strip_prefix("mbrec=")) {
- apply_musicbrainz_recording(db, rthandle, apis, node, mbid.to_string())?
- }
- Ok(())
-}
-
fn apply_musicbrainz_recording(
db: &Database,
rthandle: &Handle,