r621/src/client.rs

73 lines
2.3 KiB
Rust

use std::io::Write;
use anyhow::Result;
use base64::Engine;
use base64::engine::{GeneralPurpose};
use crate::post::{Post, Posts};
use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue, USER_AGENT};
#[derive(Clone, Debug)]
pub struct Client<'a> {
auth: Authentication<'a>,
useragent: &'a str,
host: &'static str,
http_client: reqwest::Client
}
impl<'a> Client<'a> {
pub fn new(auth: Authentication<'a>, useragent: &'a str) -> Result<Self> {
let mut header_map = HeaderMap::new();
header_map.append(USER_AGENT, HeaderValue::from_str(useragent)?);
if let Authentication::Authorized { username, apikey } = auth {
let authorization = Self::get_authorization_value(username, apikey);
header_map.append(AUTHORIZATION, HeaderValue::from_str(&authorization)?);
}
let http_client = reqwest::Client::builder()
.default_headers(header_map)
.build()?;
Ok(Client {
auth,
useragent,
host: "https://e621.net",
http_client
})
}
fn get_authorization_value(username: &'a str, apikey: &'a str) -> String {
let base64_engine = GeneralPurpose::new(&base64::alphabet::STANDARD, Default::default());
base64_engine.encode(format!("{username}:{apikey}"))
}
pub async fn list_posts(&mut self, limit: Option<u16>, tags: Option<Vec<String>>, page: Option<u32>) -> Result<Vec<Post>> {
let mut url = url::Url::parse(format!("{}/posts.json", self.host).as_str())?;
let limit = limit.unwrap_or(320);
let page = page.unwrap_or(0);
let mut query_params = String::new();
query_params.push_str("limit=");
query_params.push_str(limit.to_string().as_str());
query_params.push_str("page=");
query_params.push_str(page.to_string().as_str());
if let Some(tags) = tags {
if tags.len() > 0 {
query_params.push_str("tags=");
query_params.push_str(tags.join(",").as_str());
}
}
Ok(self.http_client.get(url.as_str())
.send()
.await?
.json::<Posts>()
.await?.into())
}
}
#[derive(Clone, Copy, Debug)]
pub enum Authentication<'a> {
Authorized {username: &'a str, apikey: &'a str},
Unauthorized
}