212 lines
5.8 KiB
Rust

use std::{collections::HashMap, env};
use chrono::{DateTime, Utc};
use rocket::{
http::{CookieJar, Status},
serde::json::json,
State,
};
use rocket_dyn_templates::Template;
use serde::Serialize;
use sqlx::{MySql, Pool};
use crate::routes::JsonResult;
fn is_admin(cookies: &CookieJar<'_>) -> bool {
cookies
.get_private("userid")
.map_or(false, |cookie| Some(cookie.value().to_string()) == env::var("ADMIN_ID").ok())
}
#[get("/")]
pub async fn admin_dashboard_home(cookies: &CookieJar<'_>) -> Result<Template, Status> {
if let Some(cookie) = cookies.get_private("userid") {
let map: HashMap<&str, String> = HashMap::new();
if Some(cookie.value().to_string()) == env::var("ADMIN_ID").ok() {
Ok(Template::render("admin_dashboard", &map))
} else {
Err(Status::Forbidden)
}
} else {
Err(Status::Unauthorized)
}
}
#[derive(Serialize)]
struct TimeFrame {
time_key: DateTime<Utc>,
count: i64,
}
#[get("/data")]
pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> JsonResult {
if !is_admin(cookies) {
return json_err!("Not authorized");
}
let backlog = sqlx::query!(
"SELECT COUNT(1) AS backlog FROM reminders WHERE `utc_time` < NOW() AND enabled = 1"
)
.fetch_one(pool.inner())
.await
.unwrap();
let schedule_once = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 300) * 300) AS `time_key`,
COUNT(1) AS `count`
FROM reminders
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let schedule_interval = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 300) * 300) AS `time_key`,
COUNT(1) AS `count`
FROM reminders
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND (
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
`interval_days` IS NOT NULL
)
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let schedule_once_long = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM reminders
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 31 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let schedule_interval_long = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM reminders
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 31 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND (
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
`interval_days` IS NOT NULL
)
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let history = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM stat
WHERE
`utc_time` > DATE_SUB(NOW(), INTERVAL 31 DAY) AND
`type` = 'reminder_sent'
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let history_failed = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM stat
WHERE
`utc_time` > DATE_SUB(NOW(), INTERVAL 31 DAY) AND
`type` = 'reminder_failed'
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let interval_count = sqlx::query!(
"SELECT COUNT(1) AS count
FROM reminders
WHERE
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
`interval_days` IS NOT NULL"
)
.fetch_one(pool.inner())
.await
.unwrap();
let reminder_count = sqlx::query!(
"SELECT COUNT(1) AS count
FROM reminders
WHERE
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL"
)
.fetch_one(pool.inner())
.await
.unwrap();
Ok(json!({
"backlog": backlog.backlog,
"scheduleShort": {
"once": schedule_once,
"interval": schedule_interval
},
"scheduleLong": {
"once": schedule_once_long,
"interval": schedule_interval_long,
},
"historyLong": {
"sent": history,
"failed": history_failed,
},
"count": {
"reminders": reminder_count.count,
"intervals": interval_count.count,
}
}))
}