feat(server): templating for cluster map is almost done (cluster hardcoded)

This commit is contained in:
Maieul BOYER 2026-02-20 18:42:45 +01:00
parent ac98af1428
commit 5e0a9ded04
Signed by: maix
SSH key fingerprint: SHA256:iqCzqFFF5KjRixmDExqbAltCIj9ndlBWIGJf3t9Ln9g
6 changed files with 173 additions and 5 deletions

View file

@ -21,3 +21,5 @@ froxy-scraper = { workspace = true }
color-eyre = "0.6.5"
cached = { version = "0.56.0", features = ["async", "async_tokio_rt_multi_thread"] }
rustc-hash = "2.1.1"
serde_json = { version = "1.0.149", features = ["preserve_order"] }
indexmap = { version = "2.13.0", features = ["serde"] }

119
server/src/cluster.rs Normal file
View file

@ -0,0 +1,119 @@
use std::collections::HashMap;
use axum::{
Router,
extract::{Query, State},
http::StatusCode,
response::Html,
};
use froxy_scraper::types::{ClusterLocationData, ClusterLocationStatus};
use froxy_templates::index::{ClusterData, LocationData, PcIssue};
use indexmap::IndexMap;
use log::trace;
use serde::{Deserialize, Serialize};
use smol_str::SmolStr;
pub fn router() -> Router<crate::GlobalState> {
Router::new().route("/", axum::routing::get(handle_cluster))
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct ClusterQuery {
cluster: Option<SmolStr>,
p: Option<SmolStr>,
}
#[cfg_attr(debug_assertions, axum::debug_handler)]
async fn handle_cluster(
State(state): State<crate::GlobalState>,
Query(ClusterQuery { cluster, p }): Query<ClusterQuery>,
) -> Result<Html<String>, StatusCode> {
let current_cluster = cluster.unwrap_or(SmolStr::new_static("f6"));
let map: HashMap<SmolStr, froxy_templates::index::Map> =
serde_json::from_str(include_str!("../../mapping.json")).unwrap();
let res = state.scraper.get("/", Some("cluster=f6")).await.unwrap();
let text = res.text().await.unwrap();
let location = froxy_scraper::parsing::get_cluster_location("f6", &text);
let issues: IndexMap<_, _> = location
.locations
.iter()
.filter(|s| matches!(s.data, ClusterLocationData::Normal { .. }))
.cloned()
.filter_map(|s| {
Some((
s.location.clone(),
match s.data {
ClusterLocationData::Normal {
status: ClusterLocationStatus::Dead,
} => PcIssue::Dead,
ClusterLocationData::Normal {
status: ClusterLocationStatus::Damaged,
} => PcIssue::Attention,
_ => return None,
},
))
})
.collect::<_>();
let loc: IndexMap<_, _> = location
.locations
.iter()
.filter(|s| matches!(s.data, ClusterLocationData::User { .. }))
.cloned()
.map(|s| {
let ClusterLocationData::User {
login,
image,
relation,
} = s.data
else {
unreachable!()
};
(
s.location.clone(),
LocationData {
login,
image: image.map(|u| u.to_string()).unwrap_or_default(),
me: matches!(relation, froxy_scraper::types::Relation::Me),
friend: matches!(relation, froxy_scraper::types::Relation::Friend),
close_friend: matches!(relation, froxy_scraper::types::Relation::CloseFriend),
pooled: matches!(relation, froxy_scraper::types::Relation::Pooled),
},
)
})
.collect::<_>();
trace!("location: {loc:?}");
state
.render_index(froxy_templates::index::IndexData {
locations: loc,
clusters: [(
SmolStr::new_static("f6"),
ClusterData {
users: 10,
max_pc: map[&SmolStr::new_static("f6")]
.rows
.iter()
.flat_map(|s| s.col.iter())
.filter(|s| matches!(s, froxy_templates::index::MapPos::Pc(_)))
.count() as u32,
silent: false,
piscine: false,
dead_pc: issues
.values()
.filter(|v| matches!(v, PcIssue::Dead))
.count() as u32,
map: map[&SmolStr::new_static("f6")].clone(),
issues,
},
)]
.into_iter()
.collect(),
current_cluster,
})
.map_err(crate::report_error)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
}

View file

@ -36,6 +36,7 @@ use log::info;
use tower_http::trace::TraceLayer;
use tracing_subscriber::EnvFilter;
mod cluster;
mod friends;
mod state;
mod static_;
@ -60,6 +61,7 @@ async fn main() {
let global_state = GlobalState::new();
let app = Router::new()
.merge(cluster::router())
.merge(friends::router())
.merge(user::router())
.merge(static_::router(&global_state))