feat: let's gong

This commit is contained in:
Max batleforc 2025-05-24 22:49:10 +02:00
parent 34501bc413
commit b7d1faebcf
No known key found for this signature in database
GPG Key ID: 25D243AB4B6AC9E7
4 changed files with 184 additions and 1 deletions

36
apps/bot/src/bot/help.rs Normal file
View File

@ -0,0 +1,36 @@
use crate::bot::{Context, Error};
use poise::samples::HelpConfiguration;
use tracing::instrument;
/// Show help message
#[instrument(skip(ctx), level = "info",fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))]
#[poise::command(prefix_command, slash_command, track_edits, category = "Utility")]
pub async fn help(
ctx: Context<'_>,
#[description = "Command to get help for"]
#[rest]
mut command: Option<String>,
) -> Result<(), Error> {
// This makes it possible to just make `help` a subcommand of any command
// `/fruit help` turns into `/help fruit`
// `/fruit help apple` turns into `/help fruit apple`
if ctx.invoked_command_name() != "help" {
command = match command {
Some(c) => Some(format!("{} {}", ctx.invoked_command_name(), c)),
None => Some(ctx.invoked_command_name().to_string()),
};
}
let extra_text_at_bottom = "\
Provided by Mak with and too much ";
let config = HelpConfiguration {
show_subcommands: true,
show_context_menu_commands: false,
ephemeral: true,
extra_text_at_bottom,
..Default::default()
};
poise::builtins::help(ctx, command.as_deref(), config).await?;
Ok(())
}

View File

@ -1,12 +1,15 @@
use std::sync::Arc;
use clickhouse_pool::pool_manager::PoolManager;
use help::help;
use poise::serenity_prelude as serenity;
use poise::serenity_prelude::GatewayIntents;
use tracing::{info, instrument};
use crate::config::Config;
pub mod help;
/// Displays your or another user's account creation date
#[instrument(skip(ctx), level = "info", fields(channel_id = ctx.channel_id().get() , guild_id = ?ctx.guild_id(), user_id = ?ctx.author().id.get(), user_name = ctx.author().name))]
#[poise::command(slash_command, prefix_command)]
@ -44,7 +47,7 @@ pub async fn start_bot(config: Config, datalake_config: Arc<PoolManager>) {
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
commands: vec![age()],
commands: vec![age(), help()],
prefix_options: poise::PrefixFrameworkOptions {
prefix: Some(prefix),
..Default::default()

135
libs/database/src/guild.rs Normal file
View File

@ -0,0 +1,135 @@
use std::collections::HashMap;
use chrono::{DateTime, Utc};
use clickhouse::Row;
use clickhouse_pool::traits::Model;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Row, Serialize, Deserialize)]
pub struct Guild {
pub id: u64,
pub bot_name: String,
pub enrolled: bool,
pub prefix: String,
pub moderator: Vec<u64>,
pub feature_flags: HashMap<String, bool>,
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
pub created_at: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
pub updated_at: DateTime<Utc>,
pub creator_id: u64,
pub updater_id: u64,
}
impl Model for Guild {
type T = Guild;
fn table_name() -> &'static str {
"guild"
}
fn create_table_sql() -> &'static str {
r#"
CREATE TABLE IF NOT EXISTS guild (
id UInt64 PRIMARY KEY,
bot_name String,
enrolled Bool,
prefix String,
moderator Array(UInt64),
feature_flags Map(String, Bool),
created_at DateTime64(3),
updated_at DateTime64(3),
creator_id UInt64,
updater_id UInt64
) ENGINE = MergeTree()
ORDER BY (id)
"#
.trim()
}
fn column_names() -> Vec<&'static str> {
vec![
"id",
"bot_name",
"enrolled",
"prefix",
"moderator",
"feature_flags",
"created_at",
"updated_at",
"creator_id",
"updater_id",
]
}
fn to_row(&self) -> (Vec<&'static str>, Vec<String>) {
(
Self::column_names(),
vec![
self.id.to_string(),
self.bot_name.clone(),
self.enrolled.to_string(),
self.prefix.clone(),
format!("{:?}", self.moderator),
format!("{:?}", self.feature_flags),
self.created_at.to_rfc3339(),
self.updated_at.to_rfc3339(),
self.creator_id.to_string(),
self.updater_id.to_string(),
],
)
}
fn insert_query(&self) -> String {
let (columns, values) = self.to_row();
let columns_str = columns.join(", ");
let values_str = values.join(", ");
format!(
"INSERT INTO {} ({}) VALUES ({})",
Self::table_name(),
columns_str,
values_str
)
}
fn batch_insert_query(items: &[Self::T]) -> String {
let mut queries = Vec::new();
for item in items {
let (columns, values) = item.to_row();
let columns_str = columns.join(", ");
let values_str = values.join(", ");
queries.push(format!(
"INSERT INTO {} ({}) VALUES ({})",
Self::table_name(),
columns_str,
values_str
));
}
queries.join("; ")
}
fn build_select_query(
where_clause: Option<&str>,
limit: Option<u64>,
offset: Option<u64>,
) -> String {
let mut query = format!(
"SELECT {} FROM {}",
Self::column_names().join(", "),
Self::table_name()
);
if let Some(where_clause) = where_clause {
query.push_str(&format!(" WHERE {}", where_clause));
}
if let Some(limit) = limit {
query.push_str(&format!(" LIMIT {}", limit));
}
if let Some(offset) = offset {
query.push_str(&format!(" OFFSET {}", offset));
}
query
}
}

View File

@ -2,6 +2,7 @@ pub mod config;
use std::{error::Error, sync::Arc};
pub mod guild;
pub mod trivial;
pub mod trivial_point;
pub mod trivial_question;
@ -12,6 +13,7 @@ use clickhouse_pool::{
pool_manager::PoolManager,
traits::Model,
};
use guild::Guild;
use tracing::{error, info, instrument};
use trivial::Trivial;
use trivial_point::TrivialPoint;
@ -75,6 +77,13 @@ pub async fn create_manager_and_init(
}
};
manager = match create_table::<Guild>(manager).await {
Ok(manager) => manager,
Err(e) => {
return Err(e);
}
};
info!("All tables created successfully");
Ok(Arc::new(manager))