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) -> 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), } }