1use serde::Deserialize;
2use time::Date;
3
4use crate::common::{
5 AccountStates, AlternativeTitles, Changes, ExternalIds, Images, Rated, StatusResponse,
6 Translations, Videos, WatchProviders,
7};
8use crate::endpoints::credit::Credits;
9use crate::endpoints::genre::Genre;
10use crate::endpoints::keyword::{Keyword, TvKeywords};
11use crate::endpoints::list::ListShort;
12use crate::endpoints::review::Review;
13use crate::{
14 Backdrop, CountryCode, GuestSessionId, Language, Logo, Page, Poster, Profile, SessionId, Still,
15};
16
17#[derive(Debug, Clone, Deserialize)]
18pub struct ContentRating {
19 #[serde(rename = "iso_3166_1")]
20 pub country: CountryCode,
21 pub rating: String,
22}
23
24#[derive(Debug, Clone, Deserialize)]
25pub struct ContentRatings {
26 pub results: Vec<ContentRating>,
27}
28
29#[derive(Debug, Clone, Deserialize)]
31pub struct SeasonShort {
32 pub season_number: u32,
33 pub name: String,
34 pub episode_count: u32,
35 pub overview: Option<String>,
36 #[serde(rename = "poster_path")]
37 pub poster: Option<Poster>,
38 #[serde(default, deserialize_with = "crate::common::opt_date")]
39 pub air_date: Option<Date>,
40}
41
42use crate::append::appendable;
43
44#[derive(Debug, Clone, Deserialize)]
46pub struct TvShort {
47 pub id: u64,
48 pub name: String,
49 pub original_name: String,
50 pub overview: String,
51 #[serde(
52 rename = "first_air_date",
53 default,
54 deserialize_with = "crate::common::opt_date"
55 )]
56 pub release_date: Option<Date>,
57 #[serde(rename = "poster_path")]
58 pub poster: Option<Poster>,
59 #[serde(rename = "backdrop_path")]
60 pub backdrop: Option<Backdrop>,
61 pub vote_average: f64,
62 pub vote_count: u32,
63 pub popularity: f64,
64 #[serde(default)]
65 pub genre_ids: Vec<u64>,
66 #[serde(default, deserialize_with = "crate::common::opt_language")]
67 pub original_language: Option<Language>,
68 #[serde(default)]
69 pub origin_country: Vec<String>,
70 pub adult: bool,
71}
72
73#[derive(Debug, Clone, Deserialize)]
75pub struct NextEpisode {
76 pub id: u64,
77 pub name: String,
78 pub episode_number: u32,
79 pub season_number: u32,
80 #[serde(default, deserialize_with = "crate::common::opt_date")]
81 pub air_date: Option<Date>,
82}
83
84#[derive(Debug, Clone, Deserialize)]
86pub struct Episode {
87 pub id: u64,
88 pub name: String,
89 pub overview: String,
90 pub episode_number: u32,
91 pub season_number: u32,
92 pub runtime: Option<u32>,
93 #[serde(rename = "still_path")]
94 pub still: Option<Still>,
95 #[serde(default, deserialize_with = "crate::common::opt_date")]
96 pub air_date: Option<Date>,
97 pub vote_average: f64,
98 pub vote_count: u32,
99}
100
101#[derive(Debug, Clone, Deserialize)]
103pub struct Role {
104 pub credit_id: String,
105 pub character: String,
106 pub episode_count: u32,
107}
108
109#[derive(Debug, Clone, Deserialize)]
110pub struct AggregateCastMember {
111 pub id: u64,
112 pub name: String,
113 #[serde(rename = "profile_path")]
114 pub profile: Option<Profile>,
115 pub roles: Vec<Role>,
116 pub total_episode_count: u32,
117 pub order: Option<u32>,
118}
119
120#[derive(Debug, Clone, Deserialize)]
122pub struct Job {
123 pub credit_id: String,
124 pub job: String,
125 pub episode_count: u32,
126}
127
128#[derive(Debug, Clone, Deserialize)]
129pub struct AggregateCrewMember {
130 pub id: u64,
131 pub name: String,
132 #[serde(rename = "profile_path")]
133 pub profile: Option<Profile>,
134 pub jobs: Vec<Job>,
135 pub total_episode_count: u32,
136 pub department: String,
137}
138
139#[derive(Debug, Clone, Deserialize)]
141pub struct AggregateCredits {
142 pub cast: Vec<AggregateCastMember>,
143 pub crew: Vec<AggregateCrewMember>,
144}
145
146#[derive(Debug, Clone, Deserialize)]
148pub struct NetworkShort {
149 pub id: u64,
150 pub name: String,
151 #[serde(rename = "logo_path")]
152 pub logo: Option<Logo>,
153 pub origin_country: Option<String>,
154}
155
156#[derive(Debug, Clone, Deserialize)]
157pub struct EpisodeGroupShort {
158 pub id: String,
159 pub name: String,
160 pub description: String,
161 pub episode_count: u32,
162 pub group_count: u32,
163 #[serde(rename = "type")]
164 pub kind: u32,
165 pub network: Option<NetworkShort>,
166}
167
168#[derive(Debug, Clone, Deserialize)]
169pub struct EpisodeGroups {
170 pub results: Vec<EpisodeGroupShort>,
171}
172
173#[derive(Debug, Clone, Deserialize)]
175pub struct EpisodeGroupEntry {
176 pub id: String,
177 pub name: String,
178 pub order: u32,
179 #[serde(default)]
180 pub episodes: Vec<Episode>,
181}
182
183#[derive(Debug, Clone, Deserialize)]
184pub struct EpisodeGroup {
185 pub id: String,
186 pub name: String,
187 pub description: String,
188 pub episode_count: u32,
189 pub group_count: u32,
190 #[serde(rename = "type")]
191 pub kind: u32,
192 pub network: Option<NetworkShort>,
193 pub groups: Vec<EpisodeGroupEntry>,
194}
195
196#[derive(Debug, Clone, Deserialize)]
198pub struct ScreenedEntry {
199 pub id: u64,
200 pub episode_number: u32,
201 pub season_number: u32,
202}
203
204#[derive(Debug, Clone, Deserialize)]
205pub struct ScreenedTheatrically {
206 pub results: Vec<ScreenedEntry>,
207}
208
209appendable! {
210 AggregateCredits,
211 ContentRatings,
212 EpisodeGroups,
213 ScreenedTheatrically,
214}
215
216endpoint! {
217 tv(id: u64): GET "/tv/{id}" => TvDetails {
219 params { language: Language }
220 base {
221 pub id: u64,
222 pub name: String,
223 pub original_name: String,
224 pub overview: String,
225 pub tagline: String,
226 #[serde(
227 rename = "first_air_date",
228 default,
229 deserialize_with = "crate::common::opt_date"
230 )]
231 pub release_date: Option<Date>,
232 #[serde(default, deserialize_with = "crate::common::opt_date")]
233 pub last_air_date: Option<Date>,
234 pub vote_average: f64,
235 pub vote_count: u32,
236 pub popularity: f64,
237 pub number_of_seasons: u32,
238 pub number_of_episodes: u32,
239 pub episode_run_time: Vec<u32>,
240 #[serde(default, deserialize_with = "crate::common::opt_language")]
241 pub original_language: Option<Language>,
242 #[serde(rename = "poster_path")]
243 pub poster: Option<Poster>,
244 #[serde(rename = "backdrop_path")]
245 pub backdrop: Option<Backdrop>,
246 pub genres: Vec<Genre>,
247 #[serde(rename = "homepage")]
248 pub website: String,
249 pub status: String,
250 pub in_production: bool,
251 #[serde(default, deserialize_with = "crate::common::language_list")]
252 pub languages: Vec<Language>,
253 #[serde(default)]
254 pub origin_country: Vec<String>,
255 #[serde(default)]
256 pub seasons: Vec<SeasonShort>,
257 pub next_episode_to_air: Option<NextEpisode>,
258 pub adult: bool,
259 }
260 appends {
261 account_states: AccountStates,
262 aggregate_credits: AggregateCredits,
263 alternative_titles: AlternativeTitles,
264 changes: Changes,
265 content_ratings: ContentRatings,
266 credits: Credits,
267 episode_groups: EpisodeGroups,
268 external_ids: ExternalIds,
269 images: Images,
270 keywords: TvKeywords,
271 lists: Page<ListShort>,
272 recommendations: Page<TvShort>,
273 reviews: Page<Review>,
274 similar: Page<TvShort>,
275 translations: Translations,
276 videos: Videos,
277 watch_providers: WatchProviders as "watch/providers",
278 }
279 }
280}
281
282endpoint! {
283 tv_season(id: u64, season: u32): GET "/tv/{id}/season/{season}" => SeasonDetails {
285 params { language: Language }
286 base {
287 pub id: u64,
288 pub season_number: u32,
289 pub name: String,
290 pub overview: String,
291 #[serde(default, deserialize_with = "crate::common::opt_date")]
292 pub air_date: Option<Date>,
293 #[serde(rename = "poster_path")]
294 pub poster: Option<Poster>,
295 #[serde(default)]
296 pub episodes: Vec<Episode>,
297 }
298 appends {
299 account_states: AccountStates,
300 aggregate_credits: AggregateCredits,
301 changes: Changes,
302 credits: Credits,
303 external_ids: ExternalIds,
304 images: Images,
305 translations: Translations,
306 videos: Videos,
307 watch_providers: WatchProviders as "watch/providers",
308 }
309 }
310}
311
312endpoint! {
313 tv_episode(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}" => EpisodeDetails {
315 params { language: Language }
316 base {
317 pub id: u64,
318 pub name: String,
319 pub overview: String,
320 pub episode_number: u32,
321 pub season_number: u32,
322 pub runtime: Option<u32>,
323 #[serde(rename = "still_path")]
324 pub still: Option<Still>,
325 #[serde(default, deserialize_with = "crate::common::opt_date")]
326 pub air_date: Option<Date>,
327 pub vote_average: f64,
328 pub vote_count: u32,
329 }
330 appends {
331 account_states: AccountStates,
332 changes: Changes,
333 credits: Credits,
334 external_ids: ExternalIds,
335 images: Images,
336 translations: Translations,
337 videos: Videos,
338 }
339 }
340}
341
342endpoint! {
343 tv_latest(): GET "/tv/latest" => TvDetails {
345 params { language: Language }
346 }
347}
348
349endpoint! {
350 tv_popular(): GET "/tv/popular" => Page<TvShort> {
352 params { language: Language, page: u32 }
353 }
354}
355
356endpoint! {
357 tv_top_rated(): GET "/tv/top_rated" => Page<TvShort> {
359 params { language: Language, page: u32 }
360 }
361}
362
363endpoint! {
364 tv_on_the_air(): GET "/tv/on_the_air" => Page<TvShort> {
366 params { language: Language, page: u32 }
367 }
368}
369
370endpoint! {
371 tv_airing_today(): GET "/tv/airing_today" => Page<TvShort> {
373 params { language: Language, page: u32 }
374 }
375}
376
377endpoint! {
378 tv_keywords(id: u64): GET "/tv/{id}/keywords" => Vec<Keyword> [results]
380}
381
382endpoint! {
383 tv_external_ids(id: u64): GET "/tv/{id}/external_ids" => ExternalIds
385}
386
387endpoint! {
388 tv_account_states(id: u64): GET "/tv/{id}/account_states" => AccountStates {
390 params { session_id: SessionId, guest_session_id: GuestSessionId }
391 }
392}
393
394endpoint! {
395 tv_aggregate_credits(id: u64): GET "/tv/{id}/aggregate_credits" => AggregateCredits {
397 params { language: Language }
398 }
399}
400
401endpoint! {
402 tv_alternative_titles(id: u64): GET "/tv/{id}/alternative_titles" => AlternativeTitles
404}
405
406endpoint! {
407 tv_changes_by_id(id: u64): GET "/tv/{id}/changes" => Changes {
409 params { start_date: Date, end_date: Date, page: u32 }
410 }
411}
412
413endpoint! {
414 tv_content_ratings(id: u64): GET "/tv/{id}/content_ratings" => ContentRatings
416}
417
418endpoint! {
419 tv_credits(id: u64): GET "/tv/{id}/credits" => Credits {
421 params { language: Language }
422 }
423}
424
425endpoint! {
426 tv_episode_groups(id: u64): GET "/tv/{id}/episode_groups" => EpisodeGroups
428}
429
430endpoint! {
431 tv_images(id: u64): GET "/tv/{id}/images" => Images {
433 params { language: Language, include_image_language: Vec<Language> }
434 }
435}
436
437endpoint! {
438 tv_lists(id: u64): GET "/tv/{id}/lists" => Page<ListShort> {
440 params { language: Language, page: u32 }
441 }
442}
443
444endpoint! {
445 tv_similar(id: u64): GET "/tv/{id}/similar" => Page<TvShort> {
447 params { language: Language, page: u32 }
448 }
449}
450
451endpoint! {
452 tv_recommendations(id: u64): GET "/tv/{id}/recommendations" => Page<TvShort> {
454 params { language: Language, page: u32 }
455 }
456}
457
458endpoint! {
459 tv_reviews(id: u64): GET "/tv/{id}/reviews" => Page<Review> {
461 params { language: Language, page: u32 }
462 }
463}
464
465endpoint! {
466 tv_screened_theatrically(id: u64): GET "/tv/{id}/screened_theatrically" => ScreenedTheatrically
468}
469
470endpoint! {
471 tv_translations(id: u64): GET "/tv/{id}/translations" => Translations
473}
474
475endpoint! {
476 tv_videos(id: u64): GET "/tv/{id}/videos" => Videos {
478 params { language: Language, include_image_language: Vec<Language> }
479 }
480}
481
482endpoint! {
483 tv_watch_providers(id: u64): GET "/tv/{id}/watch/providers" => WatchProviders
485}
486
487endpoint! {
488 rate_tv(id: u64): POST "/tv/{id}/rating" => StatusResponse {
490 params { session_id: SessionId, guest_session_id: GuestSessionId }
491 body { value: f64 }
492 }
493}
494
495endpoint! {
496 unrate_tv(id: u64): DELETE "/tv/{id}/rating" => StatusResponse {
498 params { session_id: SessionId, guest_session_id: GuestSessionId }
499 }
500}
501
502endpoint! {
503 tv_season_account_states(id: u64, season: u32): GET "/tv/{id}/season/{season}/account_states" => Vec<EpisodeAccountState> [results] {
505 params { session_id: SessionId, guest_session_id: GuestSessionId }
506 }
507}
508
509#[derive(Debug, Clone, Deserialize)]
510pub struct EpisodeAccountState {
511 pub id: u64,
512 pub episode_number: u32,
513 pub rated: Rated,
514}
515
516endpoint! {
517 tv_season_aggregate_credits(id: u64, season: u32): GET "/tv/{id}/season/{season}/aggregate_credits" => AggregateCredits {
519 params { language: Language }
520 }
521}
522
523endpoint! {
524 tv_season_changes(id: u64): GET "/tv/season/{id}/changes" => Changes {
526 params { start_date: Date, end_date: Date, page: u32 }
527 }
528}
529
530endpoint! {
531 tv_season_credits(id: u64, season: u32): GET "/tv/{id}/season/{season}/credits" => Credits {
533 params { language: Language }
534 }
535}
536
537endpoint! {
538 tv_season_external_ids(id: u64, season: u32): GET "/tv/{id}/season/{season}/external_ids" => ExternalIds
540}
541
542endpoint! {
543 tv_season_images(id: u64, season: u32): GET "/tv/{id}/season/{season}/images" => Images {
545 params { language: Language, include_image_language: Vec<Language> }
546 }
547}
548
549endpoint! {
550 tv_season_translations(id: u64, season: u32): GET "/tv/{id}/season/{season}/translations" => Translations
552}
553
554endpoint! {
555 tv_season_videos(id: u64, season: u32): GET "/tv/{id}/season/{season}/videos" => Videos {
557 params { language: Language, include_image_language: Vec<Language> }
558 }
559}
560
561endpoint! {
562 tv_season_watch_providers(id: u64, season: u32): GET "/tv/{id}/season/{season}/watch/providers" => WatchProviders
564}
565
566endpoint! {
567 tv_episode_account_states(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/account_states" => EpisodeAccountStates {
569 params { session_id: SessionId, guest_session_id: GuestSessionId }
570 }
571}
572
573#[derive(Debug, Clone, Deserialize)]
575pub struct EpisodeAccountStates {
576 pub id: u64,
577 pub rated: Rated,
578}
579
580endpoint! {
581 tv_episode_changes(id: u64): GET "/tv/episode/{id}/changes" => Changes {
583 params { start_date: Date, end_date: Date, page: u32 }
584 }
585}
586
587endpoint! {
588 tv_episode_credits(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/credits" => Credits {
590 params { language: Language }
591 }
592}
593
594endpoint! {
595 tv_episode_external_ids(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/external_ids" => ExternalIds
597}
598
599endpoint! {
600 tv_episode_images(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/images" => Images {
602 params { language: Language, include_image_language: Vec<Language> }
603 }
604}
605
606endpoint! {
607 tv_episode_translations(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/translations" => Translations
609}
610
611endpoint! {
612 tv_episode_videos(id: u64, season: u32, episode: u32): GET "/tv/{id}/season/{season}/episode/{episode}/videos" => Videos {
614 params { language: Language, include_image_language: Vec<Language> }
615 }
616}
617
618endpoint! {
619 rate_tv_episode(id: u64, season: u32, episode: u32): POST "/tv/{id}/season/{season}/episode/{episode}/rating" => StatusResponse {
621 params { session_id: SessionId, guest_session_id: GuestSessionId }
622 body { value: f64 }
623 }
624}
625
626endpoint! {
627 unrate_tv_episode(id: u64, season: u32, episode: u32): DELETE "/tv/{id}/season/{season}/episode/{episode}/rating" => StatusResponse {
629 params { session_id: SessionId, guest_session_id: GuestSessionId }
630 }
631}
632
633endpoint! {
634 tv_episode_group(id: &str): GET "/tv/episode_group/{id}" => EpisodeGroup {
636 params { language: Language }
637 }
638}