diff options
author | metamuffin <metamuffin@disroot.org> | 2023-08-03 22:35:04 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-08-03 22:35:04 +0200 |
commit | fc74676f349f2e9de6f7a508d4ba3ff66935a6f8 (patch) | |
tree | f21fd24a4478d84ecd5044d6a9459e0e8fcf6aa6 | |
parent | fd66e97053ff88d1921bbb2d1c276c6fbe66b935 (diff) | |
download | jellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar jellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar.bz2 jellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar.zst |
dry run works as expected again
-rw-r--r-- | import/src/main.rs | 149 | ||||
-rw-r--r-- | remuxer/src/import/mod.rs | 52 |
2 files changed, 98 insertions, 103 deletions
diff --git a/import/src/main.rs b/import/src/main.rs index 6cf2ef3..f139d40 100644 --- a/import/src/main.rs +++ b/import/src/main.rs @@ -12,7 +12,6 @@ use jellymatroska::read::EbmlReader; use jellyremuxer::import::{import_metadata, seek_index::import_seek_index}; use log::info; use std::{ - collections::BTreeMap, fs::{remove_file, File}, io::stdin, path::PathBuf, @@ -81,12 +80,11 @@ fn main() -> anyhow::Result<()> { r#move, } => { 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 = tmdb_search.as_ref().unwrap(); - let results = crate::tmdb_search(tmdb_kind, title, &tmdb_key)?; + } else if let Some(title) = tmdb_search { + let tmdb_key = std::env::var("TMDB_API_KEY").context("tmdb api key required")?; + let results = crate::tmdb_search(tmdb_kind, &title, &tmdb_key)?; info!("results:"); for (i, r) in results.results.iter().enumerate() { info!( @@ -108,25 +106,55 @@ fn main() -> anyhow::Result<()> { 0 }; Some(results.results[res_index].id) + } else { + None }; - 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) + let tmdb_details = tmdb_id + .map(|id| { + let tmdb_key = + std::env::var("TMDB_API_KEY").context("tmdb api key required")?; + 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 - }); + Ok::<_, anyhow::Error>(td) + }) + .transpose()?; + + let mut kind = NodeKind::Series; + let (mut file_meta, mut seek_index, mut source_path_e) = Default::default(); + + if let Some(input_path) = &input { + source_path_e = Some(path.join(format!("source.mkv"))); + + file_meta = Some({ + let input = File::open(&input_path).unwrap(); + let mut input = EbmlReader::new(input); + import_metadata(&mut input)? + }); + seek_index = { + let input = File::open(&input_path).unwrap(); + let mut input = EbmlReader::new(input); + import_seek_index(&mut input)? + }; - let title = tmdb_details + kind = NodeKind::Movie; + } + + let title = file_meta .as_ref() - .map(|d| d.title.clone().or(d.name.clone())) + .map(|m| m.title.clone()) .flatten() + .or(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); @@ -163,54 +191,14 @@ fn main() -> anyhow::Result<()> { .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")); - if r#move { - std::fs::rename(&input, &source_path)?; - } else if copy { - std::fs::copy(&input, &source_path)?; - } else { - if source_path.is_symlink() { - remove_file(&source_path)?; - } - std::os::unix::fs::symlink(&input, &source_path)?; - } - - 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(MediaSource::Local { - tracks: local_tracks, - }); - source_path_e = Some(source_path) - } else { - kind = NodeKind::Series; - media = None; - source = None; - }; - let node = Node { private: NodePrivate { import: None, backdrop: backdrop.clone().map(AssetLocation::Library), poster: poster.clone().map(AssetLocation::Library), - source, + source: file_meta.as_ref().map(|m| MediaSource::Local { + tracks: m.track_sources.clone(), + }), }, public: NodePublic { parent: None, @@ -224,26 +212,37 @@ fn main() -> anyhow::Result<()> { index: None, kind, children: Vec::new(), - media, + media: file_meta.as_ref().map(|m| MediaInfo { + duration: m.duration, + tracks: m.tracks.clone(), + }), }, }; if args.dry { - println!("{node:?}") + 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(), - )?; + if let Some(source_path) = source_path_e { + let input = input.clone().unwrap(); + if r#move { + std::fs::rename(&input, &source_path)?; + } else if copy { + std::fs::copy(&input, &source_path)?; + } else { + if source_path.is_symlink() { + remove_file(&source_path)?; + } + std::os::unix::fs::symlink(&input, &source_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.with_extension(&format!("si.{tn}")))?, + bincode::config::standard(), + )?; + } } let f = File::create(path.join(if series { "directory.json".to_string() diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs index 4c5275e..a5c4e3c 100644 --- a/remuxer/src/import/mod.rs +++ b/remuxer/src/import/mod.rs @@ -15,13 +15,18 @@ use jellymatroska::{ use log::{debug, error, info, warn}; use std::path::PathBuf; -pub fn import_metadata( - path: &PathBuf, - input: &mut EbmlReader, -) -> Result<(Vec<SourceTrack>, Vec<LocalTrack>, f64)> { - let mut iteminfo = Vec::new(); - let mut private = Vec::new(); - let mut dur = None; +#[derive(Default)] +pub struct MatroskaMetadata { + pub title: Option<String>, + pub description: Option<String>, + pub tracks: Vec<SourceTrack>, + pub track_sources: Vec<LocalTrack>, + pub image: Option<(String, Vec<u8>)>, + pub duration: f64, +} + +pub fn import_metadata(input: &mut EbmlReader) -> Result<MatroskaMetadata> { + let mut m = None; while let Some(item) = input.next() { let item = match item { Ok(item) => item, @@ -50,28 +55,19 @@ pub fn import_metadata( MatroskaTag::Segment(_) => { info!("segment start"); let mut children = Unflatten::new_with_end(input, item); - dur = dur.or(import_read_segment( - path, - &mut children, - &mut iteminfo, - &mut private, - )?); + m = Some(import_read_segment(&mut children)?); info!("segment end"); } _ => debug!("(r) tag ignored: {item:?}"), } } - Ok((iteminfo, private, dur.unwrap_or(0.))) + Ok(m.ok_or(anyhow!("no segment"))?) } -fn import_read_segment( - path: &PathBuf, - segment: &mut Unflatten, - iteminfo: &mut Vec<SourceTrack>, - private: &mut Vec<LocalTrack>, -) -> Result<Option<f64>> { +fn import_read_segment(segment: &mut Unflatten) -> Result<MatroskaMetadata> { let (mut timestamp_scale, mut duration) = (None, None); + let mut m = MatroskaMetadata::default(); while let Some(Ok(Unflat { children, item, .. })) = segment.n() { match item { @@ -83,6 +79,7 @@ fn import_read_segment( })) = children.n() { match item { + MatroskaTag::Title(t) => m.title = Some(t), MatroskaTag::TimestampScale(v) => timestamp_scale = Some(v), MatroskaTag::Duration(v) => duration = Some(v), _ => debug!("(rsi) tag ignored: {item:?}"), @@ -169,16 +166,16 @@ fn import_read_segment( 17 => SourceTrackKind::Subtitles, _ => bail!("invalid track type"), }; - iteminfo.push(SourceTrack { + m.tracks.push(SourceTrack { default_duration, name: name.unwrap_or_else(|| "unnamed".to_string()), codec: codec.unwrap(), language: language.unwrap_or_else(|| "none".to_string()), kind, }); - private.push(LocalTrack { + m.track_sources.push(LocalTrack { track: track_index as usize, - path: path.to_owned(), + path: PathBuf::new(), codec_private, }) } @@ -190,10 +187,9 @@ fn import_read_segment( _ => debug!("(rs) tag ignored: {item:?}"), }; } + if let Some(duration) = duration { + m.duration = (duration * timestamp_scale.unwrap_or(1_000_000) as f64) / 1_000_000_000_f64; + } - Ok(if let Some(duration) = duration { - Some((duration * timestamp_scale.unwrap_or(1_000_000) as f64) / 1_000_000_000_f64) - } else { - None - }) + Ok(m) } |