Working on database
This commit is contained in:
parent
dd33bc8f81
commit
90dadc92d6
|
@ -4,4 +4,5 @@
|
||||||
Conf.toml
|
Conf.toml
|
||||||
/data
|
/data
|
||||||
/log
|
/log
|
||||||
join_audio.mp3
|
*.mp3
|
||||||
|
.env
|
|
@ -29,9 +29,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.38"
|
version = "1.0.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arc-swap"
|
name = "arc-swap"
|
||||||
|
@ -91,6 +91,17 @@ dependencies = [
|
||||||
"webpki-roots 0.21.0",
|
"webpki-roots 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "audiopus"
|
name = "audiopus"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -300,6 +311,39 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diesel"
|
||||||
|
version = "1.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"diesel_derives",
|
||||||
|
"pq-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diesel_derives"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diesel_migrations"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c"
|
||||||
|
dependencies = [
|
||||||
|
"migrations_internals",
|
||||||
|
"migrations_macros",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -343,6 +387,19 @@ dependencies = [
|
||||||
"num-traits 0.1.43",
|
"num-traits 0.1.43",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
|
@ -827,6 +884,27 @@ version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "migrations_internals"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860"
|
||||||
|
dependencies = [
|
||||||
|
"diesel",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "migrations_macros"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c"
|
||||||
|
dependencies = [
|
||||||
|
"migrations_internals",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
@ -1135,6 +1213,15 @@ version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pq-sys"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
|
||||||
|
dependencies = [
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.5.19"
|
version = "0.5.19"
|
||||||
|
@ -1361,14 +1448,34 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
|
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusty-bot-convert-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"diesel",
|
||||||
|
"env_logger",
|
||||||
|
"log",
|
||||||
|
"rusty-bot-database",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusty-bot-database"
|
name = "rusty-bot-database"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"diesel",
|
||||||
|
"diesel_migrations",
|
||||||
|
"log",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusty_bot"
|
name = "rusty_bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
|
@ -1378,6 +1485,7 @@ dependencies = [
|
||||||
"log4rs",
|
"log4rs",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rusty-bot-database",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serenity",
|
"serenity",
|
||||||
|
@ -1738,19 +1846,28 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "termcolor"
|
||||||
version = "1.0.24"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.24"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2239,6 +2356,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"rusty-bot",
|
"rusty-bot",
|
||||||
"rusty-bot-database"
|
"rusty-bot-database",
|
||||||
|
"rusty-bot-convert-data"
|
||||||
]
|
]
|
|
@ -12,3 +12,5 @@ root:
|
||||||
loggers:
|
loggers:
|
||||||
rusty_bot:
|
rusty_bot:
|
||||||
level: trace
|
level: trace
|
||||||
|
rusty_bot_database:
|
||||||
|
level: trace
|
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "rusty-bot-convert-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
rusty-bot-database = { path = "../rusty-bot-database" }
|
||||||
|
log = "0.4.14"
|
||||||
|
env_logger = "0.9.0"
|
||||||
|
diesel = { version = "1.4", features = ["postgres"] }
|
|
@ -0,0 +1,64 @@
|
||||||
|
use std::{env::args, path::Path};
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
|
use diesel::{query_builder::AsQuery, RunQueryDsl};
|
||||||
|
use env_logger::Env;
|
||||||
|
use rusty_bot_database::{establish_connection, models::NewSettings};
|
||||||
|
|
||||||
|
mod models;
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||||
|
|
||||||
|
let mut args = args().skip(1);
|
||||||
|
|
||||||
|
let data_path = args.next().expect("missing data path");
|
||||||
|
let data_path = Path::new(&data_path);
|
||||||
|
let database_url = args.next().expect("missing database url");
|
||||||
|
|
||||||
|
let conn = establish_connection(&database_url)?;
|
||||||
|
|
||||||
|
let guild_options_path = data_path.join("guilds_options");
|
||||||
|
for entry in std::fs::read_dir(&guild_options_path)
|
||||||
|
.with_context(move || format!("failed to open {:?}", guild_options_path))?
|
||||||
|
.filter_map(|e| e.ok())
|
||||||
|
{
|
||||||
|
match serde_json::from_reader::<std::fs::File, models::GuildOptions>(std::fs::File::open(
|
||||||
|
entry.path(),
|
||||||
|
)?) {
|
||||||
|
Ok(options) => {
|
||||||
|
let id = entry
|
||||||
|
.file_name()
|
||||||
|
.to_string_lossy()
|
||||||
|
.split('.')
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.parse::<u64>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let new_settings = NewSettings::new(
|
||||||
|
id,
|
||||||
|
options.mute_id,
|
||||||
|
Some(options.roulette_options.kick_enabled),
|
||||||
|
options.mention_log_channel,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Err(e) = diesel::insert_into(rusty_bot_database::schema::settings::table)
|
||||||
|
.values(&new_settings)
|
||||||
|
.as_query()
|
||||||
|
.execute(&conn)
|
||||||
|
.context("failed to instart data")
|
||||||
|
{
|
||||||
|
println!("{:?}", e);
|
||||||
|
} else {
|
||||||
|
log::info!("inserted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("While parsing guild option {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct GuildOptions {
|
||||||
|
pub(crate) mute_id: Option<u64>,
|
||||||
|
pub(crate) mention_log_channel: Option<u64>,
|
||||||
|
pub(crate) roulette_options: RouletteOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct RouletteOptions {
|
||||||
|
pub(crate) kick_enabled: bool,
|
||||||
|
}
|
|
@ -6,3 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
diesel = { version = "1.4", features = ["postgres"] }
|
||||||
|
thiserror = "1.0"
|
||||||
|
log = "0.4"
|
||||||
|
diesel_migrations = "1.4"
|
|
@ -0,0 +1,5 @@
|
||||||
|
# RustyBot Database
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
![Screenshot](schema/database.svg)
|
|
@ -0,0 +1,5 @@
|
||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/schema.rs"
|
|
@ -0,0 +1,6 @@
|
||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||||
|
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
|
@ -0,0 +1,36 @@
|
||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Sets up a trigger for the given table to automatically set a column called
|
||||||
|
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||||
|
-- in the modified columns)
|
||||||
|
--
|
||||||
|
-- # Example
|
||||||
|
--
|
||||||
|
-- ```sql
|
||||||
|
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||||
|
--
|
||||||
|
-- SELECT diesel_manage_updated_at('users');
|
||||||
|
-- ```
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||||
|
BEGIN
|
||||||
|
IF (
|
||||||
|
NEW IS DISTINCT FROM OLD AND
|
||||||
|
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||||
|
) THEN
|
||||||
|
NEW.updated_at := current_timestamp;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
|
@ -0,0 +1,13 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
|
||||||
|
drop table if exists music_info;
|
||||||
|
|
||||||
|
drop table if exists music_session_list;
|
||||||
|
|
||||||
|
drop table if exists music;
|
||||||
|
|
||||||
|
drop table if exists music_session;
|
||||||
|
|
||||||
|
drop table if exists settings;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
CREATE TABLE MUSIC
|
||||||
|
(
|
||||||
|
musicID SERIAL NOT NULL,
|
||||||
|
musicSourceURL TEXT NOT NULL,
|
||||||
|
musicUserRequesterID BIGINT NOT NULL, -- TO BE TRANSMUTED TO U64 ?
|
||||||
|
PRIMARY KEY (musicid)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MUSIC_INFO
|
||||||
|
(
|
||||||
|
musicInfoSourceURL TEXT NOT NULL,
|
||||||
|
musicInfoTitle TEXT NOT NULL,
|
||||||
|
musicInfoThumbnailURL TEXT,
|
||||||
|
musicInfoLength INTEGER NOT NULL,
|
||||||
|
musicInfoMusicID INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (musicInfoSourceURL)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MUSIC_SESSION
|
||||||
|
(
|
||||||
|
musicSessionID SERIAL NOT NULL,
|
||||||
|
musicSessionCurrentPlayingIndex SMALLINT DEFAULT 0, -- START FROM 0
|
||||||
|
musicSessionGuildID BIGINT NOT NULL,
|
||||||
|
musicSessionTextChannelID BIGINT NOT NULL,
|
||||||
|
musicSessionPlayingChannelID BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY (musicsessionid)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MUSIC_SESSION_LIST
|
||||||
|
(
|
||||||
|
musicSessionID INTEGER NOT NULL,
|
||||||
|
musicID INTEGER NOT NULL,
|
||||||
|
musicSessionListIndex SMALLINT NOT NULL,
|
||||||
|
PRIMARY KEY (musicSessionID, musicID, musicSessionListIndex)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE SETTINGS
|
||||||
|
(
|
||||||
|
settingsGuildID BIGINT NOT NULL,
|
||||||
|
settingsMuteRoleID BIGINT,
|
||||||
|
settingsRouletteKickEnabled BOOLEAN DEFAULT FALSE,
|
||||||
|
settingsLogChannelID BIGINT,
|
||||||
|
PRIMARY KEY (settingsGuildID)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE MUSIC_INFO
|
||||||
|
ADD FOREIGN KEY (musicInfoMusicID) REFERENCES MUSIC (musicID);
|
||||||
|
|
||||||
|
ALTER TABLE MUSIC_SESSION_LIST
|
||||||
|
ADD FOREIGN KEY (musicID) REFERENCES MUSIC (musicID);
|
||||||
|
|
||||||
|
ALTER TABLE MUSIC_SESSION_LIST
|
||||||
|
ADD FOREIGN KEY (musicSessionID) REFERENCES MUSIC_SESSION (musicSessionID);
|
|
@ -0,0 +1,244 @@
|
||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="911" height="346" view_box="0 0 911 346" xmlns="http://www.w3.org/2000/svg" xmlns:link="http://www.w3.org/1999/xlink">
|
||||||
|
\n\n
|
||||||
|
<desc>Généré par Mocodo 2.3.7 le Tue, 15 Mar 2022 13:53:31</desc>
|
||||||
|
|
||||||
|
<rect id="frame" x="0" y="0" width="911" height="346" fill="#f5f5f5" stroke="none" stroke-width="0" />
|
||||||
|
|
||||||
|
<!-- Association PLAYING_ON_MUSIC_SESSION -->
|
||||||
|
<line x1="280" y1="127" x2="280" y2="43" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="285.0" y="85" fill="#01665e" font-family="Verdana" font-size="12">0,N</text>
|
||||||
|
<line x1="481" y1="43" x2="280" y2="43" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="389" y="60.0" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<path d="M 415.0 43.0 L 403.0 49.0 L 407.0 43.0 L 403.0 37.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<g id="association-PLAYING_ON_MUSIC_SESSION">
|
||||||
|
<path d="M 369 18 a 14 14 90 0 1 14 14 V 43 h -206 V 32 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 383 43.0 v 11 a 14 14 90 0 1 -14 14 H 191 a 14 14 90 0 1 -14 -14 V 43.0 H 206" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="177" y="18" width="206" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="177" y1="43" x2="383" y2="43" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="184" y="35.7" fill="#000000" font-family="Verdana" font-size="12">PLAYING_ON_MUSIC_SESSION</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association LOG_CHANNEL -->
|
||||||
|
<line x1="836" y1="43" x2="836" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="841.0" y="85" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<path d="M 836.0 68.0 L 842.0 80.0 L 836.0 76.0 L 830.0 80.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<line x1="836" y1="228" x2="836" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="841.0" y="186" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<g id="association-LOG_CHANNEL">
|
||||||
|
<path d="M 875 102 a 14 14 90 0 1 14 14 V 127 h -106 V 116 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 889 127.0 v 11 a 14 14 90 0 1 -14 14 H 797 a 14 14 90 0 1 -14 -14 V 127.0 H 106" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="783" y="102" width="106" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="783" y1="127" x2="889" y2="127" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="790" y="119.7" fill="#000000" font-family="Verdana" font-size="12">LOG_CHANNEL</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association TEXT_CHANNEL -->
|
||||||
|
<line x1="836" y1="43" x2="664" y2="43" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="774" y="35.0" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<path d="M 800.0 43.0 L 788.0 49.0 L 792.0 43.0 L 788.0 37.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<line x1="481" y1="43" x2="664" y2="43" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="552" y="35.0" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<g id="association-TEXT_CHANNEL">
|
||||||
|
<path d="M 706 18 a 14 14 90 0 1 14 14 V 43 h -112 V 32 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 720 43.0 v 11 a 14 14 90 0 1 -14 14 H 622 a 14 14 90 0 1 -14 -14 V 43.0 H 112" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="608" y="18" width="112" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="608" y1="43" x2="720" y2="43" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="615" y="35.7" fill="#000000" font-family="Verdana" font-size="12">TEXT_CHANNEL</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association MUSIC_METADATAS -->
|
||||||
|
<line x1="90" y1="228" x2="280" y2="228" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="162" y="245.0" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<path d="M 157.0 228.0 L 169.0 222.0 L 165.0 228.0 L 169.0 234.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<line x1="280" y1="127" x2="280" y2="228" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="285.0" y="178" fill="#01665e" font-family="Verdana" font-size="12">0,N</text>
|
||||||
|
<g id="association-MUSIC_METADATAS">
|
||||||
|
<path d="M 335 203 a 14 14 90 0 1 14 14 V 228 h -138 V 217 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 349 228.0 v 11 a 14 14 90 0 1 -14 14 H 225 a 14 14 90 0 1 -14 -14 V 228.0 H 138" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="211" y="203" width="138" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="211" y1="228" x2="349" y2="228" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="218" y="220.7" fill="#000000" font-family="Verdana" font-size="12">MUSIC_METADATAS</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association MUSIC_REQUESTED_BY -->
|
||||||
|
<line x1="90" y1="43" x2="90" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="95.0" y="85" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<path d="M 90.0 68.0 L 96.0 80.0 L 90.0 76.0 L 84.0 80.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<line x1="280" y1="127" x2="90" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="197" y="144.0" fill="#01665e" font-family="Verdana" font-size="12">0,N</text>
|
||||||
|
<g id="association-MUSIC_REQUESTED_BY">
|
||||||
|
<path d="M 157 102 a 14 14 90 0 1 14 14 V 127 h -162 V 116 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 171 127.0 v 11 a 14 14 90 0 1 -14 14 H 23 a 14 14 90 0 1 -14 -14 V 127.0 H 162" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="9" y="102" width="162" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="9" y1="127" x2="171" y2="127" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="16" y="119.7" fill="#000000" font-family="Verdana" font-size="12">MUSIC_REQUESTED_BY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association SETTINGS_OF_GUILD -->
|
||||||
|
<line x1="836" y1="228" x2="664" y2="228" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="744" y="245.0" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<line x1="481" y1="228" x2="664" y2="228" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="513" y="245.0" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<path d="M 508.0 228.0 L 520.0 222.0 L 516.0 228.0 L 520.0 234.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<g id="association-SETTINGS_OF_GUILD">
|
||||||
|
<path d="M 724 203 a 14 14 90 0 1 14 14 V 228 h -148 V 217 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 738 228.0 v 11 a 14 14 90 0 1 -14 14 H 604 a 14 14 90 0 1 -14 -14 V 228.0 H 148" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="590" y="203" width="148" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="590" y1="228" x2="738" y2="228" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="597" y="220.7" fill="#000000" font-family="Verdana" font-size="12">SETTINGS_OF_GUILD</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association PLAYING_ON_GUILD -->
|
||||||
|
<line x1="481" y1="43" x2="481" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="455.0" y="94" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<line x1="481" y1="228" x2="481" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="486.0" y="195" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<path d="M 481.0 203.0 L 475.0 191.0 L 481.0 195.0 L 487.0 191.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<g id="association-PLAYING_ON_GUILD">
|
||||||
|
<path d="M 538 102 a 14 14 90 0 1 14 14 V 127 h -142 V 116 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 552 127.0 v 11 a 14 14 90 0 1 -14 14 H 424 a 14 14 90 0 1 -14 -14 V 127.0 H 142" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="410" y="102" width="142" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="410" y1="127" x2="552" y2="127" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="417" y="119.7" fill="#000000" font-family="Verdana" font-size="12">PLAYING_ON_GUILD</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association PLAYING_ON_CHANNEL -->
|
||||||
|
<line x1="481" y1="43" x2="664" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="552" y="68.8895407756" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<line x1="836" y1="43" x2="664" y2="127" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="774" y="56.401628839" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<path d="M 800.0 60.5813953488 L 791.850201599 71.2388240268 L 792.811459872 64.0920777369 L 786.584178017 60.456013835 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<g id="association-PLAYING_ON_CHANNEL">
|
||||||
|
<path d="M 730 102 a 14 14 90 0 1 14 14 V 127 h -160 V 116 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 744 127.0 v 11 a 14 14 90 0 1 -14 14 H 598 a 14 14 90 0 1 -14 -14 V 127.0 H 160" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="584" y="102" width="160" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="584" y1="127" x2="744" y2="127" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="591" y="119.7" fill="#000000" font-family="Verdana" font-size="12">PLAYING_ON_CHANNEL</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Association MUTE_ROLE -->
|
||||||
|
<line x1="836" y1="228" x2="836" y2="312" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="841.0" y="279" fill="#01665e" font-family="Verdana" font-size="12">1,1</text>
|
||||||
|
<line x1="664" y1="312" x2="836" y2="312" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<text x="693" y="329.0" fill="#01665e" font-family="Verdana" font-size="12">0,1</text>
|
||||||
|
<path d="M 688.0 312.0 L 700.0 306.0 L 696.0 312.0 L 700.0 318.0 Z" fill="#bf812d" stroke-width="0" />
|
||||||
|
<g id="association-MUTE_ROLE">
|
||||||
|
<path d="M 867 287 a 14 14 90 0 1 14 14 V 312 h -90 V 301 a 14 14 90 0 1 14 -14" fill="#dfc27d" stroke="#dfc27d" stroke-width="0" />
|
||||||
|
<path d="M 881 312.0 v 11 a 14 14 90 0 1 -14 14 H 805 a 14 14 90 0 1 -14 -14 V 312.0 H 90" fill="#f6e8c3" stroke="#f6e8c3" stroke-width="0" />
|
||||||
|
<rect x="791" y="287" width="90" height="50" fill="none" rx="14" stroke="#bf812d" stroke-width="2" />
|
||||||
|
<line x1="791" y1="312" x2="881" y2="312" stroke="#bf812d" stroke-width="1" />
|
||||||
|
<text x="798" y="304.7" fill="#000000" font-family="Verdana" font-size="12">MUTE_ROLE</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity GUILD -->
|
||||||
|
<g id="entity-GUILD">
|
||||||
|
<g id="frame-GUILD">
|
||||||
|
<rect x="454" y="203" width="54" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="454" y="228.0" width="54" height="25" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="454" y="203" width="54" height="50" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="454" y1="228" x2="508" y2="228" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="461" y="220.7" fill="#000000" font-family="Verdana" font-size="12">GUILD</text>
|
||||||
|
<text x="459" y="245.8" fill="#000000" font-family="Verdana" font-size="12">guildID</text>
|
||||||
|
<line x1="459" y1="248" x2="503" y2="248" stroke="#000000" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity SETTINGS -->
|
||||||
|
<g id="entity-SETTINGS">
|
||||||
|
<g id="frame-SETTINGS">
|
||||||
|
<rect x="770" y="194" width="132" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="770" y="219.0" width="132" height="43" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="770" y="194" width="132" height="68" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="770" y1="219" x2="902" y2="219" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="804" y="211.7" fill="#000000" font-family="Verdana" font-size="12">SETTINGS</text>
|
||||||
|
<text x="775" y="236.8" fill="#000000" font-family="Verdana" font-size="12">settingsID</text>
|
||||||
|
<line x1="775" y1="239" x2="838" y2="239" stroke="#000000" stroke-width="1" />
|
||||||
|
<text x="775" y="253.8" fill="#000000" font-family="Verdana" font-size="12">rouletteKickEnabled</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity DISCORD_USER -->
|
||||||
|
<g id="entity-DISCORD_USER">
|
||||||
|
<g id="frame-DISCORD_USER">
|
||||||
|
<rect x="35" y="18" width="110" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="35" y="43.0" width="110" height="25" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="35" y="18" width="110" height="50" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="35" y1="43" x2="145" y2="43" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="40" y="35.7" fill="#000000" font-family="Verdana" font-size="12">DISCORD_USER</text>
|
||||||
|
<text x="40" y="60.8" fill="#000000" font-family="Verdana" font-size="12">userId</text>
|
||||||
|
<line x1="40" y1="63" x2="80" y2="63" stroke="#000000" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity MUSIC_INFO -->
|
||||||
|
<g id="entity-MUSIC_INFO">
|
||||||
|
<g id="frame-MUSIC_INFO">
|
||||||
|
<rect x="23" y="177" width="134" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="23" y="202.0" width="134" height="77" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="23" y="177" width="134" height="102" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="23" y1="202" x2="157" y2="202" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="50" y="194.7" fill="#000000" font-family="Verdana" font-size="12">MUSIC_INFO</text>
|
||||||
|
<text x="28" y="219.7" fill="#000000" font-family="Verdana" font-size="12">musicSourceURL</text>
|
||||||
|
<line x1="28" y1="222" x2="129" y2="222" stroke="#000000" stroke-width="1" />
|
||||||
|
<text x="28" y="236.8" fill="#000000" font-family="Verdana" font-size="12">musicTitle</text>
|
||||||
|
<text x="28" y="253.8" fill="#000000" font-family="Verdana" font-size="12">musicThumbnailURL</text>
|
||||||
|
<text x="28" y="270.8" fill="#000000" font-family="Verdana" font-size="12">musicLength</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity MUSIC -->
|
||||||
|
<g id="entity-MUSIC">
|
||||||
|
<g id="frame-MUSIC">
|
||||||
|
<rect x="224" y="93" width="112" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="224" y="118.0" width="112" height="43" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="224" y="93" width="112" height="68" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="224" y1="118" x2="336" y2="118" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="259" y="110.7" fill="#000000" font-family="Verdana" font-size="12">MUSIC</text>
|
||||||
|
<text x="229" y="135.8" fill="#000000" font-family="Verdana" font-size="12">musicID</text>
|
||||||
|
<line x1="229" y1="138" x2="279" y2="138" stroke="#000000" stroke-width="1" />
|
||||||
|
<text x="229" y="152.8" fill="#000000" font-family="Verdana" font-size="12">musicSourceURL</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity ROLE -->
|
||||||
|
<g id="entity-ROLE">
|
||||||
|
<g id="frame-ROLE">
|
||||||
|
<rect x="640" y="287" width="48" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="640" y="312.0" width="48" height="25" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="640" y="287" width="48" height="50" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="640" y1="312" x2="688" y2="312" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="647" y="304.7" fill="#000000" font-family="Verdana" font-size="12">ROLE</text>
|
||||||
|
<text x="645" y="329.8" fill="#000000" font-family="Verdana" font-size="12">roleID</text>
|
||||||
|
<line x1="645" y1="332" x2="683" y2="332" stroke="#000000" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity MUSIC_SESSION -->
|
||||||
|
<g id="entity-MUSIC_SESSION">
|
||||||
|
<g id="frame-MUSIC_SESSION">
|
||||||
|
<rect x="415" y="9" width="132" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="415" y="34.0" width="132" height="43" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="415" y="9" width="132" height="68" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="415" y1="34" x2="547" y2="34" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="428" y="26.7" fill="#000000" font-family="Verdana" font-size="12">MUSIC_SESSION</text>
|
||||||
|
<text x="420" y="51.8" fill="#000000" font-family="Verdana" font-size="12">musicSessionID</text>
|
||||||
|
<line x1="420" y1="54" x2="516" y2="54" stroke="#000000" stroke-width="1" />
|
||||||
|
<text x="420" y="68.8" fill="#000000" font-family="Verdana" font-size="12">currentPlayingIndex</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Entity CHANNEL -->
|
||||||
|
<g id="entity-CHANNEL">
|
||||||
|
<g id="frame-CHANNEL">
|
||||||
|
<rect x="800" y="18" width="72" height="25" fill="#80cdc1" stroke="#80cdc1" stroke-width="0" />
|
||||||
|
<rect x="800" y="43.0" width="72" height="25" fill="#c7eae5" stroke="#c7eae5" stroke-width="0" />
|
||||||
|
<rect x="800" y="18" width="72" height="50" fill="none" stroke="#35978f" stroke-width="2" />
|
||||||
|
<line x1="800" y1="43" x2="872" y2="43" stroke="#35978f" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
<text x="806" y="35.7" fill="#000000" font-family="Verdana" font-size="12">CHANNEL</text>
|
||||||
|
<text x="805" y="60.8" fill="#000000" font-family="Verdana" font-size="12">channelID</text>
|
||||||
|
<line x1="805" y1="63" x2="867" y2="63" stroke="#000000" stroke-width="1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,21 @@
|
||||||
|
DISCORD_USER: userId
|
||||||
|
PLAYING_ON_MUSIC_SESSION, 0N MUSIC, 01> MUSIC_SESSION
|
||||||
|
MUSIC_SESSION: musicSessionID, currentPlayingIndex
|
||||||
|
TEXT_CHANNEL, 11> CHANNEL, 01 MUSIC_SESSION
|
||||||
|
CHANNEL: channelID
|
||||||
|
|
||||||
|
MUSIC_REQUESTED_BY, 11> DISCORD_USER, 0N MUSIC
|
||||||
|
MUSIC: musicID, musicSourceURL
|
||||||
|
PLAYING_ON_GUILD, 01 MUSIC_SESSION, 11> GUILD
|
||||||
|
PLAYING_ON_CHANNEL, 01 MUSIC_SESSION, 11> CHANNEL
|
||||||
|
LOG_CHANNEL, 01> CHANNEL, 11 SETTINGS
|
||||||
|
|
||||||
|
MUSIC_INFO: musicSourceURL, musicTitle, musicThumbnailURL, musicLength
|
||||||
|
MUSIC_METADATAS, 01> MUSIC_INFO, 0N MUSIC
|
||||||
|
GUILD: guildID
|
||||||
|
SETTINGS_OF_GUILD, 01 SETTINGS, 11> GUILD
|
||||||
|
SETTINGS: settingsID, rouletteKickEnabled
|
||||||
|
|
||||||
|
:::
|
||||||
|
ROLE: roleID
|
||||||
|
MUTE_ROLE, 11 SETTINGS, 01> ROLE
|
|
@ -0,0 +1,23 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Failed to fetch")]
|
||||||
|
Database(#[from] diesel::result::Error),
|
||||||
|
#[error("Failed to connect to db")]
|
||||||
|
Connection(#[from] diesel::result::ConnectionError),
|
||||||
|
#[error("Failed to run migrations")]
|
||||||
|
Migrations(#[from] diesel_migrations::RunMigrationsError)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn is_not_found_error(&self) -> bool {
|
||||||
|
if let Error::Database(e) = self {
|
||||||
|
e == &diesel::result::Error::NotFound
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
@ -1 +1,24 @@
|
||||||
// KEEP
|
#[macro_use]
|
||||||
|
pub extern crate diesel;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate diesel_migrations;
|
||||||
|
|
||||||
|
use diesel::prelude::*;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
|
pub mod models;
|
||||||
|
pub mod queries;
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
|
use error::*;
|
||||||
|
|
||||||
|
diesel_migrations::embed_migrations!();
|
||||||
|
|
||||||
|
pub fn establish_connection(database_url: &str) -> Result<PgConnection> {
|
||||||
|
let conn = PgConnection::establish(&database_url)?;
|
||||||
|
|
||||||
|
embedded_migrations::run(&conn)?;
|
||||||
|
|
||||||
|
Ok(conn)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct Music {
|
||||||
|
pub id: i32,
|
||||||
|
pub music_source_url: String,
|
||||||
|
pub music_requester_id: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct MusicInfo {
|
||||||
|
pub source_url: String,
|
||||||
|
pub info_title: Option<String>,
|
||||||
|
pub thumbnail_url: Option<String>,
|
||||||
|
pub length: i32,
|
||||||
|
pub music_id: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO FIX SCHEMA DIR
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct MusicSession {
|
||||||
|
pub id: i32,
|
||||||
|
pub current_playing_index: Option<i16>,
|
||||||
|
pub guild_id: i64,
|
||||||
|
pub text_channel_id: i64,
|
||||||
|
pub playing_channel_id: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct MusicSessionList {
|
||||||
|
pub session_id: i32,
|
||||||
|
pub music_id: i32,
|
||||||
|
pub index: i16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct Settings {
|
||||||
|
pub guild_id: i64,
|
||||||
|
pub mute_role_id: Option<i64>,
|
||||||
|
pub roulette_kick_enabled: Option<bool>,
|
||||||
|
pub log_channel_id: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
|
pub fn get_mute_role_id(&self) -> Option<u64> {
|
||||||
|
self.mute_role_id
|
||||||
|
.map(|id| unsafe { std::mem::transmute(id) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use super::schema::settings;
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[table_name = "settings"]
|
||||||
|
pub struct NewSettings {
|
||||||
|
#[column_name = "settingsguildid"]
|
||||||
|
pub guild_id: i64,
|
||||||
|
#[column_name = "settingsmuteroleid"]
|
||||||
|
pub mute_role_id: Option<i64>,
|
||||||
|
#[column_name = "settingsroulettekickenabled"]
|
||||||
|
pub roulette_kick_enabled: Option<bool>,
|
||||||
|
#[column_name = "settingslogchannelid"]
|
||||||
|
pub log_channel_id: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NewSettings {
|
||||||
|
pub fn new(
|
||||||
|
guild_id: u64,
|
||||||
|
mute_role_id: Option<u64>,
|
||||||
|
roulette_kick_enabled: Option<bool>,
|
||||||
|
log_channel_id: Option<u64>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
guild_id: unsafe { std::mem::transmute(guild_id) },
|
||||||
|
mute_role_id: mute_role_id.map(|f| unsafe { std::mem::transmute(f) }),
|
||||||
|
roulette_kick_enabled,
|
||||||
|
log_channel_id: log_channel_id.map(|f| unsafe { std::mem::transmute(f) }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::{QueryDsl, RunQueryDsl};
|
||||||
|
|
||||||
|
use crate::models::{NewSettings, Settings};
|
||||||
|
use crate::schema;
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
|
pub trait RustyConnectionExt {
|
||||||
|
fn fetch_settings(&self, guild_id: u64) -> Result<Settings>;
|
||||||
|
fn settings_edit_kick(&self, guild_id: u64, disable: bool) -> Result<()>;
|
||||||
|
fn settings_fetch_mute_role(&self, guild_id: u64) -> Result<Option<u64>>;
|
||||||
|
fn settings_edit_mute_role(&self, guild_id: u64, mute_role: Option<u64>) -> Result<()>;
|
||||||
|
fn settings_fetch_log_channel(&self, guild_id: u64) -> Result<Option<u64>>;
|
||||||
|
fn settings_edit_log_channel(&self, guild_id: u64, channel: Option<u64>) -> Result<()>;
|
||||||
|
fn insert_settings(&self, settings: NewSettings) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RustyConnectionExt for PgConnection {
|
||||||
|
fn fetch_settings(&self, guild_id: u64) -> Result<Settings> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id = unsafe { std::mem::transmute::<u64, i64>(guild_id) };
|
||||||
|
|
||||||
|
let res = settings
|
||||||
|
.filter(settingsguildid.eq(id))
|
||||||
|
.first::<Settings>(self)?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_edit_kick(&self, guild_id: u64, disable: bool) -> Result<()> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id = unsafe { std::mem::transmute::<u64, i64>(guild_id) };
|
||||||
|
|
||||||
|
if diesel::update(settings)
|
||||||
|
.set(settingsroulettekickenabled.eq(!disable))
|
||||||
|
.filter(settingsguildid.eq(id))
|
||||||
|
.execute(self)?
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
log::error!("inserting");
|
||||||
|
diesel::insert_into(super::schema::settings::table)
|
||||||
|
.values(&NewSettings::new(guild_id, None, Some(!disable), None))
|
||||||
|
.execute(self)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_edit_mute_role(&self, guild_id: u64, mute_role: Option<u64>) -> Result<()> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id = unsafe { std::mem::transmute::<u64, i64>(guild_id) };
|
||||||
|
let mute_role = mute_role.map(|id| unsafe { std::mem::transmute::<u64, i64>(id) });
|
||||||
|
|
||||||
|
if diesel::update(settings)
|
||||||
|
.set(settingsmuteroleid.eq(mute_role))
|
||||||
|
.filter(settingsguildid.eq(id))
|
||||||
|
.execute(self)?
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
diesel::insert_into(super::schema::settings::table)
|
||||||
|
.values(&NewSettings {
|
||||||
|
guild_id: id,
|
||||||
|
mute_role_id: mute_role,
|
||||||
|
roulette_kick_enabled: None,
|
||||||
|
log_channel_id: None,
|
||||||
|
})
|
||||||
|
.execute(self)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_fetch_mute_role(&self, guild_id: u64) -> Result<Option<u64>> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id: QueryResult<Option<i64>> = settings
|
||||||
|
.select(settingsmuteroleid)
|
||||||
|
.filter(settingsguildid.eq(unsafe { std::mem::transmute::<u64, i64>(guild_id) }))
|
||||||
|
.get_result(self);
|
||||||
|
|
||||||
|
if id == Err(diesel::result::Error::NotFound) {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
let id = id?;
|
||||||
|
Ok(id.map(|id| unsafe { std::mem::transmute(id) }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_fetch_log_channel(&self, guild_id: u64) -> Result<Option<u64>> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id: QueryResult<Option<i64>> = settings
|
||||||
|
.select(settingslogchannelid)
|
||||||
|
.filter(settingsguildid.eq(unsafe { std::mem::transmute::<u64, i64>(guild_id) }))
|
||||||
|
.get_result(self);
|
||||||
|
|
||||||
|
if id == Err(diesel::result::Error::NotFound) {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
let id = id?;
|
||||||
|
Ok(id.map(|id| unsafe { std::mem::transmute(id) }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_edit_log_channel(&self, guild_id: u64, channel: Option<u64>) -> Result<()> {
|
||||||
|
use schema::settings::dsl::*;
|
||||||
|
|
||||||
|
let id = unsafe { std::mem::transmute::<u64, i64>(guild_id) };
|
||||||
|
let channel = channel.map(|id| unsafe { std::mem::transmute::<u64, i64>(id) });
|
||||||
|
|
||||||
|
if diesel::update(settings)
|
||||||
|
.set(settingslogchannelid.eq(channel))
|
||||||
|
.filter(settingsguildid.eq(id))
|
||||||
|
.execute(self)?
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
diesel::insert_into(super::schema::settings::table)
|
||||||
|
.values(&NewSettings {
|
||||||
|
guild_id: id,
|
||||||
|
mute_role_id: None,
|
||||||
|
roulette_kick_enabled: None,
|
||||||
|
log_channel_id: channel,
|
||||||
|
})
|
||||||
|
.execute(self)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_settings(&self, settings: NewSettings) -> Result<()> {
|
||||||
|
diesel::insert_into(super::schema::settings::table)
|
||||||
|
.values(&settings)
|
||||||
|
.execute(self)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
table! {
|
||||||
|
music (musicid) {
|
||||||
|
musicid -> Int4,
|
||||||
|
musicsourceurl -> Text,
|
||||||
|
musicuserrequesterid -> Int8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
music_info (musicinfosourceurl) {
|
||||||
|
musicinfosourceurl -> Text,
|
||||||
|
musicinfotitle -> Text,
|
||||||
|
musicinfothumbnailurl -> Nullable<Text>,
|
||||||
|
musicinfolength -> Int4,
|
||||||
|
musicinfomusicid -> Int4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
music_session (musicsessionid) {
|
||||||
|
musicsessionid -> Int4,
|
||||||
|
musicsessioncurrentplayingindex -> Nullable<Int2>,
|
||||||
|
musicsessionguildid -> Int8,
|
||||||
|
musicsessiontextchannelid -> Int8,
|
||||||
|
musicsessionplayingchannelid -> Int8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
music_session_list (musicsessionid, musicid, musicsessionlistindex) {
|
||||||
|
musicsessionid -> Int4,
|
||||||
|
musicid -> Int4,
|
||||||
|
musicsessionlistindex -> Int2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
settings (settingsguildid) {
|
||||||
|
settingsguildid -> Int8,
|
||||||
|
settingsmuteroleid -> Nullable<Int8>,
|
||||||
|
settingsroulettekickenabled -> Nullable<Bool>,
|
||||||
|
settingslogchannelid -> Nullable<Int8>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinable!(music_info -> music (musicinfomusicid));
|
||||||
|
joinable!(music_session_list -> music (musicid));
|
||||||
|
joinable!(music_session_list -> music_session (musicsessionid));
|
||||||
|
|
||||||
|
allow_tables_to_appear_in_same_query!(
|
||||||
|
music,
|
||||||
|
music_info,
|
||||||
|
music_session,
|
||||||
|
music_session_list,
|
||||||
|
settings,
|
||||||
|
);
|
|
@ -3,6 +3,7 @@ name = "rusty_bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["oupson"]
|
authors = ["oupson"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
default-run = "rusty_bot"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
@ -25,3 +26,5 @@ log = "0.4"
|
||||||
log4rs = "1.0"
|
log4rs = "1.0"
|
||||||
ctrlc = "3.1"
|
ctrlc = "3.1"
|
||||||
songbird = { version = "0.2", features = ["driver", "builtin-queue", "yt-dlp"], optional = true }
|
songbird = { version = "0.2", features = ["driver", "builtin-queue", "yt-dlp"], optional = true }
|
||||||
|
rusty-bot-database = { path = "../rusty-bot-database" }
|
||||||
|
anyhow = "1.0.56"
|
|
@ -1,3 +1,4 @@
|
||||||
|
use rusty_bot_database::queries::RustyConnectionExt;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
client::Context,
|
client::Context,
|
||||||
framework::standard::CommandResult,
|
framework::standard::CommandResult,
|
||||||
|
@ -14,7 +15,7 @@ use serenity::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{data::GuildOptionsKey, utils::message::embed_author};
|
use crate::{utils::message::embed_author, DatabaseKey};
|
||||||
|
|
||||||
pub(crate) async fn handle_interaction(ctx: &Context, interaction: &Interaction) -> CommandResult {
|
pub(crate) async fn handle_interaction(ctx: &Context, interaction: &Interaction) -> CommandResult {
|
||||||
match interaction {
|
match interaction {
|
||||||
|
@ -83,14 +84,13 @@ async fn goulag(
|
||||||
author: &Member,
|
author: &Member,
|
||||||
) -> CommandResult {
|
) -> CommandResult {
|
||||||
let ctx_data = ctx.data.read().await;
|
let ctx_data = ctx.data.read().await;
|
||||||
let ctx_data = ctx_data
|
|
||||||
.get::<GuildOptionsKey>()
|
|
||||||
.expect("Failed to get guild cache");
|
|
||||||
|
|
||||||
let guild_options = ctx_data.get(&guild_id.into());
|
let conn = ctx_data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
|
let conn = conn.lock().await;
|
||||||
|
let guild_options = conn.fetch_settings(guild_id).ok();
|
||||||
|
|
||||||
if let Some(guild_options) = guild_options {
|
if let Some(guild_options) = guild_options {
|
||||||
if let Some(mute_role) = guild_options.get_mute_role() {
|
if let Some(mute_role) = guild_options.get_mute_role_id() {
|
||||||
let options = &data.options;
|
let options = &data.options;
|
||||||
|
|
||||||
let user = options
|
let user = options
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use rusty_bot_database::queries::RustyConnectionExt;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
builder::CreateMessage,
|
builder::CreateMessage,
|
||||||
client::Context,
|
client::Context,
|
||||||
|
@ -5,15 +6,15 @@ use serenity::{
|
||||||
model::{
|
model::{
|
||||||
channel::Message,
|
channel::Message,
|
||||||
guild::{Member, PartialMember},
|
guild::{Member, PartialMember},
|
||||||
id::GuildId,
|
id::{GuildId, RoleId},
|
||||||
Permissions,
|
Permissions,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use songbird::{input::Metadata, Call};
|
use songbird::{input::Metadata, Call};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::GuildOptionsKey,
|
|
||||||
utils::{message::embed_author, permissions::has_permission},
|
utils::{message::embed_author, permissions::has_permission},
|
||||||
|
DatabaseKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::error::UseVoiceError;
|
use super::error::UseVoiceError;
|
||||||
|
@ -24,13 +25,13 @@ pub(crate) async fn is_mute(
|
||||||
guild_id: GuildId,
|
guild_id: GuildId,
|
||||||
) -> CommandResult<bool> {
|
) -> CommandResult<bool> {
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
|
let conn = conn.lock().await;
|
||||||
|
|
||||||
let data = data
|
let role_id = conn.settings_fetch_mute_role(guild_id.0)?;
|
||||||
.get::<GuildOptionsKey>()
|
|
||||||
.expect("Failed to get guild cache");
|
|
||||||
|
|
||||||
if let Some(mute_role) = data.get(&guild_id).and_then(|o| o.get_mute_role()) {
|
if let Some(mute_role) = role_id {
|
||||||
Ok(member.roles.contains(&mute_role))
|
Ok(member.roles.contains(&RoleId(mute_role)))
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::{
|
use crate::{api, DatabaseKey};
|
||||||
api,
|
|
||||||
data::{GuildOptions, GuildOptionsKey},
|
|
||||||
};
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use rusty_bot_database::{queries::RustyConnectionExt};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
framework::standard::{
|
framework::standard::{
|
||||||
macros::{command, group},
|
macros::{command, group},
|
||||||
|
@ -45,13 +43,13 @@ async fn shot(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
#[only_in(guilds)]
|
#[only_in(guilds)]
|
||||||
async fn kick(ctx: &Context, msg: &Message) -> CommandResult {
|
async fn kick(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
if let Some(guild_id) = &msg.guild_id {
|
if let Some(guild_id) = &msg.guild_id {
|
||||||
let mut data = ctx.data.write().await;
|
let data = ctx.data.read().await;
|
||||||
let guilds_options = data
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
.get_mut::<GuildOptionsKey>()
|
let conn = conn.lock().await;
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
let guild_options = conn.fetch_settings(guild_id.0).ok();
|
||||||
|
|
||||||
let guild_options = guilds_options.entry(*guild_id).or_default();
|
if !(guild_options.is_some() && guild_options.unwrap().roulette_kick_enabled == Some(true))
|
||||||
if !guild_options.roulette_options.kick_enabled {
|
{
|
||||||
msg.channel_id
|
msg.channel_id
|
||||||
.say(
|
.say(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -85,27 +83,23 @@ async fn kick(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
#[required_permissions("ADMINISTRATOR")]
|
#[required_permissions("ADMINISTRATOR")]
|
||||||
#[owner_privilege]
|
#[owner_privilege]
|
||||||
async fn disable_kick(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
async fn disable_kick(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
|
if let Some(guild_id) = msg.guild_id {
|
||||||
let disable = match args.len() {
|
let disable = match args.len() {
|
||||||
0 => true,
|
0 => true,
|
||||||
_ => args.single::<bool>()?,
|
_ => args.single::<bool>()?,
|
||||||
};
|
};
|
||||||
let mut data = ctx.data.write().await;
|
|
||||||
let guilds_options = data
|
|
||||||
.get_mut::<GuildOptionsKey>()
|
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
|
||||||
if let Some(guild_id) = msg.guild_id {
|
let data = ctx.data.read().await;
|
||||||
let entry = guilds_options
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
.entry(guild_id)
|
let conn = conn.lock().await;
|
||||||
.or_insert_with(|| GuildOptions::default().set_guild_id(guild_id));
|
|
||||||
entry.roulette_options.kick_enabled = !disable;
|
conn.settings_edit_kick(guild_id.0, disable)?;
|
||||||
|
|
||||||
if disable {
|
if disable {
|
||||||
msg.channel_id.say(ctx, "No fun allowed").await?;
|
msg.channel_id.say(ctx, "No fun allowed").await?;
|
||||||
} else {
|
} else {
|
||||||
msg.channel_id.say(ctx, "Done").await?;
|
msg.channel_id.say(ctx, "Done").await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.save_async(guild_id.0).await?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use rusty_bot_database::queries::RustyConnectionExt;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
client::Context,
|
client::Context,
|
||||||
framework::standard::{Args, CommandResult},
|
framework::standard::{Args, CommandResult},
|
||||||
|
@ -11,7 +12,7 @@ use serenity::{
|
||||||
model::prelude::*,
|
model::prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::data::{GuildOptions, GuildOptionsKey};
|
use crate::DatabaseKey;
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[prefix("settings")]
|
#[prefix("settings")]
|
||||||
|
@ -28,55 +29,44 @@ async fn muterole(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
||||||
_ => Some(args.single::<String>()?),
|
_ => Some(args.single::<String>()?),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(id) = role_id {
|
|
||||||
let mut data = ctx.data.write().await;
|
|
||||||
|
|
||||||
let guilds_options = data
|
|
||||||
.get_mut::<GuildOptionsKey>()
|
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
|
||||||
if let Some(guild_id) = msg.guild_id {
|
if let Some(guild_id) = msg.guild_id {
|
||||||
let entry = guilds_options
|
if let Some(id) = role_id {
|
||||||
.entry(guild_id)
|
let data = ctx.data.read().await;
|
||||||
.or_insert_with(|| GuildOptions::default().set_guild_id(guild_id));
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
|
let conn = conn.lock().await;
|
||||||
|
|
||||||
entry.mute_id = match id.as_str() {
|
conn.settings_edit_mute_role(
|
||||||
|
guild_id.0,
|
||||||
|
match id.as_str() {
|
||||||
"none" => None,
|
"none" => None,
|
||||||
_ => Some(RoleId::from_str(&id)?),
|
_ => Some(RoleId::from_str(&id)?.0),
|
||||||
};
|
},
|
||||||
|
)?;
|
||||||
entry.save_async(guild_id.0).await?;
|
|
||||||
|
|
||||||
msg.channel_id.say(&ctx.http, "Saved").await?;
|
msg.channel_id.say(&ctx.http, "Saved").await?;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
|
|
||||||
let guilds_options = data
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
.get::<GuildOptionsKey>()
|
let conn = conn.lock().await;
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
let role_id = conn.settings_fetch_mute_role(guild_id.0)?;
|
||||||
|
|
||||||
if let Some(guild_id) = msg.guild_id {
|
|
||||||
if let Some(options) = guilds_options.get(&guild_id) {
|
|
||||||
msg.channel_id
|
msg.channel_id
|
||||||
.say(
|
.say(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
if let Some(role_id) = options.mute_id {
|
if let Some(role_id) = role_id {
|
||||||
format!(
|
format!(
|
||||||
"Mute role is @{}",
|
"Mute role is @{}",
|
||||||
role_id.to_role_cached(&ctx).await.unwrap().name
|
RoleId(role_id).to_role_cached(&ctx).await.unwrap().name
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"Mute role is None".to_string()
|
"Mute role is None".to_string()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
|
||||||
msg.channel_id.say(&ctx.http, "Mute role is None").await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,51 +80,38 @@ async fn logchannel(ctx: &Context, msg: &Message, mut args: Args) -> CommandResu
|
||||||
_ => Some(args.single::<String>()?),
|
_ => Some(args.single::<String>()?),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(id) = channel_id {
|
|
||||||
let mut data = ctx.data.write().await;
|
|
||||||
|
|
||||||
let guilds_options = data
|
|
||||||
.get_mut::<GuildOptionsKey>()
|
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
|
||||||
if let Some(guild_id) = msg.guild_id {
|
if let Some(guild_id) = msg.guild_id {
|
||||||
let entry = guilds_options
|
if let Some(id) = channel_id {
|
||||||
.entry(guild_id)
|
let data = ctx.data.read().await;
|
||||||
.or_insert_with(|| GuildOptions::default().set_guild_id(guild_id));
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
|
let conn = conn.lock().await;
|
||||||
|
|
||||||
entry.mention_log_channel = match id.as_str() {
|
conn.settings_edit_log_channel(
|
||||||
|
guild_id.0,
|
||||||
|
match id.as_str() {
|
||||||
"none" => None,
|
"none" => None,
|
||||||
_ => Some(ChannelId::from_str(&id)?),
|
_ => Some(ChannelId::from_str(&id)?.0),
|
||||||
};
|
},
|
||||||
|
)?;
|
||||||
entry.save_async(guild_id.0).await?;
|
|
||||||
|
|
||||||
msg.channel_id.say(&ctx.http, "Saved").await?;
|
msg.channel_id.say(&ctx.http, "Saved").await?;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
|
let conn = conn.lock().await;
|
||||||
|
|
||||||
let guilds_options = data
|
let log_channel = conn.settings_fetch_log_channel(guild_id.0)?;
|
||||||
.get::<GuildOptionsKey>()
|
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
|
||||||
if let Some(guild_id) = msg.guild_id {
|
|
||||||
if let Some(options) = guilds_options.get(&guild_id) {
|
|
||||||
msg.channel_id
|
msg.channel_id
|
||||||
.say(
|
.say(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
if let Some(channel_id) = options.mention_log_channel {
|
if let Some(channel_id) = log_channel {
|
||||||
format!("Logging channel is {}", channel_id.mention())
|
format!("Logging channel is {}", ChannelId(channel_id).mention())
|
||||||
} else {
|
} else {
|
||||||
"Logging channel is None".to_string()
|
"Logging channel is None".to_string()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
|
||||||
msg.channel_id
|
|
||||||
.say(&ctx.http, "Logging channel is None")
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,5 @@ pub(crate) struct Bot {
|
||||||
pub(crate) token: String,
|
pub(crate) token: String,
|
||||||
pub(crate) application_id: u64,
|
pub(crate) application_id: u64,
|
||||||
pub(crate) invite_url: Option<String>,
|
pub(crate) invite_url: Option<String>,
|
||||||
|
pub(crate) database_url: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
use log::error;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serenity::{
|
|
||||||
model::{
|
|
||||||
id::ChannelId,
|
|
||||||
prelude::{GuildId, RoleId},
|
|
||||||
},
|
|
||||||
prelude::TypeMapKey,
|
|
||||||
};
|
|
||||||
use std::{
|
|
||||||
collections::HashMap,
|
|
||||||
fs,
|
|
||||||
io::{Result as IoResult, Write},
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub(crate) struct GuildOptions {
|
|
||||||
#[serde(skip_serializing)]
|
|
||||||
pub(crate) guild_id: Option<GuildId>,
|
|
||||||
pub(crate) mute_id: Option<RoleId>,
|
|
||||||
pub(crate) mention_log_channel: Option<ChannelId>,
|
|
||||||
pub(crate) roulette_options: RouletteOptions,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GuildOptions {
|
|
||||||
pub async fn save_async(&mut self, guild_id: u64) -> tokio::io::Result<()> {
|
|
||||||
let path = PathBuf::from(format!("./data/guilds_options/{}.json", guild_id));
|
|
||||||
|
|
||||||
if !path.parent().unwrap().exists() {
|
|
||||||
tokio::fs::create_dir_all(path.parent().unwrap()).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut file = tokio::fs::File::create(path).await?;
|
|
||||||
let serialized = serde_json::to_string_pretty(self)?;
|
|
||||||
file.write_all(&serialized.as_bytes()).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn save(&mut self, guild_id: u64) -> IoResult<()> {
|
|
||||||
let path = PathBuf::from(format!("./data/guilds_options/{}.json", guild_id));
|
|
||||||
|
|
||||||
if !path.parent().unwrap().exists() {
|
|
||||||
std::fs::create_dir_all(path.parent().unwrap())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut file = std::fs::File::create(path)?;
|
|
||||||
let serialized = serde_json::to_string_pretty(self)?;
|
|
||||||
file.write_all(&serialized.as_bytes())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn set_guild_id(mut self, id: GuildId) -> Self {
|
|
||||||
self.guild_id = Some(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_from_dir<P: AsRef<Path>>(path: P) -> IoResult<HashMap<GuildId, GuildOptions>> {
|
|
||||||
let mut res = HashMap::new();
|
|
||||||
for entry in fs::read_dir(path)?.filter_map(|e| e.ok()) {
|
|
||||||
match serde_json::from_reader::<fs::File, GuildOptions>(fs::File::open(entry.path())?) {
|
|
||||||
Ok(options) => {
|
|
||||||
let id = GuildId::from(
|
|
||||||
entry
|
|
||||||
.file_name()
|
|
||||||
.to_string_lossy()
|
|
||||||
.split('.')
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
.parse::<u64>()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
res.insert(id, options.set_guild_id(id));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("While parsing guild option {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_mute_role(&self) -> Option<RoleId> {
|
|
||||||
self.mute_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for GuildOptions {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
roulette_options: RouletteOptions::default(),
|
|
||||||
guild_id: None,
|
|
||||||
mute_id: None,
|
|
||||||
mention_log_channel: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for GuildOptions {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(id) = self.guild_id {
|
|
||||||
log::debug!("Saving {:?}", self);
|
|
||||||
if let Err(e) = self.save(id.0) {
|
|
||||||
log::error!("While saving {} : {}", id.0, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub(crate) struct RouletteOptions {
|
|
||||||
pub(crate) kick_enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for RouletteOptions {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { kick_enabled: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct GuildOptionsKey;
|
|
||||||
|
|
||||||
impl TypeMapKey for GuildOptionsKey {
|
|
||||||
type Value = HashMap<GuildId, GuildOptions>;
|
|
||||||
}
|
|
|
@ -4,9 +4,6 @@ use serenity::{
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
mod guilds_options;
|
|
||||||
pub(crate) use guilds_options::{GuildOptions, GuildOptionsKey};
|
|
||||||
|
|
||||||
pub(crate) struct ShardManagerContainer;
|
pub(crate) struct ShardManagerContainer;
|
||||||
|
|
||||||
impl TypeMapKey for ShardManagerContainer {
|
impl TypeMapKey for ShardManagerContainer {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use crate::{
|
use std::{
|
||||||
commands::{
|
collections::{HashMap, HashSet},
|
||||||
admin::ADMIN_GROUP, general::GENERAL_GROUP, owner::OWNER_GROUP, roulette::ROULETTE_GROUP,
|
fs,
|
||||||
settings::SETTINGS_GROUP,
|
path::Path,
|
||||||
},
|
sync::Arc,
|
||||||
data::{BulletsContainer, GuildOptions, GuildOptionsKey, ShardManagerContainer, Uptime},
|
time::Duration,
|
||||||
|
time::Instant,
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
|
||||||
use commands::interaction;
|
|
||||||
use log::{debug, error, info};
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
framework::standard::{
|
framework::standard::{
|
||||||
help_commands,
|
help_commands,
|
||||||
|
@ -19,14 +18,17 @@ use serenity::{
|
||||||
model::prelude::*,
|
model::prelude::*,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use std::{
|
|
||||||
collections::{HashMap, HashSet},
|
use log::{debug, error, info};
|
||||||
fs,
|
|
||||||
io::Result as IoResult,
|
use rusty_bot_database::{diesel::PgConnection, establish_connection, queries::RustyConnectionExt};
|
||||||
path::Path,
|
|
||||||
sync::Arc,
|
use crate::{
|
||||||
time::Duration,
|
commands::{
|
||||||
time::Instant,
|
admin::ADMIN_GROUP, general::GENERAL_GROUP, interaction, owner::OWNER_GROUP,
|
||||||
|
roulette::ROULETTE_GROUP, settings::SETTINGS_GROUP,
|
||||||
|
},
|
||||||
|
data::{BulletsContainer, ShardManagerContainer, Uptime},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "music")]
|
#[cfg(feature = "music")]
|
||||||
|
@ -47,9 +49,15 @@ const MINIMUM_MENTIONS: usize = 20;
|
||||||
const PREFIX: &str = "?";
|
const PREFIX: &str = "?";
|
||||||
pub(crate) static mut INVITE_URL: Option<String> = None;
|
pub(crate) static mut INVITE_URL: Option<String> = None;
|
||||||
|
|
||||||
|
pub(crate) struct DatabaseKey;
|
||||||
|
|
||||||
|
impl TypeMapKey for DatabaseKey {
|
||||||
|
type Value = Arc<Mutex<PgConnection>>;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO CLAP FOR CLI
|
// TODO CLAP FOR CLI
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> IoResult<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
|
log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
|
||||||
|
@ -69,10 +77,12 @@ async fn main() -> IoResult<()> {
|
||||||
fs::create_dir(dir)?;
|
fs::create_dir(dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data_dir = Path::new("data");
|
// let data_dir = Path::new("data");
|
||||||
if !data_dir.exists() {
|
// if !data_dir.exists() {
|
||||||
fs::create_dir(data_dir)?;
|
// fs::create_dir(data_dir)?;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
let conn = Arc::new(Mutex::new(establish_connection(&conf.bot.database_url)?));
|
||||||
|
|
||||||
let http = Http::new_with_token(&token);
|
let http = Http::new_with_token(&token);
|
||||||
|
|
||||||
|
@ -143,17 +153,15 @@ async fn main() -> IoResult<()> {
|
||||||
let mut data = client.data.write().await;
|
let mut data = client.data.write().await;
|
||||||
data.insert::<BulletsContainer>(HashMap::default());
|
data.insert::<BulletsContainer>(HashMap::default());
|
||||||
data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
|
data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
|
||||||
|
|
||||||
/*#[cfg(feature = "music")]
|
/*#[cfg(feature = "music")]
|
||||||
{
|
{
|
||||||
data.insert::<VoiceManager>(std::sync::Arc::clone(&client.voice_manager.unwrap()));
|
data.insert::<VoiceManager>(std::sync::Arc::clone(&client.voice_manager.unwrap()));
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
data.insert::<Uptime>(now);
|
data.insert::<Uptime>(now);
|
||||||
|
|
||||||
data.insert::<GuildOptionsKey>({
|
data.insert::<DatabaseKey>(conn);
|
||||||
let options = GuildOptions::load_from_dir("./data/guilds_options").unwrap_or_default();
|
|
||||||
log::debug!("Loaded {:?}", options);
|
|
||||||
options
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_runtime = tokio::runtime::Handle::current();
|
let current_runtime = tokio::runtime::Handle::current();
|
||||||
|
@ -177,7 +185,7 @@ async fn main() -> IoResult<()> {
|
||||||
|
|
||||||
struct Messages {}
|
struct Messages {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventHandler for Messages {
|
impl EventHandler for Messages {
|
||||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||||
info!("{} connected to discord", ready.user.name);
|
info!("{} connected to discord", ready.user.name);
|
||||||
|
@ -239,10 +247,6 @@ async fn log_mentions(ctx: Context, new_message: &Message) -> CommandResult {
|
||||||
|
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
|
|
||||||
let guilds_options = data
|
|
||||||
.get::<GuildOptionsKey>()
|
|
||||||
.expect("Expected NonKickGuildsContainer in TypeMap.");
|
|
||||||
|
|
||||||
let mute = if new_message.mention_everyone {
|
let mute = if new_message.mention_everyone {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -295,14 +299,19 @@ async fn log_mentions(ctx: Context, new_message: &Message) -> CommandResult {
|
||||||
|
|
||||||
if mute {
|
if mute {
|
||||||
if let Some(guild_id) = new_message.guild_id {
|
if let Some(guild_id) = new_message.guild_id {
|
||||||
if let Some(options) = guilds_options.get(&guild_id) {
|
let conn = data.get::<DatabaseKey>().expect("failed to get db");
|
||||||
if let Some(role_id) = options.mute_id {
|
let conn = conn.lock().await;
|
||||||
|
|
||||||
|
let role_id = conn.settings_fetch_mute_role(guild_id.0)?;
|
||||||
|
let channel_id = conn.settings_fetch_log_channel(guild_id.0)?;
|
||||||
|
|
||||||
|
if let Some(role_id) = role_id {
|
||||||
let mut member = new_message.member(&ctx).await?;
|
let mut member = new_message.member(&ctx).await?;
|
||||||
member.add_role(&ctx.http, role_id).await?;
|
member.add_role(&ctx.http, role_id).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(channel_id) = options.mention_log_channel {
|
if let Some(channel_id) = channel_id {
|
||||||
channel_id
|
ChannelId(channel_id)
|
||||||
.send_message(&ctx.http, |m| {
|
.send_message(&ctx.http, |m| {
|
||||||
m.embed(|e| {
|
m.embed(|e| {
|
||||||
e.title("New message with mentions")
|
e.title("New message with mentions")
|
||||||
|
@ -322,7 +331,6 @@ async fn log_mentions(ctx: Context, new_message: &Message) -> CommandResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue