Compare commits
8 Commits
834f58061c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
cb143254b6
|
|||
|
a6932b1b0b
|
|||
|
97cdbdec0b
|
|||
|
b0968a4f28
|
|||
|
eeee568048
|
|||
|
957cdf22cb
|
|||
|
7ae73dc49e
|
|||
|
4a53d5c111
|
Generated
+4
@@ -563,6 +563,7 @@ dependencies = [
|
|||||||
name = "bot"
|
name = "bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"entities",
|
||||||
"migration",
|
"migration",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
"serenity",
|
"serenity",
|
||||||
@@ -989,6 +990,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "entities"
|
name = "entities"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"sea-orm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ serenity = "0.12"
|
|||||||
tokio = {workspace = true}
|
tokio = {workspace = true}
|
||||||
sea-orm = {workspace = true}
|
sea-orm = {workspace = true}
|
||||||
migration ={workspace = true}
|
migration ={workspace = true}
|
||||||
|
entities = {workspace = true}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use entities::{channel, members, messages, server};
|
||||||
|
use sea_orm::{ColIdx, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter};
|
||||||
|
use serenity::all::{
|
||||||
|
CommandInteraction, Context, CreateCommand, CreateEmbed, CreateInteractionResponse,
|
||||||
|
CreateInteractionResponseMessage, InteractionContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::common::error_msg;
|
||||||
|
|
||||||
|
pub struct Channelretrive {}
|
||||||
|
|
||||||
|
impl Channelretrive {
|
||||||
|
pub async fn run(
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
ctx: &Context,
|
||||||
|
command: &CommandInteraction,
|
||||||
|
) -> CreateInteractionResponse {
|
||||||
|
let invoker_id = command.user.id.get() as i64;
|
||||||
|
let channel_id = command.channel_id.get() as i64;
|
||||||
|
// let guild_id = command.guild_id.unwrap().get() as i64;
|
||||||
|
// let guild_name = command.guild_id.unwrap().name(&ctx.cache).unwrap();
|
||||||
|
|
||||||
|
let channel_db = channel::Model::get_or_create(channel_id, db).await;
|
||||||
|
|
||||||
|
if let Err(e) = channel_db {
|
||||||
|
return error_msg(Box::new(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
// let guild_db = server::Model::get_or_create(guild_id, guild_name, db).await;
|
||||||
|
//
|
||||||
|
// if let Err(e) = guild_db {
|
||||||
|
// return error_msg(Box::new(e));
|
||||||
|
// }
|
||||||
|
|
||||||
|
let messages_by_channels = messages::Entity::find()
|
||||||
|
.filter(messages::Column::IdChannel.eq(channel_db.unwrap()))
|
||||||
|
.all(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut user_lookup: HashMap<i32, String> = HashMap::new();
|
||||||
|
let mut user_msg_amount: HashMap<String, i32> = HashMap::new();
|
||||||
|
|
||||||
|
for x in messages_by_channels {
|
||||||
|
if let Some(user) = user_lookup.get(&x.id_sender) {
|
||||||
|
if let Some(user_amount) = user_msg_amount.get(user) {
|
||||||
|
user_msg_amount.insert(user.to_string(), (user_amount + 1));
|
||||||
|
} else {
|
||||||
|
user_msg_amount.insert(user.clone(), 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let memebr = members::Entity::find_by_id(x.id_sender)
|
||||||
|
.one(db)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
user_lookup.insert(memebr.id, memebr.name.clone());
|
||||||
|
user_msg_amount.insert(memebr.name, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut summary_string: String = String::new();
|
||||||
|
for x in &user_msg_amount {
|
||||||
|
summary_string.push_str(format!("{} - {}\n", x.0, x.1).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title("Summary")
|
||||||
|
.description(format!("{}", summary_string));
|
||||||
|
|
||||||
|
let reply = CreateInteractionResponseMessage::new().embed(embed);
|
||||||
|
|
||||||
|
CreateInteractionResponse::Message(reply)
|
||||||
|
}
|
||||||
|
pub fn register() -> CreateCommand {
|
||||||
|
CreateCommand::new("retriveChannel")
|
||||||
|
.name("channeldata")
|
||||||
|
.description("description")
|
||||||
|
.contexts(vec![InteractionContext::Guild])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
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,
|
||||||
|
},
|
||||||
|
model::guild,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::common::{self, error_msg};
|
||||||
|
|
||||||
|
pub struct Retrive {}
|
||||||
|
|
||||||
|
impl Retrive {
|
||||||
|
pub async fn run(
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
ctx: &Context,
|
||||||
|
command: &CommandInteraction,
|
||||||
|
) -> CreateInteractionResponse {
|
||||||
|
let invoker_id = command.user.id.get() as i64;
|
||||||
|
let guild_id = command.guild_id.unwrap().get() as i64;
|
||||||
|
|
||||||
|
let invoker_db = members::Model::get_by_discord_id(invoker_id, db).await;
|
||||||
|
|
||||||
|
if let Err(e) = invoker_db {
|
||||||
|
return error_msg(Box::new(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
let server_db_id = server::Model::get_by_discord_id(guild_id, "".into(), db).await;
|
||||||
|
|
||||||
|
if let Err(e) = server_db_id {
|
||||||
|
return error_msg(Box::new(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
let invoker_messages = messages::Entity::find()
|
||||||
|
.filter(messages::Column::IdSender.eq(invoker_db.unwrap().unwrap().id))
|
||||||
|
.filter(messages::Column::IdServer.eq(server_db_id.unwrap().unwrap().id))
|
||||||
|
.all(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// TODO error checking here
|
||||||
|
let invoker_messages = invoker_messages.unwrap();
|
||||||
|
let mut map: HashMap<i64, i32> = HashMap::new(); // channel - amount
|
||||||
|
let mut map_channel: HashMap<i32, i64> = 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 as i64);
|
||||||
|
}
|
||||||
|
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!("- <#{}> | {} Messages \n", x.0, x.1).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title("Summary")
|
||||||
|
.description(format!("{}", 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])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use serenity::all::{
|
||||||
|
Color, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse,
|
||||||
|
CreateInteractionResponseMessage,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn error_msg(e: Box<dyn Error>) -> CreateInteractionResponse {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title("Error!")
|
||||||
|
.description("we ran into an error :c")
|
||||||
|
.footer(CreateEmbedFooter::new(format!("{}", e)))
|
||||||
|
.color(Color::RED);
|
||||||
|
let reply =
|
||||||
|
CreateInteractionResponse::Message(CreateInteractionResponseMessage::new().embed(embed));
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
use sea_orm::DatabaseConnection;
|
||||||
|
use serenity::all::{
|
||||||
|
CommandInteraction, Context, CreateCommand, CreateInteractionResponse, InteractionContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Fetch;
|
||||||
|
|
||||||
|
// This is "possible" but with ratelimiting, it'll take a long long long time to rip a medium sized
|
||||||
|
// server
|
||||||
|
|
||||||
|
impl Fetch {
|
||||||
|
pub fn register() -> CreateCommand {
|
||||||
|
CreateCommand::new("retriveChannel")
|
||||||
|
.name("channeldata")
|
||||||
|
.description("description")
|
||||||
|
.contexts(vec![InteractionContext::Guild])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use entities::{channel, content, members, messages, server};
|
||||||
|
use migration::prelude::{DateTime, Utc};
|
||||||
|
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter};
|
||||||
|
use serenity::all::{Context, Message, VoiceState};
|
||||||
|
|
||||||
|
pub async fn log_vc_event(
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
ctx: &Context,
|
||||||
|
vc: VoiceState,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn log_message(
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
ctx: &Context,
|
||||||
|
msg: Message,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
// TODO This is a mess, it should be split into its on function(s)
|
||||||
|
msg.channel(&ctx.http).await.unwrap();
|
||||||
|
|
||||||
|
let content = content::Model::get_or_create(msg.content.clone(), db).await?;
|
||||||
|
|
||||||
|
let member =
|
||||||
|
members::Model::get_or_create(msg.author.id.get().try_into()?, msg.clone().author.name, db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let server_id = msg.guild_id.unwrap().get();
|
||||||
|
let server_id_i32 = server_id.clone() as i64;
|
||||||
|
let guild_name = msg
|
||||||
|
.channel(&ctx.http)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.guild()
|
||||||
|
.unwrap()
|
||||||
|
.name
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let server = server::Model::get_or_create(server_id_i32, guild_name, db).await?;
|
||||||
|
|
||||||
|
let channel_id = msg.channel(&ctx.http).await.unwrap().id().get() as i64;
|
||||||
|
let channel = channel::Model::get_or_create(channel_id, db).await?;
|
||||||
|
|
||||||
|
let timestamp_msg = msg.timestamp.naive_utc();
|
||||||
|
let timestamp: DateTime<Utc> =
|
||||||
|
DateTime::from_timestamp_secs(timestamp_msg.and_utc().timestamp()).unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}, {}, {}, {}, {}, {}",
|
||||||
|
msg.id.get(),
|
||||||
|
member,
|
||||||
|
server,
|
||||||
|
timestamp,
|
||||||
|
content,
|
||||||
|
channel
|
||||||
|
);
|
||||||
|
|
||||||
|
let activeModel = messages::ActiveModel {
|
||||||
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
|
id_discord: sea_orm::ActiveValue::Set(msg.id.get() as i64),
|
||||||
|
timestamp: sea_orm::ActiveValue::Set(timestamp),
|
||||||
|
id_sender: sea_orm::ActiveValue::Set(member),
|
||||||
|
id_server: sea_orm::ActiveValue::Set(server),
|
||||||
|
id_content: sea_orm::ActiveValue::Set(content),
|
||||||
|
id_channel: sea_orm::ActiveValue::Set(channel),
|
||||||
|
};
|
||||||
|
activeModel.insert(db).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
+60
-5
@@ -1,22 +1,74 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
use entities::{channel, content, members, messages, server};
|
||||||
use migration::{Migrator, MigratorTrait};
|
use migration::{Migrator, MigratorTrait};
|
||||||
use sea_orm::{Database, DatabaseConnection};
|
use sea_orm::{
|
||||||
|
ActiveModelTrait, ColumnTrait, Database, DatabaseConnection, EntityTrait, Iden, QueryFilter,
|
||||||
|
};
|
||||||
|
use serenity::all::{Command, Interaction, Ready, VoiceState};
|
||||||
use serenity::async_trait;
|
use serenity::async_trait;
|
||||||
use serenity::model::channel::Message;
|
use serenity::model::channel::Message;
|
||||||
|
use serenity::model::guild;
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
|
|
||||||
struct Handler;
|
use crate::logger::{log_message, log_vc_event};
|
||||||
|
|
||||||
|
mod channelcommand;
|
||||||
|
mod command;
|
||||||
|
mod common;
|
||||||
|
mod fetchcommand;
|
||||||
|
mod logger;
|
||||||
|
|
||||||
|
struct Bot {
|
||||||
|
db: DatabaseConnection,
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventHandler for Handler {
|
impl EventHandler for Bot {
|
||||||
async fn message(&self, ctx: Context, msg: Message) {
|
async fn message(&self, ctx: Context, msg: Message) {
|
||||||
if msg.content == "!ping" {
|
if msg.content == "!ping" {
|
||||||
if let Err(why) = msg.channel_id.say(&ctx.http, "Pong!").await {
|
if let Err(why) = msg.channel_id.say(&ctx.http, "Pong!").await {
|
||||||
println!("Error sending message: {why:?}");
|
println!("Error sending message: {why:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log_message(&self.db, &ctx, msg).await.unwrap();
|
||||||
|
}
|
||||||
|
async fn voice_state_update(&self, ctx: Context, _old: Option<VoiceState>, new: VoiceState) {
|
||||||
|
log_vc_event(&self.db, &ctx, new).await.unwrap();
|
||||||
|
}
|
||||||
|
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||||
|
if let Interaction::Command(command) = interaction {
|
||||||
|
println!("Received command interaction: {command:#?}");
|
||||||
|
|
||||||
|
println!("{:#?}", command.data.name.as_str());
|
||||||
|
|
||||||
|
let content = match command.data.name.as_str() {
|
||||||
|
"userdata" => Some(command::Retrive::run(&self.db, &ctx, &command).await),
|
||||||
|
"channeldata" => {
|
||||||
|
Some(channelcommand::Channelretrive::run(&self.db, &ctx, &command).await)
|
||||||
|
}
|
||||||
|
_ => Some(serenity::all::CreateInteractionResponse::Pong),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("{:#?}", content);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
Command::create_global_command(&ctx.http, command::Retrive::register())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Command::create_global_command(&ctx.http, channelcommand::Channelretrive::register())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,11 +83,14 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
// Set gateway intents, which decides what events the bot will be notified about
|
// Set gateway intents, which decides what events the bot will be notified about
|
||||||
let intents = GatewayIntents::GUILD_MESSAGES
|
let intents = GatewayIntents::GUILD_MESSAGES
|
||||||
| GatewayIntents::DIRECT_MESSAGES
|
| GatewayIntents::DIRECT_MESSAGES
|
||||||
| GatewayIntents::MESSAGE_CONTENT;
|
| GatewayIntents::MESSAGE_CONTENT
|
||||||
|
| GatewayIntents::GUILD_VOICE_STATES;
|
||||||
|
|
||||||
|
let bot = Bot { db: dbc };
|
||||||
|
|
||||||
// Create a new instance of the Client, logging in as a bot.
|
// Create a new instance of the Client, logging in as a bot.
|
||||||
let mut client = Client::builder(&token, intents)
|
let mut client = Client::builder(&token, intents)
|
||||||
.event_handler(Handler)
|
.event_handler(bot)
|
||||||
.await
|
.await
|
||||||
.expect("Err creating client");
|
.expect("Err creating client");
|
||||||
|
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ edition = "2024"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
sea-orm = {workspace = true}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
//! `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: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model {
|
||||||
|
pub async fn get_or_create(id: i64, db: &DatabaseConnection) -> Result<i32, DbErr> {
|
||||||
|
let channel = Entity::find()
|
||||||
|
.filter(Column::IdDiscord.eq(id))
|
||||||
|
.one(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let channel = match channel {
|
||||||
|
Some(x) => x,
|
||||||
|
None => {
|
||||||
|
let activeModel = ActiveModel {
|
||||||
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
|
id_discord: sea_orm::ActiveValue::Set(id as i64),
|
||||||
|
};
|
||||||
|
activeModel.insert(db).await.unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(channel.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::messages::Entity")]
|
||||||
|
Messages,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::messages::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Messages.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
@@ -11,6 +11,30 @@ pub struct Model {
|
|||||||
pub r#type: String,
|
pub r#type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Model {
|
||||||
|
/// Get an entity that has the same content and returns its ID or creates a new entity and
|
||||||
|
/// returns its ID
|
||||||
|
pub async fn get_or_create(content: String, db: &DatabaseConnection) -> Result<i32, DbErr> {
|
||||||
|
let content_db = Entity::find()
|
||||||
|
.filter(Column::Content.eq(&content))
|
||||||
|
.one(db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let content_db = match content_db {
|
||||||
|
Some(x) => x,
|
||||||
|
None => {
|
||||||
|
let activeModel = ActiveModel {
|
||||||
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
|
content: sea_orm::ActiveValue::Set(content),
|
||||||
|
r#type: sea_orm::ActiveValue::Set("".to_string()),
|
||||||
|
};
|
||||||
|
activeModel.insert(db).await.unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(content_db.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
#[sea_orm(has_many = "super::messages::Entity")]
|
#[sea_orm(has_many = "super::messages::Entity")]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
|
pub mod channel;
|
||||||
pub mod content;
|
pub mod content;
|
||||||
pub mod members;
|
pub mod members;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
|
|||||||
@@ -7,10 +7,53 @@ use sea_orm::entity::prelude::*;
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub id_discord: i32,
|
#[sea_orm(unique)]
|
||||||
|
pub id_discord: i64,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Model {
|
||||||
|
pub async fn get_by_discord_id(
|
||||||
|
id: i64,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<Option<Model>, DbErr> {
|
||||||
|
let user_db_id = Entity::find()
|
||||||
|
.filter(Column::IdDiscord.eq(id))
|
||||||
|
.one(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match user_db_id {
|
||||||
|
Ok(x) => match x {
|
||||||
|
Some(x) => Ok(Some(x)),
|
||||||
|
None => Ok(None),
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn get_or_create(
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<i32, DbErr> {
|
||||||
|
let member = Entity::find()
|
||||||
|
.filter(Column::IdDiscord.eq(id))
|
||||||
|
.one(db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match member {
|
||||||
|
Some(x) => Ok(x.id),
|
||||||
|
None => {
|
||||||
|
let activeModel = ActiveModel {
|
||||||
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
|
id_discord: sea_orm::ActiveValue::Set(id),
|
||||||
|
name: sea_orm::ActiveValue::Set(name),
|
||||||
|
};
|
||||||
|
Ok(activeModel.insert(db).await?.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {}
|
pub enum Relation {}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,25 @@ use sea_orm::entity::prelude::*;
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub id_discord: i32,
|
pub timestamp: DateTimeUtc,
|
||||||
|
#[sea_orm(unique)]
|
||||||
|
pub id_discord: i64,
|
||||||
pub id_sender: i32,
|
pub id_sender: i32,
|
||||||
pub id_content: i32,
|
pub id_content: i32,
|
||||||
|
pub id_channel: i32,
|
||||||
pub id_server: i32,
|
pub id_server: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {
|
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(
|
#[sea_orm(
|
||||||
belongs_to = "super::content::Entity",
|
belongs_to = "super::content::Entity",
|
||||||
from = "Column::IdContent",
|
from = "Column::IdContent",
|
||||||
@@ -25,6 +36,12 @@ pub enum Relation {
|
|||||||
Content,
|
Content,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Related<super::channel::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Channel.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Related<super::content::Entity> for Entity {
|
impl Related<super::content::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Content.def()
|
Relation::Content.def()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19
|
//! `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::content::Entity as Content;
|
||||||
pub use super::members::Entity as Members;
|
pub use super::members::Entity as Members;
|
||||||
pub use super::messages::Entity as Messages;
|
pub use super::messages::Entity as Messages;
|
||||||
|
|||||||
@@ -7,10 +7,56 @@ use sea_orm::entity::prelude::*;
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub id_discord: String,
|
#[sea_orm(unique)]
|
||||||
|
pub id_discord: i64,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Model {
|
||||||
|
pub async fn get_by_discord_id(
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<Option<Model>, DbErr> {
|
||||||
|
let server_db_id = Entity::find()
|
||||||
|
.filter(Column::IdDiscord.eq(id))
|
||||||
|
.one(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match server_db_id {
|
||||||
|
Ok(x) => match x {
|
||||||
|
Some(x) => Ok(Some(x)),
|
||||||
|
None => Ok(None),
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn get_or_create(
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<i32, DbErr> {
|
||||||
|
let server_db = Entity::find()
|
||||||
|
.filter(Column::IdDiscord.eq(id))
|
||||||
|
.one(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let reply = match server_db {
|
||||||
|
Some(x) => x.id,
|
||||||
|
None => {
|
||||||
|
let activeModel = ActiveModel {
|
||||||
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
|
name: sea_orm::ActiveValue::Set(name),
|
||||||
|
id_discord: sea_orm::ActiveValue::Set(id),
|
||||||
|
};
|
||||||
|
activeModel.insert(db).await.unwrap().id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(reply)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {}
|
pub enum Relation {}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ mod m20260325_145211_servers;
|
|||||||
mod m20260325_145717_members;
|
mod m20260325_145717_members;
|
||||||
mod m20260325_162920_messages;
|
mod m20260325_162920_messages;
|
||||||
mod m20260325_233947_content;
|
mod m20260325_233947_content;
|
||||||
|
mod m20260327_164915_channels;
|
||||||
|
|
||||||
pub struct Migrator;
|
pub struct Migrator;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ impl MigratorTrait for Migrator {
|
|||||||
Box::new(m20260325_145717_members::Migration),
|
Box::new(m20260325_145717_members::Migration),
|
||||||
Box::new(m20260325_162920_messages::Migration),
|
Box::new(m20260325_162920_messages::Migration),
|
||||||
Box::new(m20260325_233947_content::Migration),
|
Box::new(m20260325_233947_content::Migration),
|
||||||
|
Box::new(m20260327_164915_channels::Migration),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ impl MigrationTrait for Migration {
|
|||||||
.table(Server::Table)
|
.table(Server::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(pk_auto(Server::Id))
|
.col(pk_auto(Server::Id))
|
||||||
.col(string(Server::IdDiscord))
|
.col(big_integer(Server::IdDiscord).unique_key())
|
||||||
.col(string(Server::Name))
|
.col(string(Server::Name))
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ impl MigrationTrait for Migration {
|
|||||||
.table(Members::Table)
|
.table(Members::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(pk_auto(Members::Id))
|
.col(pk_auto(Members::Id))
|
||||||
.col(integer(Members::IdDiscord))
|
.col(big_integer(Members::IdDiscord).unique_key())
|
||||||
.col(string(Members::Name))
|
.col(string(Members::Name))
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use sea_orm_migration::{prelude::*, schema::*};
|
use sea_orm_migration::{prelude::*, schema::*};
|
||||||
|
|
||||||
use crate::m20260325_233947_content::Content;
|
use crate::m20260325_233947_content::Content;
|
||||||
|
use crate::m20260327_164915_channels::{self, Channel};
|
||||||
|
|
||||||
#[derive(DeriveMigrationName)]
|
#[derive(DeriveMigrationName)]
|
||||||
pub struct Migration;
|
pub struct Migration;
|
||||||
@@ -14,14 +15,21 @@ impl MigrationTrait for Migration {
|
|||||||
.table(Messages::Table)
|
.table(Messages::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(pk_auto(Messages::Id))
|
.col(pk_auto(Messages::Id))
|
||||||
.col(integer(Messages::IdDiscord))
|
.col(big_integer(Messages::IdDiscord))
|
||||||
.col(integer(Messages::IdSender))
|
.col(integer(Messages::IdSender))
|
||||||
.col(integer(Messages::IdContent))
|
.col(integer(Messages::IdContent))
|
||||||
|
.col(timestamp(Messages::Timestamp))
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.from(Messages::Table, Messages::IdContent)
|
.from(Messages::Table, Messages::IdContent)
|
||||||
.to(Content::Table, Content::Id),
|
.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))
|
.col(integer(Messages::IdServer))
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
)
|
)
|
||||||
@@ -39,8 +47,10 @@ impl MigrationTrait for Migration {
|
|||||||
enum Messages {
|
enum Messages {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
|
Timestamp,
|
||||||
IdDiscord,
|
IdDiscord,
|
||||||
IdSender,
|
IdSender,
|
||||||
IdContent,
|
IdContent,
|
||||||
|
IdChannel,
|
||||||
IdServer,
|
IdServer,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(big_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,
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Id
|
||||||
|
Id_User
|
||||||
|
Event
|
||||||
|
Timestamp
|
||||||
|
|
||||||
|
enum event :
|
||||||
|
- Joined Vc
|
||||||
|
- Left Vc
|
||||||
|
- Started Screenshare
|
||||||
|
- Stopped Screenshare
|
||||||
|
- Muted
|
||||||
|
- Unmuted
|
||||||
|
- Deafened
|
||||||
|
- Undeafened
|
||||||
Reference in New Issue
Block a user