feat(kiosk): bump v0.1.2 with video library support for movies, tv shows, and seasons
This commit is contained in:
@@ -36,6 +36,8 @@ pub struct MediaItem {
|
||||
pub artist_name: Option<String>,
|
||||
pub genre: Option<String>,
|
||||
pub index_number: Option<u32>,
|
||||
pub parent_index_number: Option<u32>,
|
||||
pub season_name: Option<String>,
|
||||
pub year: Option<u32>,
|
||||
pub overview: Option<String>,
|
||||
pub rating: Option<f32>,
|
||||
@@ -197,6 +199,7 @@ pub struct JellyfinClient {
|
||||
client: reqwest::Client,
|
||||
pub token: Arc<RwLock<Option<String>>>,
|
||||
pub user_id: Arc<RwLock<Option<String>>>,
|
||||
pub library: Arc<RwLock<MediaLibrary>>,
|
||||
}
|
||||
|
||||
impl JellyfinClient {
|
||||
@@ -206,6 +209,7 @@ impl JellyfinClient {
|
||||
client: reqwest::Client::new(),
|
||||
token: Arc::new(RwLock::new(None)),
|
||||
user_id: Arc::new(RwLock::new(None)),
|
||||
library: Arc::new(RwLock::new(MediaLibrary::default())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +260,17 @@ impl JellyfinClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn ensure_authenticated(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
if self.token.read().await.is_none() {
|
||||
self.authenticate().await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_token(&self) -> Option<String> {
|
||||
self.token.read().await.clone()
|
||||
}
|
||||
|
||||
async fn get_authed_headers(&self) -> Result<HeaderMap, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let token_guard = self.token.read().await;
|
||||
let token = token_guard.as_deref().ok_or("Not authenticated")?;
|
||||
@@ -553,7 +568,7 @@ impl JellyfinClient {
|
||||
let mut favorites = fetch_endpoint(&self.client, &url_fav, &headers).await;
|
||||
sort_media_items_alphabetically(&mut favorites);
|
||||
|
||||
Ok(MediaLibrary {
|
||||
let lib = MediaLibrary {
|
||||
resume_items,
|
||||
latest_movies,
|
||||
latest_shows,
|
||||
@@ -566,7 +581,35 @@ impl JellyfinClient {
|
||||
photos,
|
||||
live_channels,
|
||||
favorites,
|
||||
})
|
||||
};
|
||||
*self.library.write().await = lib.clone();
|
||||
Ok(lib)
|
||||
}
|
||||
|
||||
pub async fn get_library(&self) -> MediaLibrary {
|
||||
{
|
||||
let guard = self.library.read().await;
|
||||
if !guard.all_movies.is_empty() || !guard.all_shows.is_empty() {
|
||||
return guard.clone();
|
||||
}
|
||||
}
|
||||
if let Ok(lib) = self.fetch_all_media().await {
|
||||
return lib;
|
||||
}
|
||||
self.library.read().await.clone()
|
||||
}
|
||||
|
||||
pub async fn fetch_show_episodes(&self, show_id: &str) -> Vec<MediaItem> {
|
||||
let base_url = self.config.server_url.trim_end_matches('/');
|
||||
if let Ok(headers) = self.get_authed_headers().await {
|
||||
let user_id = self.user_id.read().await.clone().unwrap_or_default();
|
||||
let url = format!(
|
||||
"{}/Shows/{}/Episodes?userId={}&fields=Overview,ProductionYear,CommunityRating,ParentBackdropItemId,ParentPrimaryImageItemId,UserData,IndexNumber,ParentIndexNumber,SortName,Genres",
|
||||
base_url, show_id, user_id
|
||||
);
|
||||
return fetch_endpoint(&self.client, &url, &headers).await;
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,6 +659,8 @@ fn parse_items(json: &serde_json::Value) -> Vec<MediaItem> {
|
||||
|
||||
let sort_name = it["SortName"].as_str().map(|s| s.to_string());
|
||||
let index_number = it["IndexNumber"].as_u64().map(|n| n as u32);
|
||||
let parent_index_number = it["ParentIndexNumber"].as_u64().map(|n| n as u32);
|
||||
let season_name = it["SeasonName"].as_str().map(|s| s.to_string());
|
||||
|
||||
if !id.is_empty() {
|
||||
out.push(MediaItem {
|
||||
@@ -627,6 +672,8 @@ fn parse_items(json: &serde_json::Value) -> Vec<MediaItem> {
|
||||
artist_name,
|
||||
genre,
|
||||
index_number,
|
||||
parent_index_number,
|
||||
season_name,
|
||||
year,
|
||||
overview,
|
||||
rating,
|
||||
|
||||
Reference in New Issue
Block a user