2020-07-16 16:10:45 -04:00
|
|
|
use crate::templates::RenderRucte;
|
|
|
|
use lazy_static::lazy_static;
|
2020-05-15 09:16:16 -04:00
|
|
|
use pfacts::Facts;
|
2020-07-16 16:10:45 -04:00
|
|
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
2020-05-13 16:38:16 -04:00
|
|
|
use rand::prelude::*;
|
2021-04-01 19:09:20 -04:00
|
|
|
use std::{convert::Infallible, str::FromStr};
|
|
|
|
use tokio::net::UnixListener;
|
|
|
|
use tokio_stream::wrappers::UnixListenerStream;
|
2020-07-16 16:10:45 -04:00
|
|
|
use warp::{http::Response, Filter, Rejection, Reply};
|
2020-05-13 16:38:16 -04:00
|
|
|
|
2020-07-16 16:10:45 -04:00
|
|
|
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
|
|
|
|
|
|
|
const APPLICATION_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref HIT_COUNTER: IntCounterVec =
|
|
|
|
register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"])
|
|
|
|
.unwrap();
|
2020-05-13 16:38:16 -04:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:10:45 -04:00
|
|
|
async fn give_fact(facts: Facts) -> Result<String, Infallible> {
|
|
|
|
HIT_COUNTER.with_label_values(&["fact"]).inc();
|
|
|
|
Ok(facts.choose(&mut thread_rng()).unwrap().clone())
|
2020-07-09 18:19:03 -04:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:10:45 -04:00
|
|
|
async fn index(facts: Facts) -> Result<impl Reply, Rejection> {
|
|
|
|
HIT_COUNTER.with_label_values(&["index"]).inc();
|
|
|
|
Response::builder()
|
|
|
|
.html(|o| templates::index_html(o, facts.choose(&mut thread_rng()).unwrap().clone()))
|
2020-07-09 18:19:03 -04:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:10:45 -04:00
|
|
|
async fn not_found() -> Result<impl Reply, Rejection> {
|
|
|
|
HIT_COUNTER.with_label_values(&["not_found"]).inc();
|
|
|
|
Response::builder()
|
|
|
|
.status(404)
|
|
|
|
.html(|o| templates::not_found_html(o))
|
2020-07-09 18:19:03 -04:00
|
|
|
}
|
|
|
|
|
2020-05-13 16:38:16 -04:00
|
|
|
#[tokio::main]
|
2020-07-09 18:19:03 -04:00
|
|
|
async fn main() -> anyhow::Result<()> {
|
2021-04-01 19:09:20 -04:00
|
|
|
tracing_subscriber::fmt::init();
|
2020-05-15 09:16:16 -04:00
|
|
|
let facts = pfacts::make();
|
2020-07-09 18:19:03 -04:00
|
|
|
|
|
|
|
let fact = {
|
|
|
|
let facts = facts.clone();
|
|
|
|
warp::any().map(move || facts.clone())
|
|
|
|
};
|
2020-05-13 16:38:16 -04:00
|
|
|
|
2020-07-09 18:19:03 -04:00
|
|
|
let files = warp::path("static").and(warp::fs::dir("./static"));
|
2020-05-13 16:38:16 -04:00
|
|
|
|
2020-07-09 18:19:03 -04:00
|
|
|
let fact_handler = warp::get()
|
|
|
|
.and(warp::path("fact"))
|
2020-07-16 16:10:45 -04:00
|
|
|
.and(fact.clone())
|
2020-05-13 16:38:16 -04:00
|
|
|
.and_then(give_fact);
|
|
|
|
|
2020-07-09 18:19:03 -04:00
|
|
|
let index_handler = warp::get()
|
|
|
|
.and(warp::path::end())
|
2020-07-16 16:10:45 -04:00
|
|
|
.and(fact.clone())
|
|
|
|
.and_then(index);
|
2020-07-09 18:19:03 -04:00
|
|
|
|
2020-07-16 16:10:45 -04:00
|
|
|
let not_found_handler = warp::any().and_then(not_found);
|
2020-07-09 18:19:03 -04:00
|
|
|
|
2021-04-01 19:09:20 -04:00
|
|
|
let server = warp::serve(
|
2020-07-09 18:19:03 -04:00
|
|
|
fact_handler
|
|
|
|
.or(index_handler)
|
|
|
|
.or(files)
|
2020-07-16 16:10:45 -04:00
|
|
|
.or(not_found_handler)
|
|
|
|
.with(warp::log(APPLICATION_NAME)),
|
2021-04-01 19:09:20 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
if let Ok(sockpath) = std::env::var("SOCKPATH") {
|
|
|
|
let _ = std::fs::remove_file(&sockpath);
|
|
|
|
let listener = UnixListener::bind(sockpath).unwrap();
|
|
|
|
let incoming = UnixListenerStream::new(listener);
|
|
|
|
server.run_incoming(incoming).await;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
let port = std::env::var("PORT")
|
|
|
|
.unwrap_or("5000".into())
|
|
|
|
.parse::<u16>()
|
|
|
|
.expect("PORT to be a string-encoded u16");
|
|
|
|
tracing::info!("listening on port {}", port);
|
|
|
|
server
|
|
|
|
.run((std::net::IpAddr::from_str("::").unwrap(), port))
|
|
|
|
.await;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2020-05-13 16:38:16 -04:00
|
|
|
}
|