/* 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. Copyright (C) 2023 metamuffin */ use anyhow::Context; use bincode::{Decode, Encode}; use jellycommon::chrono::{format::Parsed, Utc}; use log::info; use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct TmdbQuery { pub page: usize, pub results: Vec, pub total_pages: usize, pub total_results: usize, } #[derive(Debug, Clone, Deserialize, Encode, Decode)] pub struct TmdbQueryResult { pub adult: bool, pub backdrop_path: Option, pub genre_ids: Vec, pub id: u64, pub original_language: Option, pub original_title: Option, pub overview: String, pub popularity: f64, pub poster_path: Option, pub release_date: Option, pub title: Option, pub name: Option, pub vote_average: f64, pub vote_count: usize, } #[derive(Debug, Clone, Deserialize, Encode, Decode)] pub struct TmdbDetails { pub adult: bool, pub backdrop_path: Option, pub genres: Vec, pub id: u64, pub original_language: Option, pub original_title: Option, pub overview: String, pub popularity: f64, pub poster_path: Option, pub release_date: Option, pub title: Option, pub name: Option, pub vote_average: f64, pub vote_count: usize, pub budget: Option, pub homepage: Option, pub imdb_id: Option, pub production_companies: Vec, pub revenue: Option, pub tagline: Option, } #[derive(Debug, Clone, Deserialize, Encode, Decode)] pub struct TmdbGenre { pub id: u64, pub name: String, } #[derive(Debug, Clone, Deserialize, Encode, Decode)] pub struct TmdbProductionCompany { pub id: u64, pub name: String, pub logo_path: Option, } #[derive(Debug, Clone, Copy)] pub enum TmdbKind { Tv, Movie, } impl TmdbKind { pub fn as_str(&self) -> &'static str { match self { TmdbKind::Tv => "tv", TmdbKind::Movie => "movie", } } } pub async fn tmdb_search(kind: TmdbKind, query: &str, key: &str) -> anyhow::Result { info!("searching tmdb: {query:?}"); Ok(reqwest::get(&format!( "https://api.themoviedb.org/3/search/{}?query={}&api_key={key}", kind.as_str(), query.replace(" ", "+") )) .await? .json::() .await?) } pub async fn tmdb_details(kind: TmdbKind, id: u64, key: &str) -> anyhow::Result { info!("fetching details: {id:?}"); Ok(reqwest::get(&format!( "https://api.themoviedb.org/3/{}/{id}?api_key={key}", kind.as_str() )) .await? .json() .await?) } pub async fn tmdb_image(path: &str) -> anyhow::Result> { info!("downloading image {path:?}"); let res = reqwest::get(&format!("https://image.tmdb.org/t/p/original{path}")).await?; Ok(res.bytes().await?.to_vec()) } pub fn parse_release_date(d: &str) -> anyhow::Result { let (year, month, day) = (&d[0..4], &d[5..7], &d[8..10]); let (year, month, day) = ( year.parse().context("parsing year")?, month.parse().context("parsing month")?, day.parse().context("parsing day")?, ); let mut p = Parsed::new(); p.year = Some(year); p.month = Some(month); p.day = Some(day); p.hour_div_12 = Some(0); p.hour_mod_12 = Some(0); p.minute = Some(0); p.second = Some(0); Ok(p.to_datetime_with_timezone(&Utc)?.timestamp_millis()) }