aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/lib.rs2
-rw-r--r--import/src/lib.rs84
2 files changed, 76 insertions, 10 deletions
diff --git a/common/src/lib.rs b/common/src/lib.rs
index e61bdb9..c836b95 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -221,7 +221,7 @@ pub enum Rating {
Trakt,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Encode, Decode)]
#[serde(rename_all = "snake_case")]
pub enum SourceTrackKind {
Video {
diff --git a/import/src/lib.rs b/import/src/lib.rs
index 547179c..678d065 100644
--- a/import/src/lib.rs
+++ b/import/src/lib.rs
@@ -21,7 +21,7 @@ use jellybase::{
use jellyclient::Session;
use jellycommon::{
AssetLocation, AssetRole, ExtendedNode, ImportOptions, ImportSource, MediaInfo, Node, NodeKind,
- NodePrivate, NodePublic, PeopleGroup, Rating, TrackSource,
+ NodePrivate, NodePublic, PeopleGroup, Rating, SourceTrack, TrackSource,
};
use jellymatroska::read::EbmlReader;
use jellyremuxer::import::import_metadata;
@@ -109,7 +109,7 @@ pub fn merge_nodes(db: &DataAcid) -> anyhow::Result<()> {
let mut node = nodes
.into_iter()
.map(|(_, x)| x)
- .reduce(|x, y| merge_node(x, y))
+ .reduce(|x, y| merge_node(x, y).unwrap())
.unwrap();
node.public.id = Some(id.value().to_owned());
@@ -174,9 +174,9 @@ pub fn generate_node_paths(db: &DataAcid) -> anyhow::Result<()> {
fn compare_index_path(x: &[usize], y: &[usize]) -> Ordering {
if x.is_empty() {
- Ordering::Greater
- } else if y.is_empty() {
Ordering::Less
+ } else if y.is_empty() {
+ Ordering::Greater
} else {
match x[0].cmp(&y[0]) {
o @ (Ordering::Less | Ordering::Greater) => o,
@@ -592,8 +592,23 @@ pub fn infer_id_from_path(path: &Path) -> anyhow::Result<String> {
Ok(fsan)
}
-fn merge_node(x: Node, y: Node) -> Node {
- Node {
+fn merge_node(x: Node, y: Node) -> anyhow::Result<Node> {
+ let (media, source) = match (
+ x.public.media,
+ y.public.media,
+ x.private.source,
+ y.private.source,
+ ) {
+ (Some(x), Some(y), Some(sx), Some(sy)) => {
+ let k = merge_media(x, y, sx, sy);
+ (Some(k.0), Some(k.1))
+ }
+ (Some(x), None, Some(sx), None) => (Some(x), Some(sx)),
+ (None, Some(y), None, Some(sy)) => (Some(y), Some(sy)),
+ (None, None, None, None) => (None, None),
+ _ => bail!("invalid node. source and media dont agree."),
+ };
+ Ok(Node {
public: NodePublic {
kind: x.public.kind.or(y.public.kind),
title: x.public.title.or(y.public.title),
@@ -604,7 +619,7 @@ fn merge_node(x: Node, y: Node) -> Node {
description: x.public.description.or(y.public.description),
release_date: x.public.release_date.or(y.public.release_date),
index: x.public.index.or(y.public.index),
- media: x.public.media.or(y.public.media), // TODO proper media merging
+ media,
ratings: x
.public
.ratings
@@ -617,9 +632,9 @@ fn merge_node(x: Node, y: Node) -> Node {
id: x.private.id.or(y.private.id),
poster: x.private.poster.or(y.private.poster),
backdrop: x.private.backdrop.or(y.private.backdrop),
- source: x.private.source.or(y.private.source), // TODO here too
+ source,
},
- }
+ })
}
fn merge_children(mut a: Vec<String>, b: Vec<String>) -> Vec<String> {
@@ -631,6 +646,57 @@ fn merge_children(mut a: Vec<String>, b: Vec<String>) -> Vec<String> {
}
a
}
+fn merge_media(
+ x: MediaInfo,
+ y: MediaInfo,
+ sx: Vec<TrackSource>,
+ sy: Vec<TrackSource>,
+) -> (MediaInfo, Vec<TrackSource>) {
+ let mut tracks: Vec<SourceTrack> = Vec::new();
+ let mut source: Vec<TrackSource> = Vec::new();
+ for (t, s) in x
+ .tracks
+ .into_iter()
+ .zip(sx.into_iter())
+ .chain(y.tracks.into_iter().zip(sy.into_iter()))
+ {
+ let mut remove = None;
+ let mut skip = false;
+ for (i, ot) in tracks.iter().enumerate() {
+ if t.name == ot.name
+ && t.kind == ot.kind
+ && t.language == ot.language
+ && t.codec == ot.codec
+ {
+ if t.federated.len() < ot.federated.len() {
+ remove = Some(i);
+ } else {
+ skip = true;
+ }
+ }
+ }
+ if let Some(r) = remove {
+ tracks.swap_remove(r);
+ source.swap_remove(r);
+ }
+ if !skip {
+ tracks.push(t);
+ source.push(s);
+ }
+ }
+ (
+ MediaInfo {
+ duration: x.duration * 0.5 + y.duration * 0.5,
+ tracks,
+ chapters: if x.chapters.len() > y.chapters.len() {
+ x.chapters
+ } else {
+ y.chapters
+ },
+ },
+ source,
+ )
+}
static SEM_REMOTE_IMPORT: Semaphore = Semaphore::const_new(16);