aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-08-03 22:35:04 +0200
committermetamuffin <metamuffin@disroot.org>2023-08-03 22:35:04 +0200
commitfc74676f349f2e9de6f7a508d4ba3ff66935a6f8 (patch)
treef21fd24a4478d84ecd5044d6a9459e0e8fcf6aa6
parentfd66e97053ff88d1921bbb2d1c276c6fbe66b935 (diff)
downloadjellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar
jellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar.bz2
jellything-fc74676f349f2e9de6f7a508d4ba3ff66935a6f8.tar.zst
dry run works as expected again
-rw-r--r--import/src/main.rs149
-rw-r--r--remuxer/src/import/mod.rs52
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)
}