diff options
Diffstat (limited to 'import/src/plugins/infojson.rs')
| -rw-r--r-- | import/src/plugins/infojson.rs | 144 |
1 files changed, 88 insertions, 56 deletions
diff --git a/import/src/plugins/infojson.rs b/import/src/plugins/infojson.rs index fd15e03..72dd1ab 100644 --- a/import/src/plugins/infojson.rs +++ b/import/src/plugins/infojson.rs @@ -3,17 +3,22 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ +use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; use anyhow::{Context, Result, anyhow}; use chrono::{Utc, format::Parsed}; use jellycache::cache_read; +use jellycommon::{ + IDENT_BANDCAMP, IDENT_YOUTUBE_CHANNEL, IDENT_YOUTUBE_CHANNEL_HANDLE, IDENT_YOUTUBE_VIDEO, + KIND_CHANNEL, KIND_MUSIC, KIND_SHORTFORMVIDEO, KIND_VIDEO, NO_DESCRIPTION, NO_IDENTIFIERS, + NO_KIND, NO_RATINGS, NO_RELEASEDATE, NO_SUBTITLE, NO_TAG, NO_TITLE, RTYP_YOUTUBE_FOLLOWERS, + RTYP_YOUTUBE_LIKES, RTYP_YOUTUBE_VIEWS, +}; use jellydb::table::RowNum; use jellyremuxer::matroska::{AttachedFile, Segment}; use log::info; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fs::File, io::BufReader, path::Path}; -use crate::plugins::{ImportContext, ImportPlugin, PluginInfo}; - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct YVideo { pub album: Option<String>, @@ -174,29 +179,38 @@ impl ImportPlugin for Infojson { info!("import channel info.json at {path:?}"); let data = serde_json::from_reader::<_, YVideo>(BufReader::new(File::open(path)?))?; - ct.db.update_node_init(parent, |node| { - node.kind = NodeKind::Channel; - node.title = Some(clean_uploader_name(&data.title).to_owned()); - if let Some(cid) = data.channel_id { - node.identifiers.insert(IdentifierType::YoutubeChannel, cid); + let title = clean_uploader_name(&data.title); + + ct.dba.db.write_transaction(&mut |txn| { + let mut node = ct.dba.nodes.get(txn, parent)?.unwrap(); + node = node.as_object().insert(NO_KIND, KIND_CHANNEL); + node = node.as_object().insert(NO_TITLE, title); + if let Some(cid) = &data.channel_id { + node = node.as_object().update(NO_IDENTIFIERS, |ids| { + ids.insert(IDENT_YOUTUBE_CHANNEL, &cid) + }); } - if let Some(uid) = data.uploader_id { - node.identifiers - .insert(IdentifierType::YoutubeChannelHandle, uid); + if let Some(uid) = &data.uploader_id { + node = node.as_object().update(NO_IDENTIFIERS, |ids| { + ids.insert(IDENT_YOUTUBE_CHANNEL_HANDLE, &uid) + }) } - if let Some(desc) = data.description { - node.description = Some(desc); + if let Some(desc) = &data.description { + node = node.as_object().insert(NO_DESCRIPTION, &desc); } if let Some(followers) = data.channel_follower_count { - node.ratings - .insert(RatingType::YoutubeFollowers, followers as f64); + node = node.as_object().update(NO_RATINGS, |rat| { + rat.insert(RTYP_YOUTUBE_FOLLOWERS, followers as f64) + }); } - })?; + + ct.dba.nodes.update(txn, parent, node) + }); Ok(()) } - fn media(&self, ct: &ImportContext, node: NodeID, _path: &Path, seg: &Segment) -> Result<()> { + fn media(&self, ct: &ImportContext, row: RowNum, _path: &Path, seg: &Segment) -> Result<()> { let infojson = seg .attachments .iter() @@ -217,53 +231,71 @@ impl ImportPlugin for Infojson { .map(|date| parse_upload_date(date).context("parsing upload date")) .transpose()?; - ct.db.update_node_init(node, |node| { - node.kind = if let Some(ty) = &infojson.media_type - && ty == "short" + let kind = if let Some(ty) = &infojson.media_type + && ty == "short" + { + KIND_SHORTFORMVIDEO + } else if infojson.album.is_some() { + KIND_MUSIC + } else { + KIND_VIDEO + }; + + ct.dba.db.write_transaction(&mut |txn| { + let mut node = ct.dba.nodes.get(txn, row)?.unwrap(); + node = node.as_object().insert(NO_KIND, kind); + node = node.as_object().insert(NO_TITLE, &infojson.title); + if let Some(title) = &infojson.alt_title + && title != &infojson.title + && !node.as_object().has(NO_SUBTITLE.0) { - NodeKind::ShortFormVideo - } else if infojson.album.is_some() { - NodeKind::Music - } else { - NodeKind::Video - }; - node.title = Some(infojson.title); - node.subtitle = if infojson.alt_title != node.title { - infojson.alt_title - } else { - None + node = node.as_object().insert(NO_SUBTITLE, &title); } - .or(infojson - .uploader - .as_ref() - .map(|u| clean_uploader_name(u).to_owned())) - .or(node.subtitle.clone()); - - node.tags.extend(infojson.tags.unwrap_or_default()); - - if let Some(desc) = infojson.description { - node.description = Some(desc) + if let Some(up) = &infojson.uploader + && !node.as_object().has(NO_SUBTITLE.0) + { + node = node + .as_object() + .insert(NO_SUBTITLE, &clean_uploader_name(&up)); + } + if let Some(desc) = &infojson.description { + node = node.as_object().insert(NO_DESCRIPTION, &desc); + } + if let Some(tag) = infojson.tags.clone() { + node = node + .as_object() + .extend(NO_TAG, tag.iter().map(String::as_str)); + } + if let Some(rd) = release_date { + node = node.as_object().insert(NO_RELEASEDATE, rd); } - node.release_date = release_date.or(node.release_date); - node.tagline = Some(infojson.webpage_url); match infojson.extractor.as_str() { "youtube" => { - node.identifiers - .insert(IdentifierType::YoutubeVideo, infojson.id); - node.ratings.insert( - RatingType::YoutubeViews, - infojson.view_count.unwrap_or_default() as f64, - ); - if let Some(lc) = infojson.like_count { - node.ratings.insert(RatingType::YoutubeLikes, lc as f64); - } + node = node.as_object().update(NO_IDENTIFIERS, |rat| { + rat.insert(IDENT_YOUTUBE_VIDEO, &infojson.id) + }); + node = node.as_object().update(NO_RATINGS, |rat| { + rat.insert( + RTYP_YOUTUBE_VIEWS, + infojson.view_count.unwrap_or_default() as f64, + ) + }); + node = node.as_object().update(NO_RATINGS, |rat| { + rat.insert( + RTYP_YOUTUBE_LIKES, + infojson.like_count.unwrap_or_default() as f64, + ) + }); + } + "Bandcamp" => { + node = node.as_object().update(NO_IDENTIFIERS, |rat| { + rat.insert(IDENT_BANDCAMP, &infojson.id) + }); } - "Bandcamp" => drop( - node.identifiers - .insert(IdentifierType::Bandcamp, infojson.id), - ), _ => (), - } + }; + + ct.dba.nodes.update(txn, row, node) })?; } Ok(()) |