generated from ElnuDev/rust-project
Working images
This commit is contained in:
parent
ef562fe656
commit
331854b62b
3 changed files with 397 additions and 3 deletions
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue