aboutsummaryrefslogtreecommitdiff
path: root/import/src/plugins/infojson.rs
diff options
context:
space:
mode:
Diffstat (limited to 'import/src/plugins/infojson.rs')
-rw-r--r--import/src/plugins/infojson.rs144
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(())