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, /// api key from wallhaven.cc api_key: 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/APIKEY #[get("/random/{atleast}/{ratios}/{purity}/{categories}/{q}/{api_key}")] 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 = args.api_key.clone(); 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}" ); let search_resp = reqwest::get(wh_url).await; match search_resp { Err(err) => { println!("search_resp: {}", err); } Ok(search_resp) => { let json = search_resp.json::().await; match json { Err(err) => { println!("json: {}", 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<()> { HttpServer::new(|| App::new().service(random)) .bind(("127.0.0.1", 3000))? .run() .await }