Working images

This commit is contained in:
Elnu 2023-08-08 17:40:46 -07:00
parent ef562fe656
commit 331854b62b
3 changed files with 397 additions and 3 deletions

View file

@ -1,3 +1,76 @@
fn main() {
println!("Hello, world!");
use utils::error::Result;
use actix_web::{get, http::header, web, App, HttpResponse, HttpServer, Responder};
use rand::seq::SliceRandom;
pub const BING: &str = "https://www.bing.com/images/search";
async fn get_images(query: &str) -> reqwest::Result<Vec<String>> {
use lazy_static::lazy_static;
use scraper::{Html, Selector};
lazy_static! {
static ref MIMG: Selector = Selector::parse("img.mimg").unwrap();
}
let target = format!("{BING}?q={query}");
let document = Html::parse_document(&reqwest::get(&target).await?.text().await?);
Ok(document
.select(&MIMG)
.filter_map(|element| element.value().attr("src"))
.filter(|src| src.starts_with("http"))
.map(|href| href.to_owned())
.collect())
}
async fn route<F>(query: &str, handler: F) -> Result<impl Responder>
where
F: Fn(&Vec<String>) -> Option<&String>,
{
let images = get_images(query).await?;
Ok(match handler(&images) {
Some(image) => HttpResponse::Found()
.append_header((header::LOCATION, image.as_str()))
.finish(),
None => HttpResponse::Ok().body("No results"),
})
}
#[get("/{query}/list")]
async fn route_query_list(path: web::Path<String>) -> Result<impl Responder> {
let query = path.into_inner();
let images = get_images(&query).await?;
Ok(HttpResponse::Ok()
.append_header(header::ContentType(mime::APPLICATION_JSON))
.body(serde_json::to_string(&images).unwrap_or_else(|_| "[]".to_string())))
}
#[get("/{query}")]
async fn route_query(path: web::Path<String>) -> Result<impl Responder> {
let query = path.into_inner();
route(&query, |images| images.get(0)).await
}
#[get("/{query}/random")]
async fn route_query_random(path: web::Path<String>) -> Result<impl Responder> {
let query = path.into_inner();
route(&query, |images| images.choose(&mut rand::thread_rng())).await
}
#[get("/{query}/{index}")]
async fn route_query_index(path: web::Path<(String, usize)>) -> Result<impl Responder> {
let (query, index) = path.into_inner();
route(&query, move |images| images.get(index % images.len())).await
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(route_query_list)
.service(route_query)
.service(route_query_random)
.service(route_query_index)
})
.bind(("127.0.0.1", 3002))?
.run()
.await
}