Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add show crew information in series page #139

Merged
merged 1 commit into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/api/tv_maze/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use thiserror::Error;

pub mod episodes_information;
pub mod image;
pub mod people;
pub mod seasons_list;
pub mod series_information;
pub mod series_searching;
pub mod show_cast;
pub mod show_images;
pub mod show_lookup;
pub mod tv_schedule;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::core::api::tv_maze::Image;
use serde::Deserialize;

use super::{get_pretty_json_from_url, ApiError, Image};
pub mod show_cast;
pub mod show_crew;

#[derive(Deserialize, Debug, Clone)]
pub struct Cast {
pub person: Person,
pub character: Character,
pub struct Country {
pub name: String,
}

#[derive(Deserialize, Debug, Clone)]
Expand All @@ -30,23 +31,15 @@ pub enum AgeError {
Parse(chrono::ParseError),
}

impl Cast {
impl Person {
pub fn birth_naive_date(&self) -> Result<chrono::NaiveDate, AgeError> {
let date = self
.person
.birthday
.as_ref()
.ok_or(AgeError::BirthdateNotFound)?;
let date = self.birthday.as_ref().ok_or(AgeError::BirthdateNotFound)?;

chrono::NaiveDate::parse_from_str(date, "%Y-%m-%d").map_err(AgeError::Parse)
}

pub fn death_naive_date(&self) -> Result<chrono::NaiveDate, AgeError> {
let date = self
.person
.deathday
.as_ref()
.ok_or(AgeError::DeathdateNotFound)?;
let date = self.deathday.as_ref().ok_or(AgeError::DeathdateNotFound)?;

chrono::NaiveDate::parse_from_str(date, "%Y-%m-%d").map_err(AgeError::Parse)
}
Expand All @@ -66,25 +59,3 @@ impl Cast {
Ok(deathdate.signed_duration_since(birthdate))
}
}

#[derive(Deserialize, Debug, Clone)]
pub struct Country {
pub name: String,
}

#[derive(Deserialize, Debug, Clone)]
pub struct Character {
pub name: String,
pub image: Option<Image>,
}

// replace ID with the actual show id
const SHOW_CAST_ADDRESS: &str = "https://api.tvmaze.com/shows/ID/cast";

pub async fn get_show_cast(series_id: u32) -> Result<String, ApiError> {
let url = SHOW_CAST_ADDRESS.replace("ID", &series_id.to_string());

get_pretty_json_from_url(url)
.await
.map_err(ApiError::Network)
}
27 changes: 27 additions & 0 deletions src/core/api/tv_maze/people/show_cast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use serde::Deserialize;

pub use super::AgeError;
use crate::core::api::tv_maze::{get_pretty_json_from_url, ApiError, Image};

#[derive(Deserialize, Debug, Clone)]
pub struct Cast {
pub person: super::Person,
pub character: Character,
}

#[derive(Deserialize, Debug, Clone)]
pub struct Character {
pub name: String,
pub image: Option<Image>,
}

// replace ID with the actual show id
const SHOW_CAST_ADDRESS: &str = "https://api.tvmaze.com/shows/ID/cast";

pub async fn get_show_cast(series_id: u32) -> Result<String, ApiError> {
let url = SHOW_CAST_ADDRESS.replace("ID", &series_id.to_string());

get_pretty_json_from_url(url)
.await
.map_err(ApiError::Network)
}
22 changes: 22 additions & 0 deletions src/core/api/tv_maze/people/show_crew.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use serde::Deserialize;

pub use super::AgeError;
use crate::core::api::tv_maze::{get_pretty_json_from_url, ApiError};

#[derive(Deserialize, Debug, Clone)]
pub struct Crew {
#[serde(rename = "type")]
pub kind: String,
pub person: super::Person,
}

// replace ID with the actual show id
const SHOW_CREW_ADDRESS: &str = "https://api.tvmaze.com/shows/ID/crew";

pub async fn get_show_crew(series_id: u32) -> Result<String, ApiError> {
let url = SHOW_CREW_ADDRESS.replace("ID", &series_id.to_string());

get_pretty_json_from_url(url)
.await
.map_err(ApiError::Network)
}
10 changes: 9 additions & 1 deletion src/core/caching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! - `main-info`. The main series information.
//! - `episode-list`. The list of all episode of the series.
//! - `show-cast`. The list of top cast of the series.
//! - `show-crew`. The list of top crew of the series.
//! - `image-list`. The list of all images of the series i.e posters, banners, backgrounds etc.
//!
//! ## Images cache directory
Expand All @@ -39,10 +40,10 @@ use tracing::{error, info};

pub mod cache_updating;
pub mod episode_list;
pub mod people;
pub mod series_info_and_episode_list;
pub mod series_information;
pub mod series_list;
pub mod show_cast;
pub mod show_images;
pub mod tv_schedule;

Expand All @@ -51,6 +52,7 @@ const IMAGES_CACHE_DIRECTORY: &str = "images-cache";
const EPISODE_LIST_FILENAME: &str = "episode-list";
const SERIES_MAIN_INFORMATION_FILENAME: &str = "main-info";
const SERIES_CAST_FILENAME: &str = "show-cast";
const SERIES_CREW_FILENAME: &str = "show-crew";
const SERIES_IMAGE_LIST_FILENAME: &str = "image-list";

lazy_static! {
Expand All @@ -66,6 +68,7 @@ pub enum CacheFilePath {
SeriesMainInformation(u32),
SeriesEpisodeList(u32),
SeriesShowCast(u32),
SeriesShowCrew(u32),
SeriesImageList(u32),
}

Expand Down Expand Up @@ -119,6 +122,11 @@ impl Cacher {
cache_folder.push(SERIES_CAST_FILENAME);
cache_folder
}
CacheFilePath::SeriesShowCrew(series_id) => {
let mut cache_folder = self.get_series_cache_folder_path(series_id);
cache_folder.push(SERIES_CREW_FILENAME);
cache_folder
}
CacheFilePath::SeriesImageList(series_id) => {
let mut cache_folder = self.get_series_cache_folder_path(series_id);
cache_folder.push(SERIES_IMAGE_LIST_FILENAME);
Expand Down
44 changes: 44 additions & 0 deletions src/core/caching/people.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::io::ErrorKind;

use tracing::info;

use super::{CacheFilePath, CACHER};
use crate::core::api::tv_maze::deserialize_json;
use crate::core::api::tv_maze::people::show_cast::{self, Cast};
use crate::core::api::tv_maze::people::show_crew::{self, Crew};
use crate::core::api::tv_maze::ApiError;
use crate::core::caching::{read_cache, write_cache};

pub async fn get_show_cast(series_id: u32) -> Result<Vec<Cast>, ApiError> {
let series_cast_filepath = CACHER.get_cache_file_path(CacheFilePath::SeriesShowCast(series_id));

let json_string = match read_cache(&series_cast_filepath).await {
Ok(json_string) => json_string,
Err(err) => {
info!("falling back online for 'show cast' for series id: {series_id}");
let json_string = show_cast::get_show_cast(series_id).await?;
if err.kind() == ErrorKind::NotFound {
write_cache(&json_string, &series_cast_filepath).await;
}
json_string
}
};
deserialize_json(&json_string)
}

pub async fn get_show_crew(series_id: u32) -> Result<Vec<Crew>, ApiError> {
let series_crew_filepath = CACHER.get_cache_file_path(CacheFilePath::SeriesShowCrew(series_id));

let json_string = match read_cache(&series_crew_filepath).await {
Ok(json_string) => json_string,
Err(err) => {
info!("falling back online for 'show crew' for series id: {series_id}");
let json_string = show_crew::get_show_crew(series_id).await?;
if err.kind() == ErrorKind::NotFound {
write_cache(&json_string, &series_crew_filepath).await;
}
json_string
}
};
deserialize_json(&json_string)
}
30 changes: 0 additions & 30 deletions src/core/caching/show_cast.rs

This file was deleted.

31 changes: 16 additions & 15 deletions src/gui/series_page/series/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::core::api::tv_maze::series_information::SeriesMainInformation;
use crate::core::api::tv_maze::Image;
use crate::core::{caching, database};
use crate::gui::styles;
use cast_widget::{CastWidget, Message as CastWidgetMessage};
use data_widgets::*;
use people_widget::{Message as PeopleWidgetMessage, PeopleWidget};
use season_widget::{Message as SeasonsMessage, Seasons};
use series_suggestion_widget::{Message as SeriesSuggestionMessage, SeriesSuggestion};

Expand All @@ -17,8 +17,8 @@ use iced::widget::vertical_space;
use iced::widget::{column, scrollable};
use iced::{Command, Element, Renderer};

mod cast_widget;
mod data_widgets;
mod people_widget;
mod season_widget;
mod series_suggestion_widget;

Expand All @@ -27,7 +27,7 @@ pub enum Message {
SeriesImageLoaded(Option<Bytes>),
SeriesBackgroundLoaded(Option<Bytes>),
Seasons(SeasonsMessage),
CastWidgetAction(CastWidgetMessage),
PeopleWidget(PeopleWidgetMessage),
SeriesSuggestion(SeriesSuggestionMessage),
PageScrolled(Viewport),
TrackSeries,
Expand All @@ -41,7 +41,7 @@ pub struct Series<'a> {
series_image_blurred: Option<image::DynamicImage>,
series_background: Option<Bytes>,
seasons: Seasons,
casts_widget: CastWidget,
people_widget: PeopleWidget,
series_suggestion_widget: SeriesSuggestion<'a>,
scroll_offset: RelativeOffset,
scroller_id: Id,
Expand All @@ -54,7 +54,7 @@ impl<'a> Series<'a> {
series_page_sender: mpsc::Sender<SeriesMainInformation>,
) -> (Self, Command<Message>) {
let series_id = series_information.id;
let (casts_widget, casts_widget_command) = CastWidget::new(series_id);
let (people_widget, people_widget_command) = PeopleWidget::new(series_id);
let (seasons, seasons_command) = Seasons::new(series_id, series_information.name.clone());

let (series_suggestion_widget, series_suggestion_widget_command) = SeriesSuggestion::new(
Expand All @@ -72,7 +72,7 @@ impl<'a> Series<'a> {
series_image_blurred: None,
series_background: None,
seasons,
casts_widget,
people_widget,
series_suggestion_widget,
scroll_offset: RelativeOffset::default(),
scroller_id: scroller_id.clone(),
Expand All @@ -83,7 +83,7 @@ impl<'a> Series<'a> {
let commands = [
Command::batch(load_images(series_image, series_id)),
seasons_command.map(Message::Seasons),
casts_widget_command.map(Message::CastWidgetAction),
people_widget_command.map(Message::PeopleWidget),
series_suggestion_widget_command.map(Message::SeriesSuggestion),
scroller_command,
];
Expand Down Expand Up @@ -144,12 +144,6 @@ impl<'a> Series<'a> {
series.mark_untracked();
}
}
Message::CastWidgetAction(message) => {
return self
.casts_widget
.update(message)
.map(Message::CastWidgetAction)
}
Message::SeriesBackgroundLoaded(background) => self.series_background = background,
Message::SeriesSuggestion(message) => {
return self
Expand All @@ -160,6 +154,12 @@ impl<'a> Series<'a> {
Message::PageScrolled(view_port) => {
self.scroll_offset = view_port.relative_offset();
}
Message::PeopleWidget(message) => {
return self
.people_widget
.update(message)
.map(Message::PeopleWidget)
}
}
Command::none()
}
Expand All @@ -178,7 +178,8 @@ impl<'a> Series<'a> {

let seasons_widget = self.seasons.view().map(Message::Seasons);

let casts_widget = self.casts_widget.view().map(Message::CastWidgetAction);
let people_widget = self.people_widget.view().map(Message::PeopleWidget);

let series_suggestion_widget = self
.series_suggestion_widget
.view()
Expand All @@ -189,7 +190,7 @@ impl<'a> Series<'a> {
series_metadata,
vertical_space(10),
seasons_widget,
casts_widget,
people_widget,
series_suggestion_widget
];

Expand Down
Loading
Loading