use std::sync::OnceLock;
use fyyd_types::v2::fyyd_response::{FyydPodcast, FyydResponse};
use reqwest::{Client, ClientBuilder};
const FYYD_API_V2: &str = "https://api.fyyd.de/0.2";
const PODCAST: &str = "/podcast";
const EPISODES: &str = "/episodes";
const _PODCAST_LATEST: &str = "/podcast/latest";
const SEARCH_PODCAST: &str = "/search/podcast";
static HTTP_CLIENT: OnceLock<Client> = OnceLock::new();
fn get_http_client(client_builder: Option<ClientBuilder>) -> &'static Client {
HTTP_CLIENT.get_or_init(|| {
let builder = client_builder.unwrap_or_else(ClientBuilder::new);
builder.build().unwrap()
})
}
pub struct FyydClient {
client: Client,
}
impl FyydClient {
pub fn new(client_builder: Option<ClientBuilder>) -> Self {
let client = get_http_client(client_builder).clone();
FyydClient { client }
}
pub async fn search_podcast_feed(
&self,
title: Option<String>,
url: Option<String>,
term: Option<String>,
page: Option<u16>,
) -> Result<FyydResponse<Vec<FyydPodcast>>, Box<dyn std::error::Error>> {
let path = FYYD_API_V2.to_owned() + SEARCH_PODCAST;
let request = self
.client
.get(path)
.query(&[("title", title.unwrap_or_default().as_str())])
.query(&[("url", url.unwrap_or_default().as_str())])
.query(&[("term", term.unwrap_or_default().as_str())])
.query(&[("page", page.unwrap_or_default())]);
let response = request.send().await?;
let body = response.bytes().await?.to_vec();
let fyyd_response: FyydResponse<Vec<FyydPodcast>> = serde_json::from_slice(&body)?;
Ok(fyyd_response)
}
pub async fn get_episodes_from_id(
&self,
id: u64,
slug: Option<String>,
count: Option<u16>,
page: Option<u16>,
_episodes: bool,
) -> Result<FyydResponse<FyydPodcast>, Box<dyn std::error::Error>> {
let path = FYYD_API_V2.to_owned() + PODCAST + EPISODES;
let request = self
.client
.get(path)
.query(&[("podcast_id", id)])
.query(&[("podcast_slug", slug.unwrap_or_default().as_str())])
.query(&[("page", page.unwrap_or_default())])
.query(&[("count", count.unwrap_or(50))]);
let response = request.send().await?;
let body = response.bytes().await?.to_vec();
let fyyd_response: FyydResponse<FyydPodcast> = serde_json::from_slice(&body)?;
Ok(fyyd_response)
}
pub(crate) async fn _get_latest_episodes_from_id(
&self,
since_id: Option<u64>,
count: Option<u16>,
) -> Result<FyydResponse<FyydPodcast>, Box<dyn std::error::Error>> {
let path = FYYD_API_V2.to_owned() + _PODCAST_LATEST;
let request = self
.client
.get(path)
.query(&[("since_id", since_id)])
.query(&[("count", count.unwrap_or(20))]);
let response = request.send().await?;
let body = response.bytes().await?.to_vec();
let fyyd_response: FyydResponse<FyydPodcast> = serde_json::from_slice(&body)?;
Ok(fyyd_response)
}
}