aboutsummaryrefslogtreecommitdiff
path: root/import/src/trakt.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-20 22:40:03 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-20 22:40:03 +0100
commit0f74f013128f45a4f34761791203d88228a5eb52 (patch)
tree32826c46971e3d637b32f67630989a243d4dbb9d /import/src/trakt.rs
parent42f7a95ce67506344b694535ff193745452c6e29 (diff)
downloadjellything-0f74f013128f45a4f34761791203d88228a5eb52.tar
jellything-0f74f013128f45a4f34761791203d88228a5eb52.tar.bz2
jellything-0f74f013128f45a4f34761791203d88228a5eb52.tar.zst
implement trakt search api
Diffstat (limited to 'import/src/trakt.rs')
-rw-r--r--import/src/trakt.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/import/src/trakt.rs b/import/src/trakt.rs
new file mode 100644
index 0000000..e142eb6
--- /dev/null
+++ b/import/src/trakt.rs
@@ -0,0 +1,131 @@
+use reqwest::{
+ header::{HeaderMap, HeaderName, HeaderValue},
+ Client, ClientBuilder,
+};
+use serde::{Deserialize, Serialize};
+
+pub struct Trakt {
+ client: Client,
+}
+
+impl Trakt {
+ pub fn new(api_key: &str) -> Self {
+ let client = ClientBuilder::new()
+ .default_headers(HeaderMap::from_iter([
+ (
+ HeaderName::from_static("trakt-api-key"),
+ HeaderValue::from_str(api_key).unwrap(),
+ ),
+ (
+ HeaderName::from_static("trakt-api-version"),
+ HeaderValue::from_static("2"),
+ ),
+ (
+ HeaderName::from_static("content-type"),
+ HeaderValue::from_static("application/json"),
+ ),
+ ]))
+ .build()
+ .unwrap();
+ Self { client }
+ }
+
+ pub async fn search(
+ &self,
+ types: &[TraktKind],
+ query: &str,
+ extended: bool,
+ ) -> anyhow::Result<Vec<TraktSearchResult>> {
+ let res = self
+ .client
+ .get(format!(
+ "https://api.trakt.tv/search/{}?query={}{}",
+ types
+ .iter()
+ .map(|t| serde_json::to_string(t).unwrap())
+ .collect::<Vec<_>>()
+ .join(","),
+ urlencoding::encode(query),
+ optext(extended)
+ ))
+ .send()
+ .await?;
+ Ok(res.json().await?)
+ }
+}
+
+fn optext(extended: bool) -> &'static str {
+ if extended {
+ "&extended=full"
+ } else {
+ ""
+ }
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
+#[serde(rename_all = "snake_case")]
+pub enum TraktKind {
+ Movie,
+ Show,
+ Season,
+ Episode,
+ Person,
+ User,
+}
+
+impl TraktKind {
+ pub fn singular(self) -> &'static str {
+ match self {
+ TraktKind::Movie => "movie",
+ TraktKind::Show => "show",
+ TraktKind::Season => "season",
+ TraktKind::Episode => "episode",
+ TraktKind::Person => "person",
+ TraktKind::User => "user",
+ }
+ }
+ pub fn plural(self) -> &'static str {
+ match self {
+ TraktKind::Movie => "movies",
+ TraktKind::Show => "shows",
+ TraktKind::Season => "seasons",
+ TraktKind::Episode => "episodes",
+ TraktKind::Person => "people",
+ TraktKind::User => "user", // //! not used in API
+ }
+ }
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct TraktSearchResult {
+ r#type: TraktKind,
+ score: f64,
+ inner: TraktKindObject,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum TraktKindObject {
+ Movie(TraktMediaObject),
+ Show(TraktMediaObject),
+ Season(TraktMediaObject),
+ Episode(TraktMediaObject),
+ Person(TraktMediaObject),
+ User(TraktMediaObject),
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct TraktMediaObject {
+ title: String,
+ year: Option<u32>,
+ ids: TraktMediaObjectIds,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct TraktMediaObjectIds {
+ trakt: u64,
+ slug: String,
+
+ imdb: Option<String>,
+ tmdb: Option<u64>,
+}