From 570f24c99af8c9cd1b9050564c32adb85e2c9c0f Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 30 Jan 2025 13:46:29 +0100 Subject: channel.info.json --- import/src/infojson.rs | 28 +++++++++++++------------- import/src/lib.rs | 53 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 33 deletions(-) (limited to 'import/src') diff --git a/import/src/infojson.rs b/import/src/infojson.rs index f4c028b..c2ae305 100644 --- a/import/src/infojson.rs +++ b/import/src/infojson.rs @@ -13,23 +13,23 @@ use std::collections::HashMap; pub struct YVideo { pub id: String, pub title: String, - pub formats: Vec, + pub formats: Option>, pub thumbnails: Vec, - pub thumbnail: String, + pub thumbnail: Option, pub description: String, pub channel_id: String, pub duration: Option, - pub view_count: usize, + pub view_count: Option, pub average_rating: Option, - pub age_limit: usize, + pub age_limit: Option, pub webpage_url: String, - pub categories: Vec, + pub categories: Option>, pub tags: Vec, - pub playable_in_embed: bool, + pub playable_in_embed: Option, pub aspect_ratio: Option, pub width: Option, pub height: Option, - pub automatic_captions: HashMap>, + pub automatic_captions: Option>>, pub comment_count: Option, pub chapters: Option>, pub heatmap: Option>, @@ -40,7 +40,7 @@ pub struct YVideo { pub uploader: Option, pub uploader_id: Option, pub uploader_url: Option, - pub upload_date: String, + pub upload_date: Option, pub availability: Option, // "public" | "private" | "unlisted", pub original_url: Option, pub webpage_url_basename: String, @@ -55,11 +55,11 @@ pub struct YVideo { pub playlist_uploader_id: Option, pub n_entries: Option, pub playlist_index: Option, - pub display_id: String, - pub fulltitle: String, - pub duration_string: String, - pub is_live: bool, - pub was_live: bool, + pub display_id: Option, + pub fulltitle: Option, + pub duration_string: Option, + pub is_live: Option, + pub was_live: Option, pub epoch: usize, } @@ -105,7 +105,7 @@ pub struct YFragment { #[derive(Debug, Serialize, Deserialize)] pub struct YThumbnail { pub url: String, - pub preference: i32, + pub preference: Option, pub id: String, pub height: Option, pub width: Option, diff --git a/import/src/lib.rs b/import/src/lib.rs index 243ac8a..add7e4d 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -9,27 +9,22 @@ use ebml_struct::{ matroska::*, read::{EbmlReadExt, TagRead}, }; +use infojson::YVideo; use jellybase::{assetfed::AssetInner, cache::cache_file, database::Database, CONF, SECRETS}; use jellycommon::{ Chapter, LocalTrack, MediaInfo, Node, NodeID, NodeKind, Rating, SourceTrack, SourceTrackKind, TrackSource, }; -use log::{info, warn}; -use rayon::iter::{ - IntoParallelIterator, IntoParallelRefIterator, ParallelBridge, ParallelDrainRange, - ParallelIterator, -}; +use log::info; +use rayon::iter::{ParallelDrainRange, ParallelIterator}; use regex::Regex; use std::{ - collections::{HashMap, VecDeque}, + collections::HashMap, fs::File, io::{BufReader, ErrorKind, Read, Write}, mem::swap, path::{Path, PathBuf}, - sync::{ - atomic::{AtomicUsize, Ordering}, - LazyLock, - }, + sync::LazyLock, time::UNIX_EPOCH, }; use tmdb::Tmdb; @@ -126,7 +121,6 @@ fn import_iter_inner(path: &Path, db: &Database, incremental: bool) -> Result Result<()> { - let filename = path.file_stem().unwrap().to_string_lossy(); let parent = NodeID::from_slug( &path .parent() @@ -135,20 +129,22 @@ fn import_file(db: &Database, path: &Path) -> Result<()> { .ok_or(anyhow!("parent no filename"))? .to_string_lossy(), ); + + let filename = path.file_name().unwrap().to_string_lossy(); match filename.as_ref() { - "poster" => { + "poster.jpeg" | "poster.webp" => { db.update_node_init(parent, |node| { node.poster = Some(AssetInner::Media(path.to_owned()).ser()); Ok(()) })?; } - "backdrop" => { + "backdrop.jpeg" | "backdrop.webp" => { db.update_node_init(parent, |node| { node.backdrop = Some(AssetInner::Media(path.to_owned()).ser()); Ok(()) })?; } - "info" => { + "info.json" | "info.yaml" => { let data = serde_yaml::from_reader::<_, Node>(BufReader::new(File::open(path)?))?; db.update_node_init(parent, |node| { fn merge_option(a: &mut Option, b: Option) { @@ -162,6 +158,23 @@ fn import_file(db: &Database, path: &Path) -> Result<()> { Ok(()) })?; } + "channel.info.json" => { + let data = serde_json::from_reader::<_, YVideo>(BufReader::new(File::open(path)?))?; + db.update_node_init(parent, |node| { + node.title = Some( + data.title + .strip_suffix(" - Videos") + .unwrap_or(&data.title) + .to_owned(), + ); + node.description = Some(data.description); + if let Some(followers) = data.channel_follower_count { + node.ratings + .insert(Rating::YoutubeFollowers, followers as f64); + } + Ok(()) + })?; + } _ => (), } @@ -288,12 +301,14 @@ fn import_media_file(db: &Database, path: &Path, parent: NodeID) -> Result<()> { node.title = Some(infojson.title); node.description = Some(infojson.description); node.tagline = Some(infojson.webpage_url); - node.release_date = Some( - infojson::parse_upload_date(&infojson.upload_date) - .context("parsing upload date")?, + if let Some(date) = &infojson.upload_date { + node.release_date = + Some(infojson::parse_upload_date(date).context("parsing upload date")?); + } + node.ratings.insert( + Rating::YoutubeViews, + infojson.view_count.unwrap_or_default() as f64, ); - node.ratings - .insert(Rating::YoutubeViews, infojson.view_count as f64); if let Some(lc) = infojson.like_count { node.ratings.insert(Rating::YoutubeLikes, lc as f64); } -- cgit v1.2.3-70-g09d2