aboutsummaryrefslogtreecommitdiff
path: root/import/src/trakt.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-05 23:10:15 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-05 23:10:15 +0100
commitdf36a85b54fd427cc0914320d29aa4f005e5aff7 (patch)
tree0702e87d55fe1a7b4d6913a35759e343f9923389 /import/src/trakt.rs
parentfea9d99cef52a8ba258f5c8a11af08ec3304613e (diff)
downloadjellything-df36a85b54fd427cc0914320d29aa4f005e5aff7.tar
jellything-df36a85b54fd427cc0914320d29aa4f005e5aff7.tar.bz2
jellything-df36a85b54fd427cc0914320d29aa4f005e5aff7.tar.zst
trakt episode details
Diffstat (limited to 'import/src/trakt.rs')
-rw-r--r--import/src/trakt.rs127
1 files changed, 76 insertions, 51 deletions
diff --git a/import/src/trakt.rs b/import/src/trakt.rs
index c7a25ad..1daee77 100644
--- a/import/src/trakt.rs
+++ b/import/src/trakt.rs
@@ -1,3 +1,4 @@
+use anyhow::Context;
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
@@ -46,76 +47,115 @@ impl Trakt {
&self,
kinds: &[TraktKind],
query: &str,
- extended: bool,
) -> anyhow::Result<Arc<Vec<TraktSearchResult>>> {
+ async_cache_memory(&["api-trakt-lookup", query], || async move {
+ let url = format!(
+ "https://api.trakt.tv/search/{}?query={}&extended=full",
+ kinds
+ .iter()
+ .map(|t| t.singular())
+ .collect::<Vec<_>>()
+ .join(","),
+ urlencoding::encode(query),
+ );
+ let res = self.client.get(url).send().await?.error_for_status()?;
+ Ok(res.json().await?)
+ })
+ .await
+ .context("trakt search")
+ }
+
+ pub async fn lookup(&self, kind: TraktKind, id: u64) -> anyhow::Result<Arc<TraktMediaObject>> {
async_cache_memory(
- &["api-trakt-lookup", query, if extended { "a" } else { "b" }],
+ &["api-trakt-lookup", &format!("{kind} {id}")],
|| async move {
- let url = format!(
- "https://api.trakt.tv/search/{}?query={}{}",
- kinds
- .iter()
- .map(|t| t.singular())
- .collect::<Vec<_>>()
- .join(","),
- urlencoding::encode(query),
- optext(extended)
- );
+ info!("trakt lookup {kind:?}:{id:?}");
+ let url = format!("https://api.trakt.tv/{}/{id}?extended=full", kind.plural());
let res = self.client.get(url).send().await?.error_for_status()?;
Ok(res.json().await?)
},
)
.await
+ .context("trakt lookup")
}
- pub async fn lookup(
- &self,
- kind: TraktKind,
- id: u64,
- extended: bool,
- ) -> anyhow::Result<Arc<TraktMediaObject>> {
+ pub async fn people(&self, kind: TraktKind, id: u64) -> anyhow::Result<Arc<TraktPeople>> {
async_cache_memory(
- &["api-trakt-lookup", &format!("{id} {extended}")],
+ &["api-trakt-people", &format!("{kind} {id}")],
|| async move {
- info!("trakt lookup {kind:?}:{id:?}");
+ info!("trakt people {kind:?}:{id:?}");
let url = format!(
- "https://api.trakt.tv/{}/{}{}",
- kind.plural(),
- id,
- optext2(extended)
+ "https://api.trakt.tv/{}/{id}/people?extended=full",
+ kind.plural()
);
let res = self.client.get(url).send().await?.error_for_status()?;
Ok(res.json().await?)
},
)
.await
+ .context("trakt people")
+ }
+
+ pub async fn show_seasons(&self, id: u64) -> anyhow::Result<Arc<Vec<TraktSeason>>> {
+ async_cache_memory(&["api-trakt-seasons", &id.to_string()], || async move {
+ info!("trakt seasons {id:?}");
+ let url = format!("https://api.trakt.tv/shows/{id}/seasons?extended=full");
+ let res = self.client.get(url).send().await?.error_for_status()?;
+ Ok(res.json().await?)
+ })
+ .await
+ .context("trakt show seasons")
}
- pub async fn people(
+ pub async fn show_season_episodes(
&self,
- kind: TraktKind,
id: u64,
- extended: bool,
- ) -> anyhow::Result<Arc<TraktPeople>> {
+ season: usize,
+ ) -> anyhow::Result<Arc<Vec<TraktEpisode>>> {
async_cache_memory(
- &["api-trakt-people", &format!("{id} {extended}")],
+ &["api-trakt-episodes", &id.to_string(), &season.to_string()],
|| async move {
- info!("trakt people {kind:?}:{id:?}");
- let url = format!(
- "https://api.trakt.tv/{}/{}/people{}",
- kind.plural(),
- id,
- optext2(extended)
- );
+ info!("trakt episodes {id:?} season={season}");
+ let url = format!("https://api.trakt.tv/shows/{id}/seasons/{season}?extended=full");
let res = self.client.get(url).send().await?.error_for_status()?;
Ok(res.json().await?)
},
)
.await
+ .context("trakt show season episodes")
}
}
#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+pub struct TraktSeason {
+ pub number: usize,
+ pub ids: ObjectIds,
+ pub rating: f64,
+ pub votes: usize,
+ pub episode_count: usize,
+ pub aired_count: Option<usize>,
+ pub title: String,
+ pub overview: Option<String>,
+ pub network: String,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+pub struct TraktEpisode {
+ pub season: Option<usize>,
+ pub number: usize,
+ pub number_abs: Option<usize>,
+ pub ids: ObjectIds,
+ pub rating: f64,
+ pub votes: usize,
+ pub title: String,
+ pub runtime: f64,
+ pub overview: Option<String>,
+ pub available_translations: Vec<String>,
+ pub first_aired: Option<String>,
+ pub episode_type: String,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
pub struct TraktPeople {
#[serde(default)]
pub cast: Vec<TraktAppearance>,
@@ -138,21 +178,6 @@ pub struct TraktPerson {
pub ids: ObjectIds,
}
-fn optext(extended: bool) -> &'static str {
- if extended {
- "&extended=full"
- } else {
- ""
- }
-}
-fn optext2(extended: bool) -> &'static str {
- if extended {
- "?extended=full"
- } else {
- ""
- }
-}
-
#[derive(Debug, Serialize, Deserialize, Encode, Decode)]
pub struct TraktSearchResult {
pub r#type: TraktKind,