MOdularizing kuma interface

This commit is contained in:
2026-04-30 21:33:12 -07:00
parent 9ee400041f
commit b7d25ef259
4 changed files with 14 additions and 6 deletions

View File

@@ -8,12 +8,12 @@ pub const BASE_URL: &str = "https://uptime.shockrah.xyz";
#[macro_export] #[macro_export]
macro_rules! heartbeat { macro_rules! heartbeat {
($slug:expr) => { format!("{}/api/status-page/heartbeat/{}", crate::api::BASE_URL, $slug) } ($slug:expr) => { format!("{}/api/status-page/heartbeat/{}", BASE_URL, $slug) }
} }
#[macro_export] #[macro_export]
macro_rules! endpoints { macro_rules! endpoints {
($slug:expr) => { format!("{}/api/status-page/{}", crate::api::BASE_URL, $slug) } ($slug:expr) => { format!("{}/api/status-page/{}", BASE_URL, $slug) }
} }
/// A single heartbeat within a monitor's latest status /// A single heartbeat within a monitor's latest status
@@ -48,10 +48,11 @@ pub struct KumaStatusPage {
} }
impl KumaMonitor { impl KumaMonitor {
/// Generates a full monitor object with the most recent available heartbeats
pub async fn new(val: &Value) -> Result<Self, Error> { pub async fn new(val: &Value) -> Result<Self, Error> {
// Populate the monitor with it's respective heartbeats at that time // Populate the monitor with it's respective heartbeats at that time
let id = val["id"].as_i64().unwrap_or(0); let id = val["id"].as_i64().unwrap_or(0);
let name = val["name"].to_string(); let name = val["name"].as_str().unwrap().into();
let response: Value = reqwest::get(heartbeat!("pub")).await?.json().await?; let response: Value = reqwest::get(heartbeat!("pub")).await?.json().await?;
if let Some(list) = &response["heartbeatList"][id.to_string()].as_array() { if let Some(list) = &response["heartbeatList"][id.to_string()].as_array() {
let heartbeats = list.iter().map(|item| { let heartbeats = list.iter().map(|item| {
@@ -72,6 +73,9 @@ impl KumaMonitor {
impl KumaStatusPage { impl KumaStatusPage {
/// Monitors require their own logic to fetch with their heartbeats on load.
/// This func is only really called by Self::get when we are first loading
/// a new status page for the first time
async fn get_monitors(json: &Value) -> Vec<KumaMonitor> { async fn get_monitors(json: &Value) -> Vec<KumaMonitor> {
let mut monitors = vec![]; let mut monitors = vec![];
for group in json["publicGroupList"].as_array().unwrap_or(&vec![]) { for group in json["publicGroupList"].as_array().unwrap_or(&vec![]) {
@@ -84,6 +88,8 @@ impl KumaStatusPage {
return monitors; return monitors;
} }
/// Main entrypoint for KumaStatePage API hits. Here we get the basics of the page
/// along with any and all heartbeats for the monitors on that page
pub async fn get(slug: &str) -> Result<Self, Error> { pub async fn get(slug: &str) -> Result<Self, Error> {
let endpoint = endpoints!(slug); let endpoint = endpoints!(slug);
let resp: Value = reqwest::get(&endpoint).await?.json().await?; let resp: Value = reqwest::get(&endpoint).await?.json().await?;

2
src/kuma/mod.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod api;
pub mod data;

View File

@@ -1,8 +1,7 @@
mod data; mod kuma;
mod api;
use reqwest::{self, Error}; use reqwest::{self, Error};
use crate::api::KumaStatusPage; use crate::kuma::api::KumaStatusPage;
use serde_json; use serde_json;
@@ -10,6 +9,7 @@ use serde_json;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Error> { async fn main() -> Result<(), Error> {
let public = KumaStatusPage::get("pub").await?; let public = KumaStatusPage::get("pub").await?;
// Debugging the initial API response
match serde_json::to_string(&public) { match serde_json::to_string(&public) {
Ok(result) => println!("{result}"), Ok(result) => println!("{result}"),
Err(_) => eprintln!("bruh") Err(_) => eprintln!("bruh")