diff --git a/Cargo.lock b/Cargo.lock index 6ad9b30..1cd7f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1437,7 +1437,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "payphone" -version = "4.2.17" +version = "4.2.18" dependencies = [ "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index cf3753d..7ce9c07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "payphone" -version = "4.2.17" +version = "4.2.18" edition = "2024" default-run = "payphone" diff --git a/src/database/models.rs b/src/database/models.rs index b3f296a..95916e8 100644 --- a/src/database/models.rs +++ b/src/database/models.rs @@ -287,7 +287,7 @@ impl User { }) } - pub async fn count(&self, session: &Session) -> Result { + pub async fn count(session: &Session) -> Result { let result = session .query_unpaged( r#" @@ -1060,6 +1060,25 @@ impl Call { Ok(()) } + + pub async fn count(session: &Session) -> Result { + let result = session + .query_unpaged( + r#" + SELECT + call_id + FROM + payphone.calls; + "#, + (), + ) + .await + .map_err(DatabaseError::QueryError)? + .into_rows_result() + .map_err(|_| DatabaseError::ResultNotRows)?; + + Ok(result.rows_num()) + } } #[derive(Debug, Clone, SerializeValue, DeserializeValue)] @@ -1325,6 +1344,22 @@ impl Message { Ok(()) } + + pub async fn count(session: &Session) -> Result { + let result = session + .query_unpaged( + r#" + SELECT message_id FROM payphone.messages; + "#, + (), + ) + .await + .map_err(DatabaseError::QueryError)? + .into_rows_result() + .map_err(|_| DatabaseError::ResultNotRows)?; + + Ok(result.rows_num()) + } } pub struct MessageByPropagationId { diff --git a/src/groups/moderation/commands.rs b/src/groups/moderation/commands.rs index 845d00a..1d69c0c 100644 --- a/src/groups/moderation/commands.rs +++ b/src/groups/moderation/commands.rs @@ -1,6 +1,7 @@ use async_trait::async_trait; use crate::{ + database::models::{Call, Message, User}, extras::Extras, framework::{ commands::{ @@ -146,3 +147,39 @@ impl Command for IncidentsCommand { Ok(()) } } + +#[derive(Debug)] +pub struct StatsCommand; + +#[async_trait] +impl Command for StatsCommand { + fn name(&self) -> &'static str { + "stats" + } + + fn permissions(&self) -> Vec + Send + Sync + 'static>> { + vec![Box::new(BotOwnerPermission)] + } + + fn show_in_help(&self, rt: &Runtime, extras: &Extras) -> bool { + extras.user.id == rt.state.bot_owner_id + } + + async fn execute( + &self, + ctx: CommandContext<'_, State, Extras>, + _args: &str, + ) -> Result<(), CommandError> { + let users = User::count(&ctx.rt.state.db).await?; + let calls = Call::count(&ctx.rt.state.db).await?; + let messages = Message::count(&ctx.rt.state.db).await?; + + ctx.send() + .content(format!( + "```\nUsers: {users}\nCalls: {calls}\nMessages: {messages}\n```" + )) + .await?; + + Ok(()) + } +}