Skip to content

Commit 76e5e3c

Browse files
committed
fix series refresh
1 parent f063284 commit 76e5e3c

5 files changed

Lines changed: 64 additions & 36 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ tower-http = { version = "0.5.0", features = ["cors","trace", "normalize-path",
2424
serde = { version = "1", features = ["derive"] }
2525
serde_json = "1"
2626
serde_with = "3"
27+
serde_path_to_error = "0.1"
2728
nanoid = "0.4.0"
2829
http-body-util = "0.1.0"
2930
hyper = { version = "1.0.0", features = ["full"] }

src/plugins/medias/trakt/mod.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use chrono::{DateTime, FixedOffset};
22
use http::{header::USER_AGENT, HeaderMap, HeaderValue};
3-
use reqwest::{Client, Url};
3+
use reqwest::{Client, Response, Url};
44
use rs_plugin_common_interfaces::{domain::rs_ids::{RsIds, RsIdsError}, lookup::RsLookupMovie};
5+
use serde::de::DeserializeOwned;
56
use tower::Service;
67
use trakt_people::{TraktActorsResult, TraktPeopleSearchElement, TraktPerson};
78
use crate::{domain::{episode::Episode, movie::Movie, people::Person, serie::Serie}, plugins::medias::trakt::{trakt_episode::TraktSeasonWithEpisodes, trakt_show::TraktFullShow}, tools::clock::{Clock, RsNaiveDate}, Error, Result};
@@ -10,6 +11,20 @@ use self::{trakt_episode::TraktFullEpisode, trakt_movie::{TraktFullMovie, TraktM
1011
// Context required for all requests
1112
use unidecode::unidecode;
1213

14+
/// Deserialize JSON response with detailed error path information
15+
async fn json_with_path<T: DeserializeOwned>(response: Response, context: &str) -> crate::Result<T> {
16+
let url = response.url().to_string();
17+
let bytes = response.bytes().await?;
18+
let jd = &mut serde_json::Deserializer::from_slice(&bytes);
19+
serde_path_to_error::deserialize(jd).map_err(|e| {
20+
let path = e.path().to_string();
21+
Error::Error(format!(
22+
"JSON parse error in {} at field '{}': {} (url: {})",
23+
context, path, e.inner(), url
24+
))
25+
})
26+
}
27+
1328
mod trakt_show;
1429
mod trakt_episode;
1530
mod trakt_movie;
@@ -70,7 +85,7 @@ impl TraktContext {
7085

7186
let url = self.base_url.join(&format!("shows/{}?extended=full", id)).unwrap();
7287
let r = self.client.get(url).header("trakt-api-key", &self.client_id).send().await?;
73-
let show = r.json::<TraktFullShow>().await?;
88+
let show: TraktFullShow = json_with_path(r, &format!("get_serie({})", id)).await?;
7489

7590
let show_nous: Serie = show.into();
7691
Ok(show_nous)
@@ -100,7 +115,8 @@ impl TraktContext {
100115
let url = self.base_url.join(&format!("shows/{}/seasons?extended=full,episodes", serie_id)).unwrap();
101116
let r = self.client.get(url).header("trakt-api-key", &self.client_id).send().await?;
102117
let best_serie_id = id.clone().into_best().unwrap_or(serie_id.to_owned());
103-
let episodes = r.json::<Vec<TraktSeasonWithEpisodes>>().await?.into_iter().flat_map(|s| s.episodes).map(|e| e.into_trakt(best_serie_id.clone())).collect::<Vec<_>>();
118+
let seasons: Vec<TraktSeasonWithEpisodes> = json_with_path(r, &format!("all_episodes({})", serie_id)).await?;
119+
let episodes = seasons.into_iter().flat_map(|s| s.episodes).map(|e| e.into_trakt(best_serie_id.clone())).collect::<Vec<_>>();
104120
Ok(episodes)
105121
}
106122

@@ -115,8 +131,8 @@ impl TraktContext {
115131
}?;
116132
let url = self.base_url.join(&format!("shows/{}/seasons/{}/episodes/{}?extended=full", id, season, episode)).unwrap();
117133
let r = self.client.get(url).header("trakt-api-key", &self.client_id).send().await?;
118-
let episodes = r.json::<TraktFullEpisode>().await?;
119-
Ok(episodes.into_trakt(format!("trakt:")))
134+
let ep: TraktFullEpisode = json_with_path(r, &format!("episode({} S{}E{})", id, season, episode)).await?;
135+
Ok(ep.into_trakt(format!("trakt:")))
120136
}
121137
}
122138

src/plugins/medias/trakt/trakt_episode.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
use crate::domain::episode::Episode;
12
use chrono::{DateTime, Utc};
23
use serde::{Deserialize, Serialize};
3-
use crate::domain::episode::Episode;
44

55
use super::trakt_show::TraktIds;
66

77
#[derive(Debug, Serialize, Deserialize)]
88
pub struct TraktSeasonWithEpisodes {
9-
pub episodes: Vec<TraktFullEpisode>
9+
pub episodes: Vec<TraktFullEpisode>,
1010
}
1111

1212
/// An [episode] with full [extended info]
@@ -21,13 +21,13 @@ pub struct TraktFullEpisode {
2121
pub ids: TraktIds,
2222
pub number_abs: Option<u32>,
2323
pub overview: Option<String>,
24-
pub rating: f32,
25-
pub votes: u32,
26-
pub comment_count: u32,
24+
pub rating: Option<f32>,
25+
pub votes: Option<u32>,
26+
pub comment_count: Option<u32>,
2727
pub first_aired: Option<DateTime<Utc>>,
2828
pub updated_at: Option<DateTime<Utc>>,
29-
pub available_translations: Vec<String>,
30-
pub runtime: u32,
29+
pub available_translations: Option<Vec<String>>,
30+
pub runtime: Option<u32>,
3131
}
3232

3333
impl TraktFullEpisode {
@@ -41,7 +41,7 @@ impl TraktFullEpisode {
4141
overview: self.overview,
4242
alt: None,
4343
airdate: self.first_aired.and_then(|t| Some(t.timestamp_millis())),
44-
duration: Some(self.runtime as u64),
44+
duration: self.runtime.map(|r| r as u64),
4545
params: None,
4646
imdb: self.ids.imdb,
4747
slug: self.ids.slug,
@@ -51,11 +51,10 @@ impl TraktFullEpisode {
5151
otherids: None,
5252
imdb_rating: None,
5353
imdb_votes: None,
54-
trakt_rating: Some(self.rating),
55-
trakt_votes: Some(self.votes.into()),
54+
trakt_rating: self.rating,
55+
trakt_votes: self.votes.map(|v| v.into()),
5656

57-
..Default::default()
57+
..Default::default()
5858
}
5959
}
6060
}
61-

src/plugins/medias/trakt/trakt_show.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::time::{SystemTime, UNIX_EPOCH};
22

3-
use rs_plugin_common_interfaces::domain::rs_ids::RsIds;
4-
use serde::{Serialize, Deserialize};
53
use chrono::{DateTime, Utc};
4+
use rs_plugin_common_interfaces::domain::rs_ids::RsIds;
5+
use serde::{Deserialize, Serialize};
66
use strum_macros::{Display, EnumString};
77

88
use crate::domain::serie::{Serie, SerieStatus};
@@ -23,8 +23,10 @@ pub enum TraktShowStatus {
2323
Released,
2424
Canceled,
2525
Pilot,
26-
#[strum(default)] Other(String),
27-
#[default] Unknown,
26+
#[strum(default)]
27+
Other(String),
28+
#[default]
29+
Unknown,
2830
}
2931

3032
impl From<TraktShowStatus> for SerieStatus {
@@ -78,14 +80,21 @@ pub struct TraktIds {
7880

7981
impl From<RsIds> for TraktIds {
8082
fn from(value: RsIds) -> Self {
81-
TraktIds { trakt: value.trakt, slug: value.slug, tvdb: value.tvdb, imdb: value.imdb, tmdb: value.tmdb, tvrage: value.tvrage }
83+
TraktIds {
84+
trakt: value.trakt,
85+
slug: value.slug,
86+
tvdb: value.tvdb,
87+
imdb: value.imdb,
88+
tmdb: value.tmdb,
89+
tvrage: value.tvrage,
90+
}
8291
}
8392
}
8493

8594
#[derive(Debug, Serialize, Deserialize)]
8695
pub struct TraktTrendingShowResult {
8796
pub watchers: u64,
88-
pub show: TraktFullShow
97+
pub show: TraktFullShow,
8998
}
9099

91100
/// A [show] with full [extended info]
@@ -99,27 +108,30 @@ pub struct TraktFullShow {
99108
pub ids: TraktIds,
100109
pub overview: Option<String>,
101110
pub first_aired: Option<DateTime<Utc>>,
102-
pub airs: Airing,
111+
pub airs: Option<Airing>,
103112
pub runtime: Option<u32>,
104113
pub certification: Option<String>,
105114
pub network: Option<String>,
106115
pub country: Option<String>,
107116
pub trailer: Option<String>,
108117
pub homepage: Option<String>,
109118
pub status: Option<TraktShowStatus>,
110-
pub rating: f64,
111-
pub votes: u32,
112-
pub comment_count: u32,
119+
pub rating: Option<f64>,
120+
pub votes: Option<u32>,
121+
pub comment_count: Option<u32>,
113122
pub updated_at: Option<DateTime<Utc>>,
114123
pub language: Option<String>,
115-
pub available_translations: Vec<String>,
116-
pub genres: Vec<String>,
117-
pub aired_episodes: u32,
124+
pub available_translations: Option<Vec<String>>,
125+
pub genres: Option<Vec<String>>,
126+
pub aired_episodes: Option<u32>,
118127
}
119128

120129
impl From<TraktFullShow> for Serie {
121130
fn from(value: TraktFullShow) -> Self {
122-
let t = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
131+
let t = SystemTime::now()
132+
.duration_since(UNIX_EPOCH)
133+
.unwrap()
134+
.as_millis() as u64;
123135
Serie {
124136
id: format!("trakt:{}", value.ids.trakt.unwrap()),
125137
name: value.title,
@@ -135,14 +147,14 @@ impl From<TraktFullShow> for Serie {
135147
otherids: None,
136148
imdb_rating: None,
137149
imdb_votes: None,
138-
trakt_votes: Some(value.votes as u64),
139-
trakt_rating: Some(value.rating as f32),
150+
trakt_votes: value.votes.map(|v| v as u64),
151+
trakt_rating: value.rating.map(|r| r as f32),
140152
trailer: value.trailer,
141153
year: value.year,
142154
max_created: None,
143155
modified: t,
144156
added: t,
145-
157+
146158
..Default::default()
147159
}
148160
}
@@ -151,6 +163,5 @@ impl From<TraktFullShow> for Serie {
151163
#[derive(Debug, Serialize, Deserialize)]
152164
pub struct TraktShowSearchElement {
153165
pub score: f64,
154-
pub show: TraktFullShow
166+
pub show: TraktFullShow,
155167
}
156-

0 commit comments

Comments
 (0)