MLeTomatic/src/main.rs

129 lines
3.1 KiB
Rust

use std::io::BufRead;
use rand::seq::SliceRandom;
use once_cell::sync::Lazy;
static FONTS: &'static [&'static str] = &[
"Albura-Regular.ttf",
"AmaticSC-Bold.ttf",
"Exo-Regular.otf",
"EBGaramond08-Regular.otf",
"Gidole-Regular.ttf",
"LondrinaBook-Regular.otf",
"PlayenSans-Regular.otf",
"Playfulist.otf",
"ProzaLibre-Regular.ttf",
];
static WORDS: Lazy<Vec<String>> = Lazy::new(|| {
let file = std::fs::File::open("lefff-3.4.mlex").unwrap();
let file_buf = std::io::BufReader::new(file);
let mut words = Vec::new();
for line in file_buf.lines() {
let line = line.unwrap();
if line.as_bytes().get(0) != Some(&b't') {
continue
}
let mut cols = line.split('\t');
let Some(word) = cols.next() else {
continue
};
let class = cols.next();
match class {
Some("nc") => {}
Some("adj") => {
let Some(flex) = cols.nth(1) else {
continue
};
if flex.contains('p') || flex.contains('m') {
continue
}
}
_ => continue
}
let mut capitalized = String::from("T");
capitalized.push_str(&word[1..]);
words.push(capitalized);
}
//eprintln!("Words: {}", words.len());
words
});
#[tokio::main]
async fn main() {
Lazy::force(&WORDS);
tide::log::start();
let mut app = tide::new();
app.at("/").get(
move |req: tide::Request<()>| {
handle_request(
req
)
}
);
app.listen(std::net::SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), 8137)).await.unwrap();
}
async fn handle_request<'a>(_req: tide::Request<()>) -> tide::Result<tide::Response> {
let mut rng = rand::thread_rng();
let word = WORDS.choose(&mut rng).unwrap();
let client = reqwest::blocking::Client::builder()
.user_agent("Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0")
.build().unwrap();
let resp = client.get(format!("https://www.bing.com/images/search?q={word}&FORM=HDRSC3")).send().unwrap();
assert!(resp.status().is_success());
let page = resp.text().unwrap();
let pattern = r#"mediaurl="#;
let url_start = page.find(pattern).unwrap() + pattern.len();
let url_len = page[url_start..].find('&').unwrap();
if url_len > 1024 {
panic!("url too long ({url_len})");
}
let img_url_encoded = &page[url_start..url_start+url_len];
let img_url = percent_encoding::percent_decode_str(img_url_encoded).decode_utf8().unwrap();
if img_url.contains('"') {
panic!("url contains quotes");
}
let font = *FONTS.choose(&mut rng).unwrap();
Ok(tide::Response::builder(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "*")
.content_type(tide::http::mime::HTML)
.body(format!(r#"<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>MLeTomatic</title>
<style type="text/css">
@font-face {{
font-family: CustomFont;
src: url("//txmn.tk/fonts/{font}");
}}
body {{
text-align: center;
}}
h1 {{
font-family: CustomFont;
font-weight: normal;
}}
#img {{
max-width: 100%;
max-height: 100vh;
}}
</style>
</head>
<body>
<h1>Monnaie Libre et {word}</h1>
<img id="img" alt="{word}" src="{img_url}"/>
</body>
</html>"#))
.build())
}