From 409583da1e0a356347d18ef97c4cbbf936b10617 Mon Sep 17 00:00:00 2001 From: eiiko6 Date: Fri, 27 Mar 2026 21:50:19 +0100 Subject: [PATCH] changed score calculation and added sorting and 'new' tag --- src/handlers.rs | 71 ++++++++++++++++++-- src/main.rs | 2 +- templates/_base.css | 17 +---- templates/details.html | 13 +++- templates/homepage.html | 144 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 220 insertions(+), 27 deletions(-) diff --git a/src/handlers.rs b/src/handlers.rs index afe0ea4..60bc322 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -1,5 +1,5 @@ use axum::{ - extract::{Path, State}, + extract::{Path, Query, State}, response::{Html, IntoResponse}, }; use chrono::{DateTime, Utc}; @@ -10,6 +10,12 @@ use tera::Context; use crate::{AppState, TEMPLATES}; +#[derive(Debug, Serialize, Deserialize)] +pub struct SortParams { + pub sort: Option, + pub order: Option, +} + #[derive(Debug, Serialize, Deserialize)] pub struct Report { pub id: u64, @@ -25,12 +31,17 @@ pub struct Report { pub struct ReportRow { pub id: u64, pub score: u64, + pub single_score: u64, + pub multi_score: u64, pub cores: u32, pub ram: String, + pub ram_raw: f32, pub os: String, pub hostname: String, pub time_ago: String, + pub timestamp: String, pub signature: String, + pub is_new: bool, } #[derive(Debug, Serialize, Deserialize)] @@ -63,6 +74,16 @@ fn format_time_ago(timestamp: &str) -> String { } } +fn is_recent(timestamp: &str) -> bool { + DateTime::parse_from_rfc3339(timestamp) + .map(|ts| { + let now = Utc::now(); + let diff = now.signed_duration_since(ts.with_timezone(&Utc)); + diff.num_hours() < 24 && diff.num_seconds() >= 0 + }) + .unwrap_or(false) +} + fn parse_total_ram(ram_str: &str) -> String { let total_part = ram_str.split('/').last().unwrap_or("").trim(); let digits: String = total_part.chars().filter(|c| c.is_ascii_digit()).collect(); @@ -73,8 +94,15 @@ fn parse_total_ram(ram_str: &str) -> String { } } +fn parse_total_ram_raw(ram_str: &str) -> f32 { + let total_part = ram_str.split('/').last().unwrap_or("").trim(); + let digits: String = total_part.chars().filter(|c| c.is_ascii_digit()).collect(); + digits.parse::().unwrap_or(0.0) / 1024.0 +} + pub async fn home_handler( State(state): State>, + Query(params): Query, ) -> Result { let response = reqwest::get("https://alatreon.org/slimes?limit=1000") .await @@ -87,11 +115,13 @@ pub async fn home_handler( ) })?; - let reports: Vec = raw_reports + let mut reports: Vec = raw_reports .into_iter() .map(|s| ReportRow { id: s.id, - score: s.benchmark.multi_thread.score, + score: (s.benchmark.multi_thread.score + s.benchmark.single_thread.score) / 2, + single_score: s.benchmark.single_thread.score, + multi_score: s.benchmark.multi_thread.score, cores: s.benchmark.logical_cores, ram: s .slimes @@ -99,6 +129,12 @@ pub async fn home_handler( .and_then(|v| v.first()) .map(|r| parse_total_ram(r)) .unwrap_or_else(|| "-".into()), + ram_raw: s + .slimes + .get("RAM") + .and_then(|v| v.first()) + .map(|r| parse_total_ram_raw(r)) + .unwrap_or_else(|| 0.0), os: s .slimes .get("OS") @@ -111,14 +147,37 @@ pub async fn home_handler( .and_then(|v| v.first()) .cloned() .unwrap_or_else(|| "-".into()), - time_ago: format_time_ago(&s.timestamp), signature: s.signature, + timestamp: s.timestamp.clone(), + time_ago: format_time_ago(&s.timestamp), + is_new: is_recent(&s.timestamp), }) .collect(); + let sort_field = params.sort.unwrap_or_else(|| "score".to_string()); + let order = params.order.unwrap_or_else(|| "desc".to_string()); + + reports.sort_by(|a, b| { + let cmp = match sort_field.as_str() { + "single" => a.single_score.cmp(&b.single_score), + "multi" => a.multi_score.cmp(&b.multi_score), + "ram" => a + .ram_raw + .partial_cmp(&b.ram_raw) + .unwrap_or(std::cmp::Ordering::Equal), + "threads" => a.cores.cmp(&b.cores), + "time" => a.timestamp.cmp(&b.timestamp), + _ => a.score.cmp(&b.score), + }; + + if order == "asc" { cmp } else { cmp.reverse() } + }); + let mut context = Context::new(); context.insert("reports", &reports); context.insert("title", &state.app_name); + context.insert("current_sort", &sort_field); + context.insert("current_order", &order); match TEMPLATES.render("index.html", &context) { Ok(html) => Ok(Html(html)), @@ -143,6 +202,10 @@ pub async fn report_details_handler( context.insert("report", &report); context.insert("title", &format!("Report #{} | {}", id, state.app_name)); context.insert("time_ago", &format_time_ago(&report.timestamp)); + context.insert( + "score", + &((report.benchmark.multi_thread.score + report.benchmark.single_thread.score) / 2), + ); match TEMPLATES.render("details.html", &context) { Ok(html) => Ok(Html(html)), diff --git a/src/main.rs b/src/main.rs index 3d19ddf..6db6c9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,7 @@ async fn main() -> anyhow::Result<()> { .init(); let shared_state = Arc::new(AppState { - app_name: "Quick rust website template".to_string(), + app_name: "Slimes Leaderboards".to_string(), }); let app = Router::new() diff --git a/templates/_base.css b/templates/_base.css index 7b11186..0bf065d 100644 --- a/templates/_base.css +++ b/templates/_base.css @@ -37,7 +37,7 @@ body { main { width: 100%; - max-width: 1200px; + max-width: 1400px; margin: 0 auto; padding: 1rem; flex: 1; @@ -83,21 +83,6 @@ tr:hover { background-color: var(--hover-color); } -.score-cell { - color: var(--primary-color); - font-weight: 700; -} - -.signature-cell { - color: var(--text-muted); - font-style: italic; - font-size: 0.8rem; - max-width: 200px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - footer { padding: 2rem; text-align: center; diff --git a/templates/details.html b/templates/details.html index 10509f2..83d8a77 100644 --- a/templates/details.html +++ b/templates/details.html @@ -44,8 +44,9 @@
-
{{ report.benchmark.multi_thread.score }}
-
Multi-Thread Score
+
{{ score }}
+
CPU Score
+
(mt+st)/2
@@ -91,7 +92,7 @@ background: var(--bg-card); border-radius: 12px; padding: 2.5rem; - box-shadow: 0 4px 6px rgba(0,0,0,0.05); + /* box-shadow: 0 4px 6px rgba(0,0,0,0.05); */ border: 1px solid var(--border-color); } @@ -165,6 +166,12 @@ line-height: 1; } .score-label { + font-size: 1rem; + text-transform: uppercase; + color: var(--text-muted); + letter-spacing: 0.1em; +} +.score-note { font-size: 0.7rem; text-transform: uppercase; color: var(--text-muted); diff --git a/templates/homepage.html b/templates/homepage.html index e6b8d2d..fce1606 100644 --- a/templates/homepage.html +++ b/templates/homepage.html @@ -1,11 +1,41 @@ {% extends "_layout.html" %} {% block content %} -

Benchmark Reports

+
+

Benchmark Reports

+ +
+
+
+ + +
+ +
+ + +
+
+
+
+ - + @@ -24,13 +54,26 @@ - + {% endfor %}
MT ScoreCPU Score Threads RAM OS{{ report.ram }} {{ report.os | truncate(length=30) }} {{ report.hostname }}{{ report.time_ago }}{{ report.time_ago }} + {% if report.is_new %} + NEW + {% endif %} + {{ report.signature }}
+ + {% endblock %}