#[macro_use] extern crate rocket;
use rocket::http::{Status, ContentType};
use rocket::http::CookieJar;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use include_dir::{include_dir, Dir};
mod rende;
mod req;
use rende::types::Sona;
static ASSETS: Dir = include_dir!("$CARGO_MANIFEST_DIR/static");
#[derive(Serialize, Deserialize, Debug)]
struct MainJSON {
sonas: Vec<Sona>
}
#[get("/")]
async fn index(cookies: &CookieJar<'_>) -> (Status, (ContentType, String)) {
let cookie = cookies.get("theme").map(|crumb| format!("{}", crumb.value()));
let theme = cookie.unwrap_or("light".to_string());
(Status::Ok, (ContentType::HTML, rende::home(theme)))
}
#[get("/search?<url>")]
async fn sonalookup(cookies: &CookieJar<'_>, url: &str) -> (Status, (ContentType, String)) {
let cookie = cookies.get("theme").map(|crumb| format!("{}", crumb.value()));
let theme = cookie.unwrap_or("light".to_string());
let mut success = false;
let mut res = req::get(url.to_string() + "/.well-known/fursona").await;
let mut r;
if let Err(e) = res {
return (Status::InternalServerError, (ContentType::HTML, rende::error(e.to_string(), theme)))
} else if let Ok(e) = res {
r = e
} else {
return (Status::ImATeapot, (ContentType::HTML, rende::error("Somewhere, somewhat, somehow", theme)))
}
if r.status() != reqwest::StatusCode::OK {
res = req::get(url.to_string() + "/.well-known/fursona.json").await;
if let Err(e) = res {
return (Status::InternalServerError, (ContentType::HTML, rende::error(e.to_string(), theme)))
} else if let Ok(e) = res {
r = e
} else {
return (Status::ImATeapot, (ContentType::HTML, rende::error("Somewhere, somewhat, somehow", theme)))
}
if r.status() == reqwest::StatusCode::OK {
success = true
}
} else {
success = true
}
if success {
let sonasr: Result<MainJSON, reqwest::Error> = r.json().await;
let mut content = "".to_string();
let mut i = 1;
if let Ok(sonas) = sonasr {
for sona in sonas.sonas {
content += &rende::card(sona, i);
i += 1;
}
return (Status::Ok, (ContentType::HTML, rende::cardpage(theme, url.to_string(), content)))
} else if let Err(e) = sonasr {
return (Status::InternalServerError, (ContentType::HTML, rende::error(e.to_string(), theme)))
} else {
return (Status::ImATeapot, (ContentType::HTML, rende::error("Somewhere, somewhat, somehow", theme)))
}
} else {
return (Status::NotFound, (ContentType::HTML, rende::error("Cannot find a fursona file in this domain.", theme)))
}
}
#[get("/<file..>")]
fn stat(cookies:&CookieJar<'_>, file: PathBuf) -> (Status, (ContentType, Vec<u8>)) {
let cookie = cookies.get("theme").map(|crumb| format!("{}", crumb.value()));
let theme = cookie.unwrap_or("light".to_string());
if let Some(file) = ASSETS.get_file(file) {
let ctype = ContentType::from_extension(file.path().extension().and_then(|x| x.to_str()).unwrap_or("")).unwrap_or(ContentType::Binary);
(Status::Ok, (ctype, file.contents().to_vec()))
} else {
(Status::NotFound, (ContentType::HTML, rende::error("You seem to be lost.", theme).into_bytes()))
}
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index, stat, sonalookup])
}