amu uptime checker
All checks were successful
arche-build-and-publish / gractwo-arche-build-test (push) Successful in 5m6s
All checks were successful
arche-build-and-publish / gractwo-arche-build-test (push) Successful in 5m6s
This commit is contained in:
692
Cargo.lock
generated
692
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@ chrono = "0.4.41"
|
||||
chrono-tz = "0.10.3"
|
||||
dotenvy = "0.15.7"
|
||||
rand = "0.9.1"
|
||||
reqwest = "0.13.2"
|
||||
serenity = "0.12.4"
|
||||
tokio = { version = "1.44.2", features = ["full"] }
|
||||
tower = "0.5.2"
|
||||
|
||||
58
src/router/amu_uptime.rs
Normal file
58
src/router/amu_uptime.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use axum::extract::State;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
|
||||
use crate::router::ApiSharedState;
|
||||
|
||||
pub async fn amu_uptime_route(State(state): State<ApiSharedState>) -> Response {
|
||||
let current = state.amu_uptime.read().await.clone();
|
||||
match current {
|
||||
Some((last_check, cached)) if last_check.elapsed() <= Duration::from_secs(30) => {
|
||||
cached.into_response()
|
||||
}
|
||||
_ => get_amu_uptime(&state).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_amu_uptime(state: &ApiSharedState) -> Response {
|
||||
let keywords = "Trwają prace serwisowe";
|
||||
let cl = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let result = match cl.get("https://amu.edu.pl").send().await {
|
||||
Ok(res) if res.status().is_success() => match res.text().await {
|
||||
Ok(text) => match text.contains(keywords) {
|
||||
true => (
|
||||
StatusCode::SERVICE_UNAVAILABLE,
|
||||
"AMU is up and wrongly uses 200 OK.".into(),
|
||||
),
|
||||
false => (
|
||||
StatusCode::OK,
|
||||
"AMU is up and doesn't contain the keywords. Could it be up for real?".into(),
|
||||
),
|
||||
},
|
||||
Err(_) => (
|
||||
StatusCode::SERVICE_UNAVAILABLE,
|
||||
"Failed to read response text from AMU.".into(),
|
||||
),
|
||||
},
|
||||
Ok(res) => (
|
||||
res.status(),
|
||||
format!("AMU website returned an error status: {}", res.status()),
|
||||
),
|
||||
Err(e) => (
|
||||
StatusCode::SERVICE_UNAVAILABLE,
|
||||
format!("Failed to connect to AMU: {}", e),
|
||||
),
|
||||
};
|
||||
|
||||
let mut lock = state.amu_uptime.write().await;
|
||||
*lock = Some((Instant::now(), result.clone()));
|
||||
drop(lock);
|
||||
|
||||
result.into_response()
|
||||
}
|
||||
@@ -1,10 +1,16 @@
|
||||
use std::{sync::Arc, time::Instant};
|
||||
|
||||
use axum::{Router, http::StatusCode, routing::get};
|
||||
use tokio::sync::RwLock;
|
||||
use tower::service_fn;
|
||||
|
||||
use crate::{
|
||||
days::days_of_community_existence, router::redirects::redirects, website::website_service,
|
||||
days::days_of_community_existence,
|
||||
router::{amu_uptime::amu_uptime_route, redirects::redirects},
|
||||
website::website_service,
|
||||
};
|
||||
|
||||
mod amu_uptime;
|
||||
mod redirects;
|
||||
|
||||
pub fn init() -> Router {
|
||||
@@ -20,7 +26,21 @@ fn api() -> Router {
|
||||
.route("/live", get(async || StatusCode::OK))
|
||||
.route("/discord-member-count", get(get_member_count))
|
||||
.route("/days-community", get(get_days_since_community_formation))
|
||||
.route("/amu-uptime", get(amu_uptime_route))
|
||||
.fallback(api_fallback)
|
||||
.with_state(ApiSharedState::new())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ApiSharedState {
|
||||
amu_uptime: Arc<RwLock<Option<(Instant, (StatusCode, String))>>>,
|
||||
}
|
||||
impl ApiSharedState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
amu_uptime: Arc::new(RwLock::new(None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn api_fallback() -> (StatusCode, String) {
|
||||
|
||||
Reference in New Issue
Block a user