use super::{Client, ClientBuilder};
use crate::error::{BooruError, Result};
use crate::model::gelbooru::*;
#[derive(Debug)]
pub struct GelbooruClient(ClientBuilder<Self>);
impl From<ClientBuilder<Self>> for GelbooruClient {
fn from(value: ClientBuilder<Self>) -> Self {
Self(value)
}
}
impl Client for GelbooruClient {
type Post = GelbooruPost;
type Rating = GelbooruRating;
const URL: &'static str = "https://gelbooru.com";
const SORT: &'static str = "sort:";
const MAX_TAGS: Option<usize> = None;
async fn get_by_id(&self, id: u32) -> Result<Self::Post> {
let builder = &self.0;
let url = &builder.url;
let mut query = vec![
("page", "dapi".to_string()),
("s", "post".to_string()),
("q", "index".to_string()),
("id", id.to_string()),
("json", "1".to_string()),
];
if let (Some(key), Some(user)) = (&builder.key, &builder.user) {
query.push(("api_key", key.clone()));
query.push(("user_id", user.clone()));
}
let response = builder
.client
.get(format!("{url}/index.php"))
.query(&query)
.send()
.await?;
if response.status() == reqwest::StatusCode::UNAUTHORIZED {
return Err(BooruError::Unauthorized(
"Gelbooru requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
let data = response.json::<GelbooruResponse>().await?;
data.posts
.into_iter()
.next()
.ok_or(BooruError::PostNotFound(id))
}
async fn get(&self) -> Result<Vec<Self::Post>> {
let builder = &self.0;
let url = &builder.url;
let tag_string = builder.tags.join(" ");
let mut query = vec![
("page", "dapi".to_string()),
("s", "post".to_string()),
("q", "index".to_string()),
("pid", builder.page.to_string()),
("limit", builder.limit.to_string()),
("tags", tag_string),
("json", "1".to_string()),
];
if let (Some(key), Some(user)) = (&builder.key, &builder.user) {
query.push(("api_key", key.clone()));
query.push(("user_id", user.clone()));
}
let response = builder
.client
.get(format!("{url}/index.php"))
.query(&query)
.send()
.await?;
if response.status() == reqwest::StatusCode::UNAUTHORIZED {
return Err(BooruError::Unauthorized(
"Gelbooru requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
let data = response.json::<GelbooruResponse>().await?;
Ok(data.posts)
}
}