From 3a29113e965a94bdef06655f1583cc6e86edd606 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 21 Dec 2023 23:57:42 +0100 Subject: rework import system pt. 1 --- tool/src/main.rs | 93 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'tool/src/main.rs') diff --git a/tool/src/main.rs b/tool/src/main.rs index 31e63b7..34337ce 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -5,12 +5,10 @@ */ #![feature(file_create_new)] -pub mod import; pub mod migrate; use base64::Engine; use clap::{Parser, Subcommand, ValueEnum}; -use import::import; use jellyclient::{Instance, LoginDetails}; use jellycommon::{config::GlobalConfig, Node, NodeKind, NodePrivate, NodePublic}; use log::{info, warn}; @@ -37,47 +35,47 @@ enum Action { #[arg(short, long)] hostname: String, }, - /// Imports a movie, video or series given media and metadata sources - New { - /// Relative path to the node's parent(!). - path: PathBuf, - /// Search the node by title on TMDB - #[arg(short = 't', long)] - tmdb_search: Option, - /// Search the node by id on TMDB - #[arg(short = 'T', long)] - tmdb_id: Option, - #[arg(long)] - /// Prefix the inferred id with something to avoid collisions - ident_prefix: Option, - /// Copies media into the library - #[arg(long)] - copy: bool, - /// Moves media into the library (potentially destructive operation) - #[arg(long)] - r#move: bool, - /// Marks node as a video - #[arg(long)] - video: bool, - /// Marks node as a series - #[arg(short, long)] - series: bool, - /// Path to the media of the node, required for non-series - #[arg(short, long)] - input: Option, - /// Ignore attachments (dont use them as cover) - #[arg(long)] - ignore_attachments: bool, - /// Ignore metadate (no title, description and tagline from input) - #[arg(long)] - ignore_metadata: bool, - /// Skip any action that appears to be run already. - #[arg(long)] - skip_existing: bool, - /// Sets the title - #[arg(long)] - title: Option, - }, + // /// Imports a movie, video or series given media and metadata sources + // New { + // /// Relative path to the node's parent(!). + // path: PathBuf, + // /// Search the node by title on TMDB + // #[arg(short = 't', long)] + // tmdb_search: Option, + // /// Search the node by id on TMDB + // #[arg(short = 'T', long)] + // tmdb_id: Option, + // #[arg(long)] + // /// Prefix the inferred id with something to avoid collisions + // ident_prefix: Option, + // /// Copies media into the library + // #[arg(long)] + // copy: bool, + // /// Moves media into the library (potentially destructive operation) + // #[arg(long)] + // r#move: bool, + // /// Marks node as a video + // #[arg(long)] + // video: bool, + // /// Marks node as a series + // #[arg(short, long)] + // series: bool, + // /// Path to the media of the node, required for non-series + // #[arg(short, long)] + // input: Option, + // /// Ignore attachments (dont use them as cover) + // #[arg(long)] + // ignore_attachments: bool, + // /// Ignore metadate (no title, description and tagline from input) + // #[arg(long)] + // ignore_metadata: bool, + // /// Skip any action that appears to be run already. + // #[arg(long)] + // skip_existing: bool, + // /// Sets the title + // #[arg(long)] + // title: Option, + // }, Migrate { database: PathBuf, mode: MigrateMode, @@ -118,8 +116,11 @@ fn main() -> anyhow::Result<()> { std::fs::create_dir_all(path.join("library"))?; std::fs::create_dir_all(path.join("cache"))?; std::fs::create_dir_all(path.join("assets"))?; + std::fs::create_dir_all(path.join("media"))?; File::create_new(path.join("assets/front.htm"))? .write_fmt(format_args!("

My very own jellything instance

