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, } /// 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) -> 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::().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 }