Add metrics for player statistics
This commit is contained in:
parent
58f6d57571
commit
feb39ec8ef
3 changed files with 147 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
||||||
pub mod player_count;
|
pub mod player_count;
|
||||||
// pub mod stats;
|
pub mod stats;
|
||||||
|
|
||||||
pub trait PromMetric {
|
pub trait PromMetric {
|
||||||
fn to_metric_string(self: &Self) -> String;
|
fn to_metric_string(self: &Self) -> String;
|
||||||
|
|
133
src/collectors/stats.rs
Normal file
133
src/collectors/stats.rs
Normal file
|
@ -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<Vec<SkillInfo>> {
|
||||||
|
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<SkillInfo> = raw
|
||||||
|
.split("\n")
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| x.split(',').collect::<Vec<&str>>())
|
||||||
|
.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<String> = 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")
|
||||||
|
}
|
||||||
|
}
|
16
src/main.rs
16
src/main.rs
|
@ -1,4 +1,4 @@
|
||||||
mod collector;
|
mod collectors;
|
||||||
|
|
||||||
use axum::routing::get;
|
use axum::routing::get;
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
|
@ -25,11 +25,21 @@ async fn worlds() -> impl IntoResponse {
|
||||||
(StatusCode::OK, convert_into_metrics(resp))
|
(StatusCode::OK, convert_into_metrics(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn stats(Path(rsn): Path<String>) -> 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]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/worlds", get(worlds));
|
.route("/worlds", get(worlds))
|
||||||
// .route("/stats/:rsn", get(stats));
|
.route("/stats/:rsn", get(stats));
|
||||||
|
|
||||||
println!("Starting...");
|
println!("Starting...");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue