diff --git a/src/collectors/mod.rs b/src/collectors/mod.rs index 2e3d1e8..377d9be 100644 --- a/src/collectors/mod.rs +++ b/src/collectors/mod.rs @@ -1,5 +1,5 @@ pub mod player_count; -// pub mod stats; +pub mod stats; pub trait PromMetric { fn to_metric_string(self: &Self) -> String; diff --git a/src/collectors/stats.rs b/src/collectors/stats.rs new file mode 100644 index 0000000..a3e1cc6 --- /dev/null +++ b/src/collectors/stats.rs @@ -0,0 +1,133 @@ +use std::fmt::{Display, Formatter}; +use eyre::eyre; + +#[derive(Debug)] +pub struct SkillInfo { + pub rank: String, + pub level: String, + pub xp: String, + pub name: String, + pub player: String, + pub profile: PlayerProfiles, +} + +#[derive(Debug)] +pub enum PlayerProfiles { + Standard, + // Beta, + // QuestSpeedrunning, + // Deadman, + // PVPArena, + // TrailblazerLeague, + // DeadmanReborn, + // ShatteredRelicsLeague, +} + +impl Display for PlayerProfiles { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + PlayerProfiles::Standard => write!(f, "Standard"), + // PlayerProfiles::Beta => write!(f, "Beta"), + // PlayerProfiles::QuestSpeedrunning => write!(f, "QuestSpeedrunning"), + // PlayerProfiles::Deadman => write!(f, "Deadman"), + // PlayerProfiles::PVPArena => write!(f, "PVPArena"), + // PlayerProfiles::TrailblazerLeague => write!(f, "TrailblazerLeague"), + // PlayerProfiles::DeadmanReborn => write!(f, "DeadmanReborn"), + // PlayerProfiles::ShatteredRelicsLeague => write!(f, "ShatteredRelicsLeague"), + } + } +} + +const SKILLS: [&str; 25] = [ + "Overall", + "Attack", + "Defence", + "Strength", + "Hitpoints", + "Ranged", + "Prayer", + "Magic", + "Cooking", + "Woodcutting", + "Fletching", + "Fishing", + "Firemaking", + "Crafting", + "Smithing", + "Mining", + "Herblore", + "Agility", + "Thieving", + "Slayer", + "Farming", + "Runecrafting", + "Hunter", + "Construction", + "Stuff", +]; + +pub async fn get_player_stats(rsn: &str) -> eyre::Result> { + let req_url = format!("https://oldschool.runescape.wiki/cors/m=hiscore_oldschool/index_lite.ws?player={}", rsn); + let resp = reqwest::Client::new() + .get(req_url) + .header("User-Agent", super::USER_AGENT) + .send() + .await?; + + if resp.status() != 200 { + return Err(eyre!("Player not found")); + } + + let raw = resp.text().await?; + + let mut n = SKILLS.into_iter(); + let skills: Vec = raw + .split("\n") + .into_iter() + .map(|x| x.split(',').collect::>()) + .filter(|x| x.len() == 3) + .map(|x| { + let name = n.next().unwrap(); + SkillInfo { + rank: x[0].to_string(), + level: x[1].to_string(), + xp: x[2].to_string(), + name: name.to_string(), + profile: PlayerProfiles::Standard, + player: rsn.to_string(), + } + }) + .collect(); + + Ok(skills) +} + +impl super::PromMetric for SkillInfo { + fn to_metric_string(self: &Self) -> String { + let lines: Vec = vec![ + format!( + "osrs_player_rank{{skill=\"{}\",player=\"{}\",profile=\"{}\"}} {}", + self.name, + self.player, + self.profile, + self.rank + ), + format!( + "osrs_player_level{{skill=\"{}\",player=\"{}\",profile=\"{}\"}} {}", + self.name, + self.player, + self.profile, + self.level + ), + format!( + "osrs_player_xp{{skill=\"{}\",player=\"{}\",profile=\"{}\"}} {}", + self.name, + self.player, + self.profile, + self.xp + ), + ]; + + lines.join("\n") + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d198273..9d067df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -mod collector; +mod collectors; use axum::routing::get; use axum::Router; @@ -25,11 +25,21 @@ async fn worlds() -> impl IntoResponse { (StatusCode::OK, convert_into_metrics(resp)) } +async fn stats(Path(rsn): Path) -> impl IntoResponse { + let resp = match collectors::stats::get_player_stats(&rsn).await { + Ok(r) => r, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Nope".to_string()) + }; + + (StatusCode::OK, convert_into_metrics(resp)) +} + + #[tokio::main] async fn main() { let app = Router::new() - .route("/worlds", get(worlds)); - // .route("/stats/:rsn", get(stats)); + .route("/worlds", get(worlds)) + .route("/stats/:rsn", get(stats)); println!("Starting...");