"))?; + + // TODO: dont fill that serde_yaml::to_writer( File::create_new(path.join("config.yaml"))?, &GlobalConfig { @@ -149,8 +150,8 @@ fn main() -> anyhow::Result<()> { File::create_new(path.join("library/directory.json"))?, &Node { public: NodePublic { - kind: NodeKind::Collection, - title: "My Library".to_string(), + kind: Some(NodeKind::Collection), + title: Some("My Library".to_string()), ..Default::default() }, private: NodePrivate { @@ -162,7 +163,7 @@ fn main() -> anyhow::Result<()> { warn!("please change the admin password."); Ok(()) } - a @ Action::New { .. } => import(a, args.dry), + // a @ Action::New { .. } => import(a, args.dry), a @ Action::Migrate { .. } => migrate(a), Action::Reimport { config, -- cgit v1.2.3-70-g09d2 From 826c61c9612e855b19c3adb0e93d80bbfb4dc903 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 22 Dec 2023 00:29:11 +0100 Subject: rework import system pt. 2 --- Cargo.lock | 2 ++ common/src/lib.rs | 4 +-- import/Cargo.toml | 4 +-- import/src/lib.rs | 65 ++++++++++++++++++++++++++++++++++++++++++-- server/src/routes/ui/home.rs | 2 +- tool/src/main.rs | 13 --------- 6 files changed, 69 insertions(+), 21 deletions(-) (limited to 'tool/src/main.rs') diff --git a/Cargo.lock b/Cargo.lock index 9a12441..bd09a54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1391,9 +1391,11 @@ dependencies = [ "jellybase", "jellyclient", "jellycommon", + "jellymatroska", "jellyremuxer", "log", "reqwest", + "serde", "serde_json", "serde_yaml", "tokio", diff --git a/common/src/lib.rs b/common/src/lib.rs index e953d85..9a3535a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -21,8 +21,8 @@ use std::{collections::BTreeMap, path::PathBuf}; #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Node { - pub public: NodePublic, - pub private: NodePrivate, + #[serde(default)] pub public: NodePublic, + #[serde(default)] pub private: NodePrivate, } #[rustfmt::skip] diff --git a/import/Cargo.toml b/import/Cargo.toml index f2ba7af..a54967c 100644 --- a/import/Cargo.toml +++ b/import/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" jellycommon = { path = "../common" } jellybase = { path = "../base" } jellyclient = { path = "../client" } -# jellymatroska = { path = "../matroska" } +jellymatroska = { path = "../matroska" } jellyremuxer = { path = "../remuxer" } log = { workspace = true } anyhow = "1.0.75" reqwest = { version = "0.11.22", features = ["blocking", "json"] } -# serde = { version = "1.0.193", features = ["derive"] } +serde = { version = "1.0.193", features = ["derive"] } serde_json = "1.0.108" serde_yaml = "0.9.27" # bincode = { version = "2.0.0-rc.3", features = ["serde"] } diff --git a/import/src/lib.rs b/import/src/lib.rs index 3698f79..ed0af2d 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -4,6 +4,9 @@ Copyright (C) 2023 metamuffin */ #![feature(lazy_cell)] +pub mod infojson; +pub mod tmdb; + use anyhow::{Context, Ok}; use async_recursion::async_recursion; use futures::{stream::FuturesUnordered, StreamExt}; @@ -14,16 +17,19 @@ use jellyclient::Session; use jellycommon::{ AssetLocation, AssetRole, ImportOptions, ImportSource, Node, NodePrivate, NodePublic, }; +use jellymatroska::read::EbmlReader; +use jellyremuxer::import::import_metadata; use log::{debug, info}; use std::{ cmp::Ordering, ffi::OsStr, fs::File, + io::BufReader, os::unix::prelude::OsStrExt, path::{Path, PathBuf}, sync::{Arc, LazyLock}, }; -use tokio::sync::Semaphore; +use tokio::{sync::Semaphore, task::spawn_blocking}; static IMPORT_SEM: LazyLock = LazyLock::new(|| Semaphore::new(1)); @@ -48,12 +54,15 @@ pub fn merge_nodes(db: &Database) -> anyhow::Result<()> { nodes.sort_by(|(x, _), (y, _)| compare_index_path(x, y)); - let node = nodes + let mut node = nodes .into_iter() .map(|(_, x)| x) .reduce(|x, y| merge_node(x, y)) .unwrap(); + node.public.id = Some(id.clone()); + node.public.path = vec!["library".to_string()]; // TODO reconstruct from children + db.node.insert(&id, &node)?; } Ok(()) @@ -146,7 +155,44 @@ async fn process_source( ImportSource::Override(n) => insert_node(&id, n)?, ImportSource::Tmdb(_) => todo!(), ImportSource::Media { location } => { - let path = location.path(); + let media_path = location.path(); + + let metadata = spawn_blocking(move || { + let input = BufReader::new(File::open(&media_path).unwrap()); + let mut input = EbmlReader::new(input); + import_metadata(&mut input) + }) + .await??; + + // if let Some(cover) = metadata.cover { + // let pu = path.join(format!( + // "cover.{}", + // match mime.as_str() { + // "image/webp" => "webp", + // "image/jpeg" => "jpeg", + // "image/png" => "png", + // _ => { + // warn!("unknown mime, just using webp"); + // "webp" + // } + // } + // )); + // if !pu.exists() { + // let mut f = tokio::fs::File::create(&pu).await?; + // f.write_all(&data).await?; + // } + // } + + let node = Node { + public: NodePublic { + title: metadata.title, + description: metadata.description, + tagline: metadata.tagline, + ..Default::default() + }, + private: NodePrivate::default(), + }; + insert_node(&id, node)?; } ImportSource::Federated { host } => { let session = fed.get_session(&host).await.context("creating session")?; @@ -374,3 +420,16 @@ async fn cache_federation_asset( ) .await } + +fn make_ident(s: &str) -> String { + let mut out = String::new(); + for s in s.chars() { + match s { + 'a'..='z' | '0'..='9' => out.push(s), + 'A'..='Z' => out.push(s.to_ascii_lowercase()), + '-' | ' ' | '_' | ':' => out.push('-'), + _ => (), + } + } + out +} diff --git a/server/src/routes/ui/home.rs b/server/src/routes/ui/home.rs index bcbc847..74e9b02 100644 --- a/server/src/routes/ui/home.rs +++ b/server/src/routes/ui/home.rs @@ -77,7 +77,7 @@ pub fn r_home(sess: Session, db: &State) -> MyResult { Ok(LayoutPage { title: "Home".to_string(), content: markup::new! { - p { "Welcome back " @sess.user.display_name } + p { "Welcome back, " @sess.user.display_name } h2 { "Explore " @CONF.brand } .homelist { ul {@for (id, node, udata) in &toplevel { li { @NodeCard { id, node, udata } } diff --git a/tool/src/main.rs b/tool/src/main.rs index 34337ce..6384822 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -193,19 +193,6 @@ fn main() -> anyhow::Result<()> { } } -fn make_ident(s: &str) -> String { - let mut out = String::new(); - for s in s.chars() { - match s { - 'a'..='z' | '0'..='9' => out.push(s), - 'A'..='Z' => out.push(s.to_ascii_lowercase()), - '-' | ' ' | '_' | ':' => out.push('-'), - _ => (), - } - } - out -} - fn ok_or_warn(r: Result) -> Option { match r { Ok(t) => Some(t), -- cgit v1.2.3-70-g09d2