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"
|
chrono-tz = "0.10.3"
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
rand = "0.9.1"
|
rand = "0.9.1"
|
||||||
|
reqwest = "0.13.2"
|
||||||
serenity = "0.12.4"
|
serenity = "0.12.4"
|
||||||
tokio = { version = "1.44.2", features = ["full"] }
|
tokio = { version = "1.44.2", features = ["full"] }
|
||||||
tower = "0.5.2"
|
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 axum::{Router, http::StatusCode, routing::get};
|
||||||
|
use tokio::sync::RwLock;
|
||||||
use tower::service_fn;
|
use tower::service_fn;
|
||||||
|
|
||||||
use crate::{
|
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;
|
mod redirects;
|
||||||
|
|
||||||
pub fn init() -> Router {
|
pub fn init() -> Router {
|
||||||
@@ -20,7 +26,21 @@ fn api() -> Router {
|
|||||||
.route("/live", get(async || StatusCode::OK))
|
.route("/live", get(async || StatusCode::OK))
|
||||||
.route("/discord-member-count", get(get_member_count))
|
.route("/discord-member-count", get(get_member_count))
|
||||||
.route("/days-community", get(get_days_since_community_formation))
|
.route("/days-community", get(get_days_since_community_formation))
|
||||||
|
.route("/amu-uptime", get(amu_uptime_route))
|
||||||
.fallback(api_fallback)
|
.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) {
|
async fn api_fallback() -> (StatusCode, String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user