warthunder-leak-counter/src/controllers/home.rs
2025-09-26 22:20:08 -03:00

112 lines
3 KiB
Rust

use askama::Template;
use axum::extract::State;
use time::Date;
use crate::{sources, AppState};
#[derive(Template)]
#[template(path = "index.html")]
pub struct HomeTemplate {
time_since: TimeSince,
}
pub struct TimeSince {
days: i32,
}
impl TimeSince {
fn from_interval(leak: &Date, now: &Date) -> Self {
Self {
days: now.to_julian_day() - leak.to_julian_day(),
}
}
}
#[axum::debug_handler]
pub async fn get(state: State<AppState>) -> HomeTemplate {
let mut t = vec![];
let client = reqwest::Client::builder()
.user_agent("warthunder_leak_counter.lelgenio.com")
.build()
.unwrap();
for source in sources::sources() {
let url = source.url();
let mut cache = state.0.get_cache.lock().await;
let now = time::OffsetDateTime::now_utc();
let needs_update = match cache.get(&url) {
None => {
tracing::info!("Value is not present in cache");
true
}
Some((cached_time, _)) => {
let other_day = cached_time.to_julian_day() != now.to_julian_day();
let other_hour = cached_time.hour() != now.hour();
if other_day {
tracing::info!("Value is from another day");
}
if other_hour {
tracing::info!("Value is from another hour");
}
other_day || other_hour
}
};
if needs_update {
tracing::info!("Need update cache");
let Ok(res) = (client.get(url.clone())).send().await else {
tracing::error!("fetch error");
continue;
};
let status = res.status();
let text = res.text().await;
if !status.is_success() {
tracing::error!("fetch returned status {status}");
tracing::error!("response body {text:?}");
continue;
}
let Ok(text) = text else {
tracing::error!("fetch decode text error");
continue;
};
tracing::info!("Cache updated");
cache.insert(url.clone(), (now, text));
}
let Some((_, text)) = cache.get(&url) else {
tracing::error!("filling cache error");
continue;
};
let last = match source.latest_leak(text) {
Ok(last) => last,
Err(err) => {
tracing::error!("source decode error: {err:#?}");
continue;
}
};
t.push(last);
}
let last = t
.into_iter()
.max()
.unwrap_or(time::Date::from_calendar_date(2021, time::Month::July, 14).unwrap());
let now = time::OffsetDateTime::now_utc();
let now = time::Date::from_calendar_date(now.year(), now.month(), now.day()).unwrap();
HomeTemplate {
time_since: TimeSince::from_interval(&last, &now),
}
}