site/src/main.rs

152 lines
4.7 KiB
Rust
Raw Normal View History

2020-07-12 18:42:09 +00:00
use anyhow::Result;
2020-07-14 13:10:12 +00:00
use hyper::{header::CONTENT_TYPE, Body, Response};
use prometheus::{Encoder, TextEncoder};
2020-07-12 23:26:53 +00:00
use std::sync::Arc;
2020-07-12 22:39:50 +00:00
use warp::{path, Filter};
2020-07-12 18:42:09 +00:00
pub mod app;
2020-07-12 22:39:50 +00:00
pub mod handlers;
2020-07-13 01:50:45 +00:00
pub mod post;
2020-07-12 18:42:09 +00:00
pub mod signalboost;
2020-07-12 23:26:53 +00:00
use app::State;
2020-07-12 18:42:09 +00:00
const APPLICATION_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
2020-07-12 23:26:53 +00:00
fn with_state(
state: Arc<State>,
) -> impl Filter<Extract = (Arc<State>,), Error = std::convert::Infallible> + Clone {
warp::any().map(move || state.clone())
}
2020-07-12 18:42:09 +00:00
#[tokio::main]
async fn main() -> Result<()> {
pretty_env_logger::init();
2020-07-13 12:01:33 +00:00
log::info!("starting up");
2020-07-12 18:42:09 +00:00
2020-07-13 00:11:26 +00:00
let state = Arc::new(app::init(
std::env::var("CONFIG_FNAME")
.unwrap_or("./config.dhall".into())
.as_str()
.into(),
)?);
2020-07-12 18:42:09 +00:00
2020-07-13 00:51:58 +00:00
let healthcheck = warp::get().and(warp::path(".within").and(warp::path("health")).map(|| "OK"));
2020-07-13 02:58:00 +00:00
let blog = {
let base = warp::path!("blog" / ..);
let index = base
.and(warp::path::end())
.and(with_state(state.clone()))
2020-07-13 12:19:33 +00:00
.and_then(handlers::blog::index);
2020-07-13 02:58:00 +00:00
let series = base.and(
2020-07-13 12:19:33 +00:00
warp::path!("series").and(with_state(state.clone()).and_then(handlers::blog::series)),
2020-07-13 02:58:00 +00:00
);
2020-07-13 11:54:17 +00:00
let series_view = base.and(
warp::path!("series" / String)
.and(with_state(state.clone()))
.and(warp::get())
2020-07-13 12:19:33 +00:00
.and_then(handlers::blog::series_view),
2020-07-13 11:54:17 +00:00
);
let post_view = base.and(
warp::path!(String)
.and(with_state(state.clone()))
.and(warp::get())
2020-07-13 12:19:33 +00:00
.and_then(handlers::blog::post_view),
2020-07-13 11:54:17 +00:00
);
2020-07-13 02:58:00 +00:00
2020-07-13 11:54:17 +00:00
index.or(series.or(series_view)).or(post_view)
2020-07-13 02:58:00 +00:00
};
2020-07-13 12:26:55 +00:00
let gallery = {
let base = warp::path!("gallery" / ..);
let index = base
.and(warp::path::end())
.and(with_state(state.clone()))
.and_then(handlers::gallery::index);
2020-07-13 12:37:09 +00:00
let post_view = base.and(
warp::path!(String)
.and(with_state(state.clone()))
.and(warp::get())
.and_then(handlers::gallery::post_view),
);
2020-07-13 12:26:55 +00:00
2020-07-13 12:37:09 +00:00
index.or(post_view)
2020-07-13 12:26:55 +00:00
};
2020-07-14 13:10:12 +00:00
let talks = {
let base = warp::path!("talks" / ..);
let index = base
.and(warp::path::end())
.and(with_state(state.clone()))
.and_then(handlers::talks::index);
let post_view = base.and(
warp::path!(String)
.and(with_state(state.clone()))
.and(warp::get())
.and_then(handlers::talks::post_view),
);
index.or(post_view)
};
2020-07-13 11:54:17 +00:00
let static_pages = {
let contact = warp::path!("contact").and_then(handlers::contact);
let feeds = warp::path!("feeds").and_then(handlers::feeds);
let resume = warp::path!("resume")
.and(with_state(state.clone()))
.and_then(handlers::resume);
let signalboost = warp::path!("signalboost")
.and(with_state(state.clone()))
.and_then(handlers::signalboost);
2020-07-14 13:10:12 +00:00
contact.or(feeds).or(resume).or(signalboost)
2020-07-13 11:54:17 +00:00
};
2020-07-13 02:58:00 +00:00
2020-07-13 11:54:17 +00:00
let files = {
let files = warp::path("static").and(warp::fs::dir("./static"));
let css = warp::path("css").and(warp::fs::dir("./css"));
let sw = warp::path("sw.js").and(warp::fs::file("./static/js/sw.js"));
let robots = warp::path("robots.txt").and(warp::fs::file("./static/robots.txt"));
files.or(css).or(sw).or(robots)
};
2020-07-14 13:10:12 +00:00
let metrics_endpoint = warp::path("metrics").and(warp::path::end()).map(move || {
let encoder = TextEncoder::new();
let metric_families = prometheus::gather();
let mut buffer = vec![];
encoder.encode(&metric_families, &mut buffer).unwrap();
Response::builder()
.status(200)
.header(CONTENT_TYPE, encoder.format_type())
.body(Body::from(buffer))
.unwrap()
});
2020-07-13 11:54:17 +00:00
let site = files
2020-07-14 13:10:12 +00:00
.or(warp::get().and(path::end().and_then(handlers::index)))
.or(static_pages)
.or(blog)
.or(gallery)
.or(talks)
.or(healthcheck)
.or(metrics_endpoint)
2020-07-13 00:51:58 +00:00
.map(|reply| {
warp::reply::with_header(
reply,
"X-Hacker",
"If you are reading this, check out /signalboost to find people for your team",
)
})
2020-07-13 12:01:33 +00:00
.map(|reply| warp::reply::with_header(reply, "X-Clacks-Overhead", "GNU Ashlynn"))
2020-07-13 11:54:17 +00:00
.with(warp::log(APPLICATION_NAME))
.recover(handlers::rejection);
2020-07-12 22:39:50 +00:00
warp::serve(site).run(([127, 0, 0, 1], 3030)).await;
2020-07-12 18:42:09 +00:00
Ok(())
2020-07-12 16:54:33 +00:00
}
2020-07-12 22:39:50 +00:00
include!(concat!(env!("OUT_DIR"), "/templates.rs"));