100 lines
2.5 KiB
Rust
100 lines
2.5 KiB
Rust
use axum::{Router, routing::get};
|
|
use clap::Parser;
|
|
use fluent_templates::FluentLoader;
|
|
use lazy_static::lazy_static;
|
|
use std::{
|
|
sync::Arc,
|
|
time::{Duration, Instant},
|
|
};
|
|
use tera::Tera;
|
|
use tokio::sync::RwLock;
|
|
|
|
mod handlers;
|
|
use handlers::home_handler;
|
|
mod i18n;
|
|
|
|
use crate::{
|
|
handlers::{Report, analytics_handler, report_details_handler, set_lang_handler},
|
|
i18n::LOCALES,
|
|
};
|
|
|
|
lazy_static! {
|
|
pub static ref TEMPLATES: Tera = {
|
|
let mut tera = Tera::default();
|
|
tera.add_raw_templates(vec![
|
|
("_layout.html", include_str!("../templates/_layout.html")),
|
|
("_base.css", include_str!("../templates/_base.css")),
|
|
("index.html", include_str!("../templates/homepage.html")),
|
|
("details.html", include_str!("../templates/details.html")),
|
|
(
|
|
"analytics.html",
|
|
include_str!("../templates/analytics.html"),
|
|
),
|
|
])
|
|
.unwrap();
|
|
tera.register_function("fluent", FluentLoader::new(&*LOCALES));
|
|
tera
|
|
};
|
|
}
|
|
|
|
#[derive(clap::Parser, Debug)]
|
|
#[command(author, version, about, long_about = None)]
|
|
pub struct Cli {
|
|
/// Port to serve on
|
|
#[arg(short, long, default_value = "8000")]
|
|
port: String,
|
|
|
|
/// Whether to listen on 0.0.0.0
|
|
#[arg(long)]
|
|
host: bool,
|
|
|
|
/// Verbose mode
|
|
#[arg(short, long)]
|
|
verbose: bool,
|
|
}
|
|
|
|
pub struct Cache<T> {
|
|
pub data: T,
|
|
pub updated_at: Instant,
|
|
}
|
|
|
|
struct AppState {
|
|
app_name: String,
|
|
pub reports_cache: RwLock<Option<Cache<Vec<Report>>>>,
|
|
pub cache_duration: Duration,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
let cli = Cli::parse();
|
|
|
|
tracing_subscriber::fmt()
|
|
.with_max_level(tracing::Level::INFO)
|
|
.init();
|
|
|
|
let shared_state = Arc::new(AppState {
|
|
app_name: "Slimes Leaderboards".to_string(),
|
|
reports_cache: RwLock::new(None),
|
|
cache_duration: Duration::from_secs(30),
|
|
});
|
|
|
|
let app = Router::new()
|
|
.route("/", get(home_handler))
|
|
.route("/report/{id}", get(report_details_handler))
|
|
.route("/analytics", get(analytics_handler))
|
|
.route("/set-lang/{lang}", get(set_lang_handler))
|
|
.with_state(shared_state);
|
|
|
|
let addr = if cli.host {
|
|
format!("0.0.0.0:{}", cli.port)
|
|
} else {
|
|
format!("127.0.0.1:{}", cli.port)
|
|
};
|
|
|
|
let listener = tokio::net::TcpListener::bind(&addr).await?;
|
|
tracing::info!("Listening on http://{}", addr);
|
|
axum::serve(listener, app).await?;
|
|
|
|
Ok(())
|
|
}
|