From 63a332dee717e931d45c35259c06d56e98e204fb Mon Sep 17 00:00:00 2001 From: Zoarial94 Date: Sat, 5 Oct 2024 10:37:45 -0400 Subject: [PATCH 1/4] Fixed checking for the blacklisted library's name --- jellyfin-rpc/src/jellyfin.rs | 12 ++++++++++- jellyfin-rpc/src/lib.rs | 39 +++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/jellyfin-rpc/src/jellyfin.rs b/jellyfin-rpc/src/jellyfin.rs index 3ef92d6..79fbffc 100644 --- a/jellyfin-rpc/src/jellyfin.rs +++ b/jellyfin-rpc/src/jellyfin.rs @@ -186,6 +186,7 @@ pub struct NowPlayingItem { pub extra_type: Option, pub album_id: Option, pub album: Option, + pub path: Option, } #[derive(Deserialize, Debug, Clone)] @@ -327,8 +328,17 @@ pub struct PlayState { pub position_ticks: Option, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "PascalCase")] pub struct Item { pub name: Option, + pub path: Option, } + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "PascalCase")] +pub struct VirtualFolder { + pub name: Option, + pub locations: Vec, + pub collection_type: MediaType, +} \ No newline at end of file diff --git a/jellyfin-rpc/src/lib.rs b/jellyfin-rpc/src/lib.rs index 6436fc3..d643e83 100644 --- a/jellyfin-rpc/src/lib.rs +++ b/jellyfin-rpc/src/lib.rs @@ -10,6 +10,7 @@ use log::debug; use reqwest::header::{HeaderMap, AUTHORIZATION}; use std::str::FromStr; use url::Url; +use crate::jellyfin::VirtualFolder; mod error; mod external; @@ -523,26 +524,23 @@ impl Client { } } - fn get_ancestors(&self) -> JfResult> { - let session = self.session.as_ref().unwrap(); + fn get_virtual_media_folders(&self) -> JfResult> { - let ancestors: Vec = self + let virtual_folders: Vec = self .reqwest .get( self.url - .join(&format!("Items/{}/Ancestors", session.now_playing_item.id))?, + .join(&"Library/VirtualFolders".to_string())?, ) .send()? .json()?; - debug!("Ancestors: {:?}", ancestors); - - Ok(ancestors) + Ok(virtual_folders) } fn check_blacklist(&self) -> JfResult { let session = self.session.as_ref().unwrap(); - let ancestors = self.get_ancestors()?; + let media_folders = self.get_virtual_media_folders()?; if self .blacklist @@ -553,11 +551,24 @@ impl Client { return Ok(true); } - if self.blacklist.libraries.iter().any(|l| { - ancestors - .iter() - .any(|a| l == a.name.as_ref().unwrap_or(&"".to_string())) - }) { + let matching_media_folders: Vec<&VirtualFolder> = media_folders + .iter() + .filter(|vf| self.blacklist.libraries_names.contains(vf.name.as_ref().unwrap())).collect(); + + debug!("Matching media folders: {:?}", matching_media_folders); + + if matching_media_folders.iter() + .any(|blacklisted_mf| { + blacklisted_mf.locations.iter().any(|physical_folder| { + debug!("Playing now: {}\nBL: {}", session.now_playing_item.path.as_ref().unwrap().to_string(), physical_folder); + session.now_playing_item + .path.as_ref().unwrap().starts_with(physical_folder) + } + ) + + } + ) + { return Ok(true); } @@ -866,7 +877,7 @@ impl ClientBuilder { }, blacklist: Blacklist { media_types: self.blacklist_media_types, - libraries: self.blacklist_libraries, + libraries_names: self.blacklist_libraries, }, show_paused: self.show_paused, show_images: self.show_images, From e86ef308a8dcb0f141c3d659ac4a685572415bd6 Mon Sep 17 00:00:00 2001 From: Zoarial94 Date: Sat, 5 Oct 2024 12:20:06 -0400 Subject: [PATCH 2/4] Added a cache for blacklisted libraries since it could be an expensive operation --- jellyfin-rpc/src/jellyfin.rs | 8 --- jellyfin-rpc/src/lib.rs | 104 +++++++++++++++++++++++------------ 2 files changed, 69 insertions(+), 43 deletions(-) diff --git a/jellyfin-rpc/src/jellyfin.rs b/jellyfin-rpc/src/jellyfin.rs index 79fbffc..d359980 100644 --- a/jellyfin-rpc/src/jellyfin.rs +++ b/jellyfin-rpc/src/jellyfin.rs @@ -328,17 +328,9 @@ pub struct PlayState { pub position_ticks: Option, } -#[derive(Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -pub struct Item { - pub name: Option, - pub path: Option, -} - #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "PascalCase")] pub struct VirtualFolder { pub name: Option, pub locations: Vec, - pub collection_type: MediaType, } \ No newline at end of file diff --git a/jellyfin-rpc/src/lib.rs b/jellyfin-rpc/src/lib.rs index d643e83..f777a1a 100644 --- a/jellyfin-rpc/src/lib.rs +++ b/jellyfin-rpc/src/lib.rs @@ -5,12 +5,13 @@ use discord_rich_presence::{ }; pub use error::JfError; pub use jellyfin::{Button, MediaType}; -use jellyfin::{ExternalUrl, Item, PlayTime, RawSession, Session}; +use jellyfin::{ExternalUrl, PlayTime, RawSession, Session}; use log::debug; use reqwest::header::{HeaderMap, AUTHORIZATION}; use std::str::FromStr; use url::Url; -use crate::jellyfin::VirtualFolder; +use crate::BlacklistedLibraries::{Initialized, Uninitialized}; +use crate::jellyfin::{NowPlayingItem, VirtualFolder}; mod error; mod external; @@ -97,6 +98,14 @@ impl Client { pub fn set_activity(&mut self) -> JfResult { self.get_session()?; + // Make sure the blacklist cache is loaded/valid + match &self.blacklist.libraries { + Uninitialized => { + self.reload_blacklist(); + }, + _ => {} + } + if let Some(session) = &self.session { if session.now_playing_item.media_type == MediaType::None { return Err(Box::new(JfError::UnrecognizedMediaType)); @@ -524,23 +533,8 @@ impl Client { } } - fn get_virtual_media_folders(&self) -> JfResult> { - - let virtual_folders: Vec = self - .reqwest - .get( - self.url - .join(&"Library/VirtualFolders".to_string())?, - ) - .send()? - .json()?; - - Ok(virtual_folders) - } - fn check_blacklist(&self) -> JfResult { let session = self.session.as_ref().unwrap(); - let media_folders = self.get_virtual_media_folders()?; if self .blacklist @@ -551,29 +545,34 @@ impl Client { return Ok(true); } - let matching_media_folders: Vec<&VirtualFolder> = media_folders - .iter() - .filter(|vf| self.blacklist.libraries_names.contains(vf.name.as_ref().unwrap())).collect(); - - debug!("Matching media folders: {:?}", matching_media_folders); - - if matching_media_folders.iter() - .any(|blacklisted_mf| { - blacklisted_mf.locations.iter().any(|physical_folder| { - debug!("Playing now: {}\nBL: {}", session.now_playing_item.path.as_ref().unwrap().to_string(), physical_folder); - session.now_playing_item - .path.as_ref().unwrap().starts_with(physical_folder) - } - ) - - } - ) + if self.blacklist.check_item(&session.now_playing_item) { return Ok(true); } Ok(false) } + + /// Fetch the virtual folder list and filter out the blacklisted libraries + fn fetch_blacklist(&self) -> JfResult> { + let virtual_folders : Vec = self.reqwest + .get( + self.url + .join(&"Library/VirtualFolders".to_string())?, + ) + .send()? + .json()?; + + Ok(virtual_folders + .into_iter() + .filter(|library_folder| self.blacklist.libraries_names.contains(library_folder.name.as_ref().unwrap())).collect() + ) + } + + /// Reload the library list from Jellyfin and filter out the user-provided blacklisted libraries + fn reload_blacklist(&mut self) { + self.blacklist.libraries = Initialized(self.fetch_blacklist().unwrap()) + } } struct EpisodeDisplayOptions { @@ -589,7 +588,41 @@ struct DisplayOptions { struct Blacklist { media_types: Vec, - libraries: Vec, + libraries_names: Vec, + libraries: BlacklistedLibraries +} + +enum BlacklistedLibraries { + Uninitialized, + Initialized(Vec), +} + +impl Blacklist { + + /// Check whether a [NowPlayingItem] is in a blacklisted library + fn check_item(&self, playing_item: &NowPlayingItem) -> bool { + self.check_path(&*playing_item.path.as_ref().unwrap()) + } + + /// Check whether a path is in a blacklisted library + fn check_path(&self, item_path: &str) -> bool { + match &self.libraries { + Initialized (libraries) => { + libraries + .iter() + .any(|blacklisted_mf| { + blacklisted_mf.locations.iter().any(|physical_folder| { + debug!("Playing now: {}\nBL: {}", item_path, physical_folder); + item_path.starts_with(physical_folder) + }) + }) + + } + _ => { + false + } + } + } } struct ImgurOptions { @@ -878,6 +911,7 @@ impl ClientBuilder { blacklist: Blacklist { media_types: self.blacklist_media_types, libraries_names: self.blacklist_libraries, + libraries: Uninitialized, }, show_paused: self.show_paused, show_images: self.show_images, From eed111c88102bbf7fe57a6125da06762807b1893 Mon Sep 17 00:00:00 2001 From: Zoarial94 Date: Sat, 5 Oct 2024 12:24:34 -0400 Subject: [PATCH 3/4] Use local build of jellyfin-rpc --- Cargo.lock | 16 +--------------- jellyfin-rpc-cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b9546b..350d4de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -421,27 +421,13 @@ dependencies = [ "url", ] -[[package]] -name = "jellyfin-rpc" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf58e81834dcd46aa84eb1a8a076de0d99eb98e007bb124891997e28a9fc75f" -dependencies = [ - "discord-rich-presence", - "log", - "reqwest", - "serde", - "serde_json", - "url", -] - [[package]] name = "jellyfin-rpc-cli" version = "1.3.0" dependencies = [ "clap", "colored", - "jellyfin-rpc 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jellyfin-rpc", "log", "reqwest", "retry", diff --git a/jellyfin-rpc-cli/Cargo.toml b/jellyfin-rpc-cli/Cargo.toml index 27918d8..17a8b1d 100644 --- a/jellyfin-rpc-cli/Cargo.toml +++ b/jellyfin-rpc-cli/Cargo.toml @@ -30,7 +30,7 @@ serde_json = "1.0" [dependencies.jellyfin-rpc] version = "1.3.0" -#path = "../jellyfin-rpc" +path = "../jellyfin-rpc" [dependencies.clap] features = ["derive"] From d8a39f2340ea205ed6247ece62b6150b149cd077 Mon Sep 17 00:00:00 2001 From: Zoarial94 Date: Sat, 5 Oct 2024 12:40:19 -0400 Subject: [PATCH 4/4] Adjusted debug logs --- jellyfin-rpc/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jellyfin-rpc/src/lib.rs b/jellyfin-rpc/src/lib.rs index f777a1a..a2a5dbd 100644 --- a/jellyfin-rpc/src/lib.rs +++ b/jellyfin-rpc/src/lib.rs @@ -601,6 +601,7 @@ impl Blacklist { /// Check whether a [NowPlayingItem] is in a blacklisted library fn check_item(&self, playing_item: &NowPlayingItem) -> bool { + debug!("Checking if an item is blacklisted: {}", playing_item.name); self.check_path(&*playing_item.path.as_ref().unwrap()) } @@ -608,11 +609,12 @@ impl Blacklist { fn check_path(&self, item_path: &str) -> bool { match &self.libraries { Initialized (libraries) => { + debug!("Checking path: {}", item_path); libraries .iter() .any(|blacklisted_mf| { blacklisted_mf.locations.iter().any(|physical_folder| { - debug!("Playing now: {}\nBL: {}", item_path, physical_folder); + debug!("BL path: {}", physical_folder); item_path.starts_with(physical_folder) }) })