From 957cdf22cbc02929a4b9243351b297eb59856170 Mon Sep 17 00:00:00 2001 From: Doloro1978 Date: Fri, 27 Mar 2026 17:59:06 +0000 Subject: [PATCH] can store and retrive data now lol ok xd --- crates/bot/src/command.rs | 108 ++++++++++++++++++ crates/bot/src/main.rs | 51 ++++++++- crates/entities/src/channel.rs | 25 ++++ crates/entities/src/lib.rs | 1 + crates/entities/src/messages.rs | 15 +++ crates/entities/src/prelude.rs | 1 + crates/migration/src/lib.rs | 2 + .../src/m20260325_162920_messages.rs | 8 ++ .../src/m20260327_164915_channels.rs | 33 ++++++ 9 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 crates/bot/src/command.rs create mode 100644 crates/entities/src/channel.rs create mode 100644 crates/migration/src/m20260327_164915_channels.rs diff --git a/crates/bot/src/command.rs b/crates/bot/src/command.rs new file mode 100644 index 0000000..e180e55 --- /dev/null +++ b/crates/bot/src/command.rs @@ -0,0 +1,108 @@ +use std::collections::HashMap; + +use entities::{channel, members, messages, server}; +use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, Related}; +use serenity::all::{ + Color, Command, CommandInteraction, Context, CreateCommand, CreateEmbed, CreateEmbedFooter, + CreateInteractionResponse, CreateInteractionResponseMessage, Embed, EmbedMessageBuilding, + InteractionContext, Message, MessageBuilder, MessageId, ResolvedOption, +}; + +pub struct Retrive {} + +impl Retrive { + pub async fn run( + db: &DatabaseConnection, + ctx: &Context, + command: &CommandInteraction, + ) -> CreateInteractionResponse { + let invoker_id = command.user.id.get() as i32; + let guild_id = command.guild_id.unwrap().get() as i32; + + let user_db_id = members::Entity::find() + .filter(members::Column::IdDiscord.eq(invoker_id)) + .one(db) + .await; + + let user_db_id = match user_db_id { + Ok(x) => match x { + Some(x) => x.id, + None => -1, + }, + Err(e) => -1, + }; + + if user_db_id == -1 { + let embed = CreateEmbed::new() + .title("Error!") + .description("You're not in our database :c") + .footer(CreateEmbedFooter::new("..or we ran into an error")) + .color(Color::RED); + let reply = CreateInteractionResponse::Message( + CreateInteractionResponseMessage::new().embed(embed), + ); + return reply; + } + + let server_db_id = server::Entity::find() + .filter(server::Column::IdDiscord.eq(guild_id)) + .one(db) + .await; + + let server_db_id = match server_db_id { + Ok(x) => match x { + Some(x) => x.id, + None => -1, + }, + Err(e) => -1, + }; + + let invoker_messages = messages::Entity::find() + .filter(messages::Column::IdSender.eq(user_db_id)) + .filter(messages::Column::IdServer.eq(server_db_id)) + .all(db) + .await; + + // TODO error checking here + let invoker_messages = invoker_messages.unwrap(); + let mut map: HashMap = HashMap::new(); // channel - amount + let mut map_channel: HashMap = HashMap::new(); // db_id - discord_id + for msg in invoker_messages { + // Get discord id of channel from db then store in map for cache + if map_channel.get(&msg.id_channel).is_none() { + let channel_db = channel::Entity::find_by_id(msg.id_channel) + .one(db) + .await + .unwrap() + .unwrap(); + map_channel.insert(msg.id_channel, channel_db.id_discord); + } + let channel_discord_id = map_channel.get(&msg.id_channel).unwrap(); + if let Some(count) = map.get(channel_discord_id) { + let count = count + 1; + map.insert(*channel_discord_id, count) + } else { + map.insert(*channel_discord_id, 1) + }; + } + + let mut summary_string: String = String::new(); + for x in map { + summary_string.push_str(format!("#{} -- {} \n", x.0, x.1).as_str()); + } + + let embed = CreateEmbed::new() + .title("Summary") + .description(format!("{} msgs in this server", summary_string)); + + let reply = CreateInteractionResponseMessage::new().embed(embed); + + CreateInteractionResponse::Message(reply) + } + pub fn register() -> CreateCommand { + CreateCommand::new("rective") + .name("userdata") + .description("Gets all the data related to the user calling the command") + .contexts(vec![InteractionContext::Guild]) + } +} diff --git a/crates/bot/src/main.rs b/crates/bot/src/main.rs index 3177953..aae5a1b 100644 --- a/crates/bot/src/main.rs +++ b/crates/bot/src/main.rs @@ -1,16 +1,19 @@ use std::env; use std::error::Error; -use entities::{content, members, messages, server}; +use entities::{channel, content, members, messages, server}; use migration::{Migrator, MigratorTrait}; use sea_orm::{ ActiveModelTrait, ColumnTrait, Database, DatabaseConnection, EntityTrait, QueryFilter, }; +use serenity::all::{Command, Interaction, Ready}; use serenity::async_trait; use serenity::model::channel::Message; use serenity::model::guild; use serenity::prelude::*; +mod command; + struct Bot { db: DatabaseConnection, } @@ -23,7 +26,7 @@ impl EventHandler for Bot { println!("Error sending message: {why:?}"); } } - // This is a mess, it should be split into its on function(s) + // TODO This is a mess, it should be split into its on function(s) msg.channel(&ctx.http).await.unwrap(); let activeModel = content::ActiveModel { id: sea_orm::ActiveValue::NotSet, @@ -75,14 +78,58 @@ impl EventHandler for Bot { } }; + let channel_id = msg.channel(&ctx.http).await.unwrap().id().get() as i32; + let channel = entities::channel::Entity::find() + .filter(entities::channel::Column::IdDiscord.eq(channel_id)) + .one(&self.db) + .await + .unwrap(); + + let channel = match channel { + Some(x) => x, + None => { + let activeModel = channel::ActiveModel { + id: sea_orm::ActiveValue::NotSet, + id_discord: sea_orm::ActiveValue::Set(channel_id), + }; + activeModel.insert(&self.db).await.unwrap() + } + }; + let activeModel = messages::ActiveModel { id: sea_orm::ActiveValue::NotSet, id_discord: sea_orm::ActiveValue::Set(msg.id.get() as i32), id_sender: sea_orm::ActiveValue::Set(member.unwrap().id), id_server: sea_orm::ActiveValue::Set(server.id), id_content: sea_orm::ActiveValue::Set(content.id), + id_channel: sea_orm::ActiveValue::Set(channel.id), }; activeModel.insert(&self.db).await.unwrap(); + // medo + } + async fn interaction_create(&self, ctx: Context, interaction: Interaction) { + if let Interaction::Command(command) = interaction { + println!("Received command interaction: {command:#?}"); + + let content = match command.data.name.as_str() { + "userdata" => Some(command::Retrive::run(&self.db, &ctx, &command).await), + _ => Some(serenity::all::CreateInteractionResponse::Pong), + }; + + if let Some(content) = content { + if let Err(why) = command.create_response(&ctx.http, content).await { + println!("Cannot respond to slash command: {why}"); + } + } + } + } + async fn ready(&self, ctx: Context, ready: Ready) { + println!("{} is connected!", ready.user.name); + + let global_command = + Command::create_global_command(&ctx.http, command::Retrive::register()).await; + + println!("I created the following global slash command: {global_command:#?}"); } } diff --git a/crates/entities/src/channel.rs b/crates/entities/src/channel.rs new file mode 100644 index 0000000..f2779c7 --- /dev/null +++ b/crates/entities/src/channel.rs @@ -0,0 +1,25 @@ +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "channel")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub id_discord: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::messages::Entity")] + Messages, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Messages.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/crates/entities/src/lib.rs b/crates/entities/src/lib.rs index 3f8904d..c7e784f 100644 --- a/crates/entities/src/lib.rs +++ b/crates/entities/src/lib.rs @@ -2,6 +2,7 @@ pub mod prelude; +pub mod channel; pub mod content; pub mod members; pub mod messages; diff --git a/crates/entities/src/messages.rs b/crates/entities/src/messages.rs index a0f83e9..21a56ed 100644 --- a/crates/entities/src/messages.rs +++ b/crates/entities/src/messages.rs @@ -10,11 +10,20 @@ pub struct Model { pub id_discord: i32, pub id_sender: i32, pub id_content: i32, + pub id_channel: i32, pub id_server: i32, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm( + belongs_to = "super::channel::Entity", + from = "Column::IdChannel", + to = "super::channel::Column::Id", + on_update = "NoAction", + on_delete = "NoAction" + )] + Channel, #[sea_orm( belongs_to = "super::content::Entity", from = "Column::IdContent", @@ -25,6 +34,12 @@ pub enum Relation { Content, } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::Content.def() diff --git a/crates/entities/src/prelude.rs b/crates/entities/src/prelude.rs index 9c006b8..1028fae 100644 --- a/crates/entities/src/prelude.rs +++ b/crates/entities/src/prelude.rs @@ -1,5 +1,6 @@ //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 +pub use super::channel::Entity as Channel; pub use super::content::Entity as Content; pub use super::members::Entity as Members; pub use super::messages::Entity as Messages; diff --git a/crates/migration/src/lib.rs b/crates/migration/src/lib.rs index 92fb426..ec6fc5e 100644 --- a/crates/migration/src/lib.rs +++ b/crates/migration/src/lib.rs @@ -4,6 +4,7 @@ mod m20260325_145211_servers; mod m20260325_145717_members; mod m20260325_162920_messages; mod m20260325_233947_content; +mod m20260327_164915_channels; pub struct Migrator; @@ -15,6 +16,7 @@ impl MigratorTrait for Migrator { Box::new(m20260325_145717_members::Migration), Box::new(m20260325_162920_messages::Migration), Box::new(m20260325_233947_content::Migration), + Box::new(m20260327_164915_channels::Migration), ] } } diff --git a/crates/migration/src/m20260325_162920_messages.rs b/crates/migration/src/m20260325_162920_messages.rs index 51a72e1..ca97302 100644 --- a/crates/migration/src/m20260325_162920_messages.rs +++ b/crates/migration/src/m20260325_162920_messages.rs @@ -1,6 +1,7 @@ use sea_orm_migration::{prelude::*, schema::*}; use crate::m20260325_233947_content::Content; +use crate::m20260327_164915_channels::{self, Channel}; #[derive(DeriveMigrationName)] pub struct Migration; @@ -22,6 +23,12 @@ impl MigrationTrait for Migration { .from(Messages::Table, Messages::IdContent) .to(Content::Table, Content::Id), ) + .col(integer(Messages::IdChannel)) + .foreign_key( + ForeignKey::create() + .from(Messages::Table, Messages::IdChannel) + .to(Channel::Table, Channel::Id), + ) .col(integer(Messages::IdServer)) .to_owned(), ) @@ -42,5 +49,6 @@ enum Messages { IdDiscord, IdSender, IdContent, + IdChannel, IdServer, } diff --git a/crates/migration/src/m20260327_164915_channels.rs b/crates/migration/src/m20260327_164915_channels.rs new file mode 100644 index 0000000..589a917 --- /dev/null +++ b/crates/migration/src/m20260327_164915_channels.rs @@ -0,0 +1,33 @@ +use sea_orm_migration::{prelude::*, schema::*}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Channel::Table) + .if_not_exists() + .col(pk_auto(Channel::Id)) + .col(integer(Channel::IdDiscord)) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Channel::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Channel { + Table, + Id, + IdDiscord, +}