use actix_web::{self, get, web, App, HttpResponse, HttpServer, Responder};
use rand::seq::SliceRandom;
use reqwest;
use serde::Deserialize;
#[derive(Deserialize)]
struct RandomArgs {
/// e.g. 2560x1440
atleast: String,
/// e.g. 16x9
/// e.g. 16x9
/// or 16x9,16x10 for both, etc
ratios: String,
/// purity
/// 100 sfw
/// 010 sketchy
/// 001 nsfw
/// can combine
/// e.g. 111 for all
purity: String,
/// categories
/// 100 general
/// 010 anime
/// 001 people
/// can combine
/// e.g. 101 for no anime
categories: String,
/// query
/// can be kinda anything
/// check https://wallhaven.cc/help/api#search
/// for shid
q: String,
}
#[derive(Deserialize)]
struct WHImgInfo {
pub path: String,
}
#[derive(Deserialize)]
struct WHSearchRes {
pub data: Vec<WHImgInfo>,
}
/// get redirected to random img
/// e.g. localhost:3000/random/2560x1440/16x9/100/001/+forest
#[get("/random/{atleast}/{ratios}/{purity}/{categories}/{q}")]
async fn random(args: web::Path<RandomArgs>) -> impl Responder {
let atl = args.atleast.clone();
let rats = args.ratios.clone();
let pur = args.purity.clone();
let cats = args.categories.clone();
let q = args.q.clone();
let api_key = env!("WH_API_KEY");
let wh_url = format!(
"https://wallhaven.cc/api/v1/search?atleast={atl}&ratios={rats}&purity={pur}&categories={cats}&sorting=random&q={q}&apikey={api_key}"
);
log::info!("doing the thing with args 'atl={atl} rats={rats} pur={pur} cats={cats} q={q}'");
let search_resp = reqwest::get(wh_url).await;
match search_resp {
Err(err) => {
log::error!(
"oh nej! we hast failed! like, in the 'search_resp' thingy. err is '{err}'"
);
}
Ok(search_resp) => {
let json = search_resp.json::<WHSearchRes>().await;
match json {
Err(err) => {
log::error!("rövhål! failed in the 'json' match. err is '{err}'");
}
Ok(res) => {
let imgs = res.data;
let url = imgs.choose(&mut rand::thread_rng()).unwrap();
return HttpResponse::TemporaryRedirect()
.append_header(("Location", url.path.clone()))
.finish();
}
}
}
}
HttpResponse::TemporaryRedirect()
.append_header(("Location", "https://http.cat/510"))
.finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
log::info!("startedth uppeth");
HttpServer::new(|| App::new().service(random))
.bind(("0.0.0.0", 3000))?
.run()
.await
}