diff options
Diffstat (limited to 'tools/src/bin')
-rw-r--r-- | tools/src/bin/import.rs | 153 |
1 files changed, 97 insertions, 56 deletions
diff --git a/tools/src/bin/import.rs b/tools/src/bin/import.rs index 471a669..eada6ad 100644 --- a/tools/src/bin/import.rs +++ b/tools/src/bin/import.rs @@ -5,12 +5,13 @@ */ use anyhow::Context; use clap::{Parser, Subcommand}; -use jellycommon::{AssetLocation, MediaInfo, Node, NodeKind, NodePrivate, NodePublic}; +use jellycommon::{AssetLocation, MediaInfo, MediaSource, Node, NodeKind, NodePrivate, NodePublic}; use jellymatroska::read::EbmlReader; -use jellyremuxer::import::import_read; +use jellyremuxer::import::{import_metadata, seek_index::import_seek_index}; use jellytools::tmdb::{tmdb_details, tmdb_image, tmdb_search}; use log::info; use std::{ + collections::BTreeMap, fs::{remove_file, File}, io::stdin, path::PathBuf, @@ -29,9 +30,10 @@ struct Args { enum Action { Create { path: PathBuf, - title: Option<String>, + #[arg(short = 't', long)] + tmdb_search: Option<String>, #[arg(short = 'T', long)] - tmdb: Option<String>, + tmdb_id: Option<String>, #[arg(long)] copy: bool, #[arg(long)] @@ -69,21 +71,20 @@ fn main() -> anyhow::Result<()> { match args.action { Action::Create { path, - title, - tmdb: id, + tmdb_id, + tmdb_search, input, series, copy, r#move, } => { - assert!(series || input.is_some(), "series or input required"); - let kind = if series { "tv" } else { "movie" }; - let key = std::env::var("TMDB_API_KEY").context("tmdb api key required")?; - let id = if let Some(id) = id { - id.parse().unwrap() + let tmdb_kind = if series { "tv" } else { "movie" }; + let tmdb_key = std::env::var("TMDB_API_KEY").context("tmdb api key required")?; + let tmdb_id = if let Some(id) = tmdb_id { + Some(id.parse().unwrap()) } else { - let title = title.as_ref().unwrap(); - let results = tmdb_search(kind, title, &key)?; + let title = tmdb_search.as_ref().unwrap(); + let results = crate::tmdb_search(tmdb_kind, title, &tmdb_key)?; info!("results:"); for (i, r) in results.results.iter().enumerate() { info!( @@ -104,43 +105,67 @@ fn main() -> anyhow::Result<()> { } else { 0 }; - results.results[res_index].id + Some(results.results[res_index].id) }; - let details = tmdb_details(kind, id, &key).context("fetching details")?; - let ident = make_ident(details.title.as_ref().or(details.name.as_ref()).unwrap()); + let tmdb_details = tmdb_id.map(|id| { + let td = tmdb_details(tmdb_kind, id, &tmdb_key) + .context("fetching details") + .unwrap(); + if td.title.is_some() { + info!("is this correct? [y/n]"); + if stdin().lines().next().unwrap().unwrap() != "y" { + exit(0) + } + } + td + }); + + let title = tmdb_details + .as_ref() + .map(|d| d.title.clone().or(d.name.clone())) + .flatten() + .unwrap(); + let ident = make_ident(&title); let path = path.join(&ident); - std::fs::create_dir_all(&path)?; - let poster = details - .poster_path - .map(|p| { - let pu = path.join("poster.jpeg"); - let mut f = File::create(&pu)?; - tmdb_image(&p, &mut f)?; - Ok::<_, anyhow::Error>(pu) - }) - .transpose()?; - let backdrop = details - .backdrop_path - .map(|p| { - let pu = path.join("backdrop.jpeg"); - let mut f = File::create(&pu)?; - tmdb_image(&p, &mut f)?; - Ok::<_, anyhow::Error>(pu) + let poster = tmdb_details + .as_ref() + .map(|d| { + d.poster_path + .as_ref() + .map(|p| { + let pu = path.join("poster.jpeg"); + let mut f = File::create(&pu)?; + tmdb_image(&p, &mut f)?; + Ok::<_, anyhow::Error>(pu) + }) + .transpose() }) - .transpose()?; + .transpose()? + .flatten(); - if title.is_some() { - info!("is this correct? [y/n]"); - if stdin().lines().next().unwrap().unwrap() != "y" { - exit(0) - } - } + let backdrop = tmdb_details + .as_ref() + .map(|d| { + d.backdrop_path + .as_ref() + .map(|p| { + let pu = path.join("backdrop.jpeg"); + let mut f = File::create(&pu)?; + tmdb_image(&p, &mut f)?; + Ok::<_, anyhow::Error>(pu) + }) + .transpose() + }) + .transpose()? + .flatten(); let kind; let media; let source; + let mut seek_index = BTreeMap::new(); + let mut source_path_e = None; if let Some(input) = input { let source_path = path.join(format!("source.mkv")); @@ -154,25 +179,24 @@ fn main() -> anyhow::Result<()> { } std::os::unix::fs::symlink(&input, &source_path)?; } - let input = File::open(&source_path).unwrap(); - let mut input = EbmlReader::new(input); - let (tracks, local_tracks, seek_index, duration) = - import_read(&source_path.to_path_buf(), &mut input)?; - for (tn, index) in seek_index { - info!("writing index {tn} with {} blocks", index.blocks.len()); - bincode::encode_into_std_write( - index, - &mut File::create(source_path.with_extension(&format!("si.{tn}")))?, - bincode::config::standard(), - )?; - } + let (tracks, local_tracks, duration) = { + let input = File::open(&source_path).unwrap(); + let mut input = EbmlReader::new(input); + import_metadata(&source_path.to_path_buf(), &mut input)? + }; + seek_index = { + let input = File::open(&source_path).unwrap(); + let mut input = EbmlReader::new(input); + import_seek_index(&mut input)? + }; kind = NodeKind::Movie; media = Some(MediaInfo { duration, tracks }); - source = Some(jellycommon::MediaSource::Local { + source = Some(MediaSource::Local { tracks: local_tracks, }); + source_path_e = Some(source_path) } else { kind = NodeKind::Series; media = None; @@ -189,9 +213,12 @@ fn main() -> anyhow::Result<()> { public: NodePublic { parent: None, federated: None, - description: Some(details.overview), - tagline: details.tagline, - title: details.title.clone().or(details.name.clone()).unwrap(), + description: tmdb_details.as_ref().map(|d| d.overview.to_owned()), + tagline: tmdb_details + .as_ref() + .map(|d| d.tagline.to_owned()) + .flatten(), + title, index: None, kind, children: Vec::new(), @@ -202,6 +229,20 @@ fn main() -> anyhow::Result<()> { if args.dry { println!("{node:?}") } else { + std::fs::create_dir_all(&path)?; + for (tn, index) in seek_index { + info!("writing index {tn} with {} blocks", index.blocks.len()); + bincode::encode_into_std_write( + index, + &mut File::create( + source_path_e + .as_ref() + .unwrap() + .with_extension(&format!("si.{tn}")), + )?, + bincode::config::standard(), + )?; + } let f = File::create(path.join(if series { "directory.json".to_string() } else { |