#![feature(lazy_cell)] use dotenv::var; use log::LevelFilter; use std::fs::File; use std::sync::Arc; use lfm_embed::{STATE, ResponseCtx}; use warp::Filter; #[derive(serde::Deserialize, Debug)] struct UserQuery { #[serde(default)] theme: Option> } #[tokio::main] async fn main() { env_logger::Builder::new() .filter_level(LevelFilter::Warn) .parse_filters(&var("LFME_LOG_LEVEL").unwrap_or_default()) .target( var("LFME_LOG_FILE").ok() .map( |f| env_logger::Target::Pipe( Box::new(File::options() .append(true) .open(f) .expect("couldn't open LFME_LOG_FILE"))) ) .unwrap_or(env_logger::Target::Stderr) ).init(); std::sync::LazyLock::force(&STATE); let user = warp::path!("user" / String) .and(warp::query::()) .then(|s, q: UserQuery| async move { log::info!(target: "lfm::server::user", "Handling request for user `{s}` with {q:?}"); let (ctx, dur) = STATE.get_userinfo(&s).await; let ResponseCtx(data, status) = ctx.into(); let theme = q.theme.unwrap_or_else(|| STATE.default_theme()); warp::reply::with_header( warp::reply::with_status( warp::reply::html( STATE.handlebars().render(&theme, &data).unwrap() ), status ), "Refresh", dur.as_secs() ) }); warp::serve(user) .bind(([127,0,0,1], STATE.port())).await; }