Update dependencies, remote unnecessary RwLock on database, fix typos #43
2
.git-blame-ignore-revs
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Fix typos
|
||||
4b4e5cb2894346684034cba93a5ac1ec6f884f9f
|
||||
silver marked this conversation as resolved
|
|
@ -7,4 +7,4 @@ fn_params_layout = "Compressed"
|
|||
struct_lit_width = 0
|
||||
tab_spaces = 2
|
||||
use_small_heuristics = "Max"
|
||||
imports_granularity = "Crate"
|
||||
imports_granularity = "Crate"
|
||||
|
|
2
.taplo.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[formatting]
|
||||
column_width = 120
|
1889
Cargo.lock
generated
26
Cargo.toml
|
@ -19,16 +19,21 @@ name = "update_server-icon"
|
|||
[[bin]]
|
||||
name = "cleanup_committee"
|
||||
|
||||
[dependencies]
|
||||
# discord library
|
||||
serenity = { version = "0.12", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] }
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread", "full"] }
|
||||
[dependencies.serenity]
|
||||
version = "0.12"
|
||||
default-features = false
|
||||
features = ["client", "gateway", "rustls_backend", "model", "cache"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
# wolves api
|
||||
wolves_oxidised = { git = "https://forgejo.skynet.ie/Skynet/wolves-oxidised.git", features = ["unstable"] }
|
||||
cordlesscoder marked this conversation as resolved
silver
commented
Fix it properly, that includes teh commented out one Fix it properly, that includes teh commented out one
|
||||
# wolves_oxidised = { path = "../wolves-oxidised", features = ["unstable"] }
|
||||
|
||||
# to make the http requests
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread", "full"] }
|
||||
|
||||
# to make the http requests
|
||||
surf = "2.3"
|
||||
|
||||
dotenvy = "0.15"
|
||||
|
@ -47,13 +52,12 @@ chrono = "0.4"
|
|||
lettre = "0.11"
|
||||
maud = "0.27"
|
||||
|
||||
toml = "0.8.23"
|
||||
toml = "0.9.5"
|
||||
serde = "1.0"
|
||||
|
||||
# for image conversion
|
||||
eyre = "0.6.8"
|
||||
color-eyre = "0.6.2"
|
||||
usvg-text-layout = "0.29.0"
|
||||
usvg = "0.29.0"
|
||||
resvg = "0.29.0"
|
||||
tiny-skia = "0.8.3"
|
||||
eyre = "0.6.12"
|
||||
color-eyre = "0.6.5"
|
||||
usvg = "0.45.1"
|
||||
resvg = "0.45.1"
|
||||
tiny-skia = "0.11.4"
|
||||
|
|
|
@ -16,10 +16,10 @@ use sqlx::{Pool, Sqlite};
|
|||
use std::{process, sync::Arc};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
/// Cleanup teh Committee server
|
||||
/// Cleanup the Committee server
|
||||
///
|
||||
/// This removes any invalid roles/channels which ay have been set up accidentally
|
||||
/// DO NOT run this locally unless you have a fresh copy of teh live database handy.
|
||||
/// This removes any invalid roles/channels which have been set up accidentally
|
||||
/// DO NOT run this locally unless you have a fresh copy of the live database handy.
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let config = get_config();
|
||||
|
@ -41,7 +41,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
silver marked this conversation as resolved
silver
commented
Out of curiosity did ye try and run the bot, or did ye entirely depend on fmt/clippy? Asking as when first set up it needed to be using the rwlock, things might have changed since though. Out of curiosity did ye try and run the bot, or did ye entirely depend on fmt/clippy?
Asking as when first set up it needed to be using the rwlock, things might have changed since though.
cordlesscoder
commented
The RwLock can't be required, as the only extra capability it adds is getting a mutable reference to the Database - something your code doesn't do once, and something sqlx's Pool intentionally avoids. The RwLock can't be required, as the only extra capability it adds is getting a mutable reference to the Database - something your code doesn't do once, and something sqlx's Pool intentionally avoids.
silver
commented
Just be cause it is not now does not mean it never was. Still set of comments was more remarking on it than actually needing it changed, so marking it resolved ```diff
- code doesn't do once
+ code doesn't do once now
```
Just be cause it is not now does not mean it never was.
Still set of comments was more remarking on it than actually needing it changed, so marking it resolved
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
|
@ -69,13 +69,11 @@ impl EventHandler for Handler {
|
|||
async fn guild_members_chunk(&self, ctx: Context, chunk: GuildMembersChunkEvent) {
|
||||
if (chunk.chunk_index + 1) == chunk.chunk_count {
|
||||
println!("Cache built successfully!");
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<Config>().expect("Expected Config in TypeMap.").clone()
|
||||
|
@ -98,7 +96,7 @@ async fn cleanup(db: &Pool<Sqlite>, ctx: &Context, config: &Config) {
|
|||
let name = &channel.name;
|
||||
let committee_tmp = committees.iter().filter(|x| &x.name_channel == name).collect::<Vec<_>>();
|
||||
let committee = match committee_tmp.first() {
|
||||
// if there are no committees which match then this is not a channelw e care about
|
||||
// if there are no committees which match then this is not a channel we care about
|
||||
None => {
|
||||
continue;
|
||||
}
|
||||
|
@ -120,7 +118,7 @@ async fn cleanup(db: &Pool<Sqlite>, ctx: &Context, config: &Config) {
|
|||
let name = &role.name;
|
||||
let committee_tmp = committees.iter().filter(|x| &x.name_role == name).collect::<Vec<_>>();
|
||||
let committee = match committee_tmp.first() {
|
||||
// if there are no committees which match then this is not a channelw e care about
|
||||
// if there are no committees which match then this is not a channel we care about
|
||||
None => {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
|
|
|
@ -38,7 +38,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
|
@ -56,7 +56,7 @@ impl EventHandler for Handler {
|
|||
// get the data for each individual club/soc
|
||||
get_wolves(&ctx).await;
|
||||
|
||||
// get teh data for the clubs/socs committees
|
||||
// get the data for the clubs/socs committees
|
||||
get_cns(&ctx).await;
|
||||
|
||||
// finish up
|
||||
|
|
|
@ -22,7 +22,7 @@ async fn main() {
|
|||
// wipe whitelist first
|
||||
if !wiped.contains(&server.minecraft) {
|
||||
whitelist_wipe(&server.minecraft, &config.discord_token_minecraft).await;
|
||||
// add it to teh done list so its not done again
|
||||
// add it to the done list so its not done again
|
||||
wiped.insert(&server.minecraft);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
|
@ -50,11 +50,10 @@ impl EventHandler for Handler {
|
|||
let ctx = Arc::new(ctx);
|
||||
println!("{} is connected!", ready.user.name);
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
|
|
@ -40,7 +40,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
|
@ -79,13 +79,11 @@ impl EventHandler for Handler {
|
|||
}
|
||||
|
||||
async fn check_bulk(ctx: &Context) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
for server_config in get_server_config_bulk(&db).await {
|
||||
normal::update_server(ctx, &server_config, &[], &[]).await;
|
||||
}
|
||||
|
|
|
@ -56,11 +56,10 @@ pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
|||
return "Please provide a valid channel for ``Bot Channel``".to_string();
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let server_data = Servers {
|
||||
server: command.guild_id.unwrap_or_default(),
|
||||
|
@ -102,7 +101,7 @@ async fn add_server(db: &Pool<Sqlite>, ctx: &Context, server: &Servers) -> Resul
|
|||
.fetch_optional(db)
|
||||
.await;
|
||||
|
||||
// if the entry does not exist already tehn do a user update
|
||||
// if the entry does not exist already then do a user update
|
||||
let (update, current_remove, current_role, past_remove, past_role) = match &existing {
|
||||
None => (true, false, None, false, None),
|
||||
Some(x) => {
|
||||
|
|
|
@ -27,11 +27,10 @@ pub mod committee {
|
|||
false
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let mut cs = vec![];
|
||||
// pull it from a DB
|
||||
|
@ -95,11 +94,10 @@ pub mod servers {
|
|||
use std::collections::HashMap;
|
||||
|
||||
pub async fn run(_command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let mut committees = HashMap::new();
|
||||
if let Some(x) = get_committees(&db).await {
|
||||
|
@ -121,7 +119,7 @@ pub mod servers {
|
|||
cs.push((total, total, String::from("Skynet Network")));
|
||||
cs.push((wolves_current, wolves_past, String::from("Clubs/Socs Servers")));
|
||||
|
||||
// treat teh committee server as its own thing
|
||||
// treat the committee server as its own thing
|
||||
let committee_current = get_wolves_committee(&db).await;
|
||||
cs.push((committee_current, committee_current, String::from("Committee Server")));
|
||||
|
||||
|
@ -152,7 +150,7 @@ pub mod servers {
|
|||
|
||||
let length = line.len() + 1;
|
||||
|
||||
// +3 is to account for the closing fense
|
||||
// +3 is to account for the closing fence
|
||||
if length < (limit + 3) {
|
||||
response.push(line);
|
||||
limit -= length;
|
||||
|
|
|
@ -23,11 +23,10 @@ pub(crate) mod user {
|
|||
use sqlx::Error;
|
||||
|
||||
pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
@ -196,7 +195,7 @@ pub(crate) mod server {
|
|||
model::id::GuildId,
|
||||
};
|
||||
use sqlx::Error;
|
||||
// this is to managfe the server side of commands related to minecraft
|
||||
// this is to manage the server side of commands related to minecraft
|
||||
use super::*;
|
||||
use skynet_discord_bot::{
|
||||
common::minecraft::{update_server, Minecraft},
|
||||
|
@ -229,11 +228,10 @@ pub(crate) mod server {
|
|||
return String::from("Expected Server ID");
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
match add_server(&db, &g_id, &server_minecraft).await {
|
||||
Ok(_) => {}
|
||||
|
@ -290,11 +288,10 @@ pub(crate) mod server {
|
|||
Some(x) => x,
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let servers = get_minecraft_config_server(&db, g_id).await;
|
||||
|
||||
|
@ -366,11 +363,10 @@ pub(crate) mod server {
|
|||
return String::from("Expected Server ID");
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
let db = {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
match server_remove(&db, &g_id, &server_minecraft).await {
|
||||
Ok(_) => {}
|
||||
|
@ -380,7 +376,7 @@ pub(crate) mod server {
|
|||
}
|
||||
}
|
||||
|
||||
// no need to clear teh whitelist as it will be reset within 24hr anyways
|
||||
// no need to clear the whitelist as it will be reset within 24hr anyways
|
||||
|
||||
"Removed minecraft_server info".to_string()
|
||||
}
|
||||
|
|
|
@ -62,11 +62,10 @@ pub mod edit {
|
|||
false
|
||||
};
|
||||
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let server = command.guild_id.unwrap_or_default();
|
||||
let server_data = RoleAdder {
|
||||
|
@ -147,7 +146,7 @@ pub mod tools {
|
|||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
pub async fn on_role_change(db: &Pool<Sqlite>, ctx: &Context, new_data: Member) {
|
||||
// check if the role changed is part of the oens for this server
|
||||
// check if the role changed is part of the ones for this server
|
||||
if let Ok(role_adders) = sqlx::query_as::<_, RoleAdder>(
|
||||
r#"
|
||||
SELECT *
|
||||
|
@ -163,7 +162,7 @@ pub mod tools {
|
|||
let mut roles_remove = vec![];
|
||||
|
||||
for role_adder in role_adders {
|
||||
// if the user has both A dnd B give them C
|
||||
// if the user has both A and B give them C
|
||||
if new_data.roles.contains(&role_adder.role_a) && new_data.roles.contains(&role_adder.role_b) && !new_data.roles.contains(&role_adder.role_c)
|
||||
{
|
||||
roles_add.push(role_adder.role_c);
|
||||
|
|
|
@ -18,11 +18,10 @@ pub(crate) mod admin {
|
|||
use super::*;
|
||||
|
||||
pub async fn run(_command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
@ -58,7 +57,7 @@ pub(crate) mod user {
|
|||
format!("{}/src/branch/main/{}/{}", &config_toml.source.repo, &config_toml.source.directory, logo_name)
|
||||
}
|
||||
|
||||
/// Regular users can get teh link to teh current icon
|
||||
/// Regular users can get the link to the current icon
|
||||
pub(crate) mod current {
|
||||
use super::*;
|
||||
|
||||
|
@ -69,11 +68,10 @@ pub(crate) mod user {
|
|||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_toml = get_config_icons::minimal();
|
||||
|
||||
|
@ -145,11 +143,10 @@ pub(crate) mod user {
|
|||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
pub async fn run(_command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_toml = get_config_icons::minimal();
|
||||
|
||||
|
@ -211,7 +208,7 @@ pub(crate) mod user {
|
|||
|
||||
let length = line.len() + 1;
|
||||
|
||||
// +3 is to account for the closing fense
|
||||
// +3 is to account for the closing fence
|
||||
if length < (limit + 3) {
|
||||
response.push(line);
|
||||
limit -= length;
|
||||
|
|
|
@ -21,11 +21,10 @@ pub mod link {
|
|||
use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteraction};
|
||||
|
||||
pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
@ -77,7 +76,7 @@ pub mod link {
|
|||
Some(x) => x,
|
||||
};
|
||||
|
||||
// save teh user id and email to teh db
|
||||
// save the user id and email to the db
|
||||
match save_to_db_user(&db, id, email).await {
|
||||
Ok(x) => x,
|
||||
Err(x) => {
|
||||
|
@ -101,7 +100,7 @@ pub mod link {
|
|||
return "Email already verified".to_string();
|
||||
}
|
||||
|
||||
// generate a auth key
|
||||
// generate an auth key
|
||||
let auth = random_string(20);
|
||||
match send_mail(&config, &details.email, &auth, &command.user.name) {
|
||||
Ok(_) => match save_to_db(&db, &details, &auth, &command.user.id).await {
|
||||
|
@ -210,7 +209,7 @@ pub mod link {
|
|||
.subject("Skynet: Link Discord to Wolves.")
|
||||
.multipart(
|
||||
// This is composed of two parts.
|
||||
// also helps not trip spam settings (uneven number of url's
|
||||
// also helps not trip spam settings (uneven number of urls)
|
||||
MultiPart::alternative()
|
||||
.singlepart(SinglePart::builder().header(header::ContentType::TEXT_PLAIN).body(body_text))
|
||||
.singlepart(SinglePart::builder().header(header::ContentType::TEXT_HTML).body(html.into_string())),
|
||||
|
@ -314,11 +313,10 @@ pub mod verify {
|
|||
use sqlx::Error;
|
||||
|
||||
pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Database in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
// check if user has used /link_wolves
|
||||
let details = if let Some(x) = get_verify_from_db(&db, &command.user.id).await {
|
||||
|
@ -356,7 +354,7 @@ pub mod verify {
|
|||
Ok(_) => {
|
||||
return match set_discord(&db, &command.user.id, &details.email).await {
|
||||
Ok(_) => {
|
||||
// get teh right roles for the user
|
||||
// get the right roles for the user
|
||||
set_server_roles(&db, &command.user, ctx).await;
|
||||
|
||||
// check if they are a committee member, and on that server
|
||||
|
@ -460,8 +458,8 @@ pub mod verify {
|
|||
let config = config_lock.read().await;
|
||||
|
||||
if let Some(x) = get_server_member_discord(db, &discord.id).await {
|
||||
// if they are a member of one or more committees, and in teh committee server then give the teh general committee role
|
||||
// they will get teh more specific vanity role later
|
||||
// if they are a member of one or more committees, and in the committee server then give the general committee role
|
||||
// they will get the more specific vanity role later
|
||||
if !get_committees_id(db, x.id_wolves).await.is_empty() {
|
||||
let server = config.committee_server;
|
||||
let committee_member = config.committee_role;
|
||||
|
@ -494,13 +492,12 @@ pub mod unlink {
|
|||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
pub async fn run(command: &CommandInteraction, ctx: &Context) -> String {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Databse in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
// dosent matter if there is one or not, it will be removed regardless
|
||||
// Doesn't matter if there is one or not, it will be removed regardless
|
||||
delete_link(&db, &command.user.id).await;
|
||||
|
||||
"Discord link removed".to_string()
|
||||
|
|
|
@ -12,11 +12,10 @@ use sqlx::{
|
|||
Error, FromRow, Pool, Row, Sqlite,
|
||||
};
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct DataBase;
|
||||
impl TypeMapKey for DataBase {
|
||||
type Value = Arc<RwLock<Pool<Sqlite>>>;
|
||||
type Value = Arc<Pool<Sqlite>>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
|
|
@ -24,7 +24,7 @@ impl<'r> FromRow<'r, SqliteRow> for Minecraft {
|
|||
/**
|
||||
loop through all members of server
|
||||
get a list of folks with mc accounts that are members
|
||||
and a list that arent members
|
||||
and a list that aren't members
|
||||
*/
|
||||
pub async fn update_server(server_id: &str, db: &Pool<Sqlite>, g_id: &GuildId, config: &Config) {
|
||||
let mut usernames = vec![];
|
||||
|
@ -109,7 +109,7 @@ pub async fn whitelist_wipe(server: &str, token: &str) {
|
|||
};
|
||||
post(&format!("{url_base}/files/delete"), &bearer, &deletion).await;
|
||||
|
||||
// recreate teh file, passing in the type here so the compiler knows what type of vec it is
|
||||
// recreate the file, passing in the type here so the compiler knows what type of Vec it is
|
||||
post::<Vec<&str>>(&format!("{url_base}/files/write?file=%2Fwhitelist.json"), &bearer, &vec![]).await;
|
||||
|
||||
// reload the whitelist
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// this code is taken from https://github.com/MCorange99/svg2colored-png/tree/main
|
||||
// I was unable to figure out how to use usvg myself so younked it from here.
|
||||
// I was unable to figure out how to use usvg myself so yoinked it from here.
|
||||
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
// use clap::builder::OsStr;
|
||||
use color_eyre::{eyre::bail, Result};
|
||||
use usvg_text_layout::TreeTextToPath;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Args {
|
||||
|
@ -17,7 +16,7 @@ pub struct Args {
|
|||
/// Output folder where the PNG's will be placed
|
||||
pub output: PathBuf,
|
||||
|
||||
/// Comma seperated colors that will be used in HEX Eg. 000000,ffffff
|
||||
/// Comma separated colors that will be used in HEX Eg. 000000,ffffff
|
||||
/// Can be like an object: black:000000,white:ffffff
|
||||
pub colors: String,
|
||||
|
||||
|
@ -37,7 +36,7 @@ enum ColorType {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Renderer {
|
||||
fontdb: usvg_text_layout::fontdb::Database,
|
||||
fontdb: Arc<usvg::fontdb::Database>,
|
||||
colors: ColorType,
|
||||
size: (u32, u32),
|
||||
pub count: u64,
|
||||
|
@ -45,60 +44,48 @@ pub struct Renderer {
|
|||
|
||||
impl Renderer {
|
||||
pub fn new(args: &Args) -> Result<Self> {
|
||||
let mut db = usvg_text_layout::fontdb::Database::new();
|
||||
let mut db = usvg::fontdb::Database::default();
|
||||
db.load_system_fonts();
|
||||
|
||||
let mut this = Self {
|
||||
fontdb: db,
|
||||
fontdb: Arc::new(db),
|
||||
colors: ColorType::None,
|
||||
size: (args.width, args.height),
|
||||
count: 0,
|
||||
};
|
||||
|
||||
let colors = if args.colors.contains(':') {
|
||||
//? object
|
||||
let obj = args
|
||||
.colors
|
||||
.split(',')
|
||||
.map(|s| {
|
||||
let s = s.split(':').collect::<Vec<&str>>();
|
||||
this.colors = if args.colors.contains(':') {
|
||||
let obj = args.colors.split(',').map(|s| {
|
||||
let mut iter = s.split(':');
|
||||
let [Some(a), Some(b), None] = std::array::from_fn(|_| iter.next()) else {
|
||||
dbg!("Invalid color object, try checking help");
|
||||
return None;
|
||||
};
|
||||
|
||||
if s.len() < 2 {
|
||||
dbg!("Invalid color object, try checking help");
|
||||
return None;
|
||||
}
|
||||
Some((a.to_string(), b.to_string()))
|
||||
});
|
||||
|
||||
Some((s[0].to_string(), s[1].to_string()))
|
||||
let colors = obj
|
||||
.flatten()
|
||||
.map(|c| {
|
||||
std::fs::create_dir_all(args.output.join(&c.0))?;
|
||||
Ok(c)
|
||||
})
|
||||
.collect::<Vec<Option<(String, String)>>>();
|
||||
|
||||
let mut colors = Vec::new();
|
||||
|
||||
for c in obj.into_iter().flatten() {
|
||||
std::fs::create_dir_all(args.output.join(&c.0))?;
|
||||
|
||||
colors.push(c);
|
||||
}
|
||||
.collect::<std::io::Result<_>>()?;
|
||||
|
||||
ColorType::Object(colors)
|
||||
} else {
|
||||
//? list
|
||||
// let colors = args.colors.split(",").map(|s| {
|
||||
// s.to_string()
|
||||
// })
|
||||
// .collect::<Vec<String>>();
|
||||
|
||||
let mut colors = Vec::new();
|
||||
|
||||
for color in args.colors.split(',') {
|
||||
std::fs::create_dir_all(args.output.join(color))?;
|
||||
colors.push(color.to_string())
|
||||
}
|
||||
let colors = args
|
||||
.colors
|
||||
.split(',')
|
||||
.map(|color| -> std::io::Result<String> {
|
||||
std::fs::create_dir_all(args.output.join(color))?;
|
||||
Ok(color.to_string())
|
||||
})
|
||||
.collect::<std::io::Result<_>>()?;
|
||||
|
||||
ColorType::Array(colors)
|
||||
};
|
||||
|
||||
this.colors = colors;
|
||||
Ok(this)
|
||||
}
|
||||
|
||||
|
@ -144,10 +131,11 @@ impl Renderer {
|
|||
let opt = usvg::Options {
|
||||
// Get file's absolute directory.
|
||||
resources_dir: std::fs::canonicalize(fi).ok().and_then(|p| p.parent().map(|p| p.to_path_buf())),
|
||||
fontdb: self.fontdb.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut tree = match usvg::Tree::from_data(svg.as_bytes(), &opt) {
|
||||
let tree = match usvg::Tree::from_data(svg.as_bytes(), &opt) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
dbg!("Failed to parse {fi:?}");
|
||||
|
@ -155,14 +143,14 @@ impl Renderer {
|
|||
}
|
||||
};
|
||||
|
||||
tree.convert_text(&self.fontdb);
|
||||
|
||||
let mut pixmap = tiny_skia::Pixmap::new(self.size.0, self.size.1).unwrap();
|
||||
let scale = {
|
||||
let x = tree.size().width() / self.size.0 as f32;
|
||||
let y = tree.size().height() / self.size.0 as f32;
|
||||
x.min(y)
|
||||
};
|
||||
|
||||
// log::info!("Rendering {fo:?}");
|
||||
|
||||
//? maybe handle this and possibly throw error if its none
|
||||
let _ = resvg::render(&tree, usvg::FitTo::Size(self.size.0, self.size.1), tiny_skia::Transform::default(), pixmap.as_mut());
|
||||
resvg::render(&tree, usvg::Transform::default().post_scale(scale, scale), &mut pixmap.as_mut());
|
||||
cordlesscoder
commented
Please double check this replacement logic for FitTo Please double check this replacement logic for FitTo
silver
commented
Read the top comment on this page, then decide what ye want to do. Read the top comment on this page, then decide what ye want to do.
|
||||
|
||||
pixmap.save_png(fo)?;
|
||||
self.count += 1;
|
||||
|
|
|
@ -281,7 +281,7 @@ pub mod update_icon {
|
|||
|
||||
// check if exists
|
||||
if !path_new.exists() {
|
||||
// convert if it hasnt been converted already
|
||||
// convert if it hasn't been converted already
|
||||
match r.render(&path_local, &args) {
|
||||
Ok(_) => {}
|
||||
Err(_e) => {
|
||||
|
@ -349,7 +349,7 @@ pub mod update_icon {
|
|||
}
|
||||
|
||||
async fn logo_set(ctx: &Context, db: &Pool<Sqlite>, server: &GuildId, logo_selected: &LogoData) {
|
||||
// add to teh database
|
||||
// add to the database
|
||||
if !logo_set_db(db, logo_selected).await {
|
||||
// something went wrong
|
||||
return;
|
||||
|
|
|
@ -17,13 +17,11 @@ pub mod normal {
|
|||
}
|
||||
|
||||
pub async fn update_server(ctx: &Context, server: &Servers, remove_roles: &[Option<RoleId>], members_changed: &[UserId]) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Database in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let Servers {
|
||||
server,
|
||||
role_past,
|
||||
|
@ -48,7 +46,7 @@ pub mod normal {
|
|||
|
||||
if let Ok(x) = server.members(ctx, None, None).await {
|
||||
for member in x {
|
||||
// members_changed acts as an override to only deal with teh users in it
|
||||
// members_changed acts as an override to only deal with the users in it
|
||||
if !members_changed.is_empty() && !members_changed.contains(&member.user.id) {
|
||||
continue;
|
||||
}
|
||||
|
@ -84,7 +82,7 @@ pub mod normal {
|
|||
|
||||
if member.roles.contains(role_current) {
|
||||
roles_set.current_rem += 1;
|
||||
// if theya re not a current member and have the role then remove it
|
||||
// if they're not a current member and have the role then remove it
|
||||
if let Err(e) = member.remove_role(ctx, role_current).await {
|
||||
println!("{e:?}");
|
||||
}
|
||||
|
@ -174,13 +172,11 @@ pub mod committee {
|
|||
use std::collections::HashMap;
|
||||
|
||||
pub async fn check_committee(ctx: &Context) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<Config>().expect("Expected Config in TypeMap.").clone()
|
||||
|
@ -189,14 +185,14 @@ pub mod committee {
|
|||
|
||||
let server = config_global.committee_server;
|
||||
|
||||
// because to use it to update a single user we need to pre-get the members of teh server
|
||||
// because to use it to update a single user we need to pre-get the members of the server
|
||||
let mut members = server.members(&ctx, None, None).await.unwrap_or_default();
|
||||
|
||||
update_committees(&db, ctx, &config_global, &mut members).await;
|
||||
}
|
||||
|
||||
/**
|
||||
This function can take a vec of members (or just one) and gives tehm the appropiate roles on teh committee server
|
||||
This function can take a Vec of members (or just one) and gives them the appropriate roles on the committee server
|
||||
*/
|
||||
pub async fn update_committees(db: &Pool<Sqlite>, ctx: &Context, config: &Config, members: &mut Vec<Member>) {
|
||||
let server = config.committee_server;
|
||||
|
@ -228,11 +224,11 @@ pub mod committee {
|
|||
|
||||
let mut channels = server.channels(&ctx).await.unwrap_or_default();
|
||||
|
||||
// a map of users and the roles they are goign to be getting
|
||||
// a map of users and the roles they are going to be getting
|
||||
let mut users_roles = HashMap::new();
|
||||
|
||||
let mut re_order = false;
|
||||
// we need to create roles and channels if tehy dont already exist
|
||||
// we need to create roles and channels if they don't already exist
|
||||
let mut category_index = 0;
|
||||
let mut i = 0;
|
||||
loop {
|
||||
|
@ -298,7 +294,7 @@ pub mod committee {
|
|||
// save it to the db in case of crash or error
|
||||
db_role_set(db, &tmp).await;
|
||||
|
||||
// insert it into teh local cache
|
||||
// insert it into the local cache
|
||||
e.insert(tmp);
|
||||
|
||||
re_order = true;
|
||||
|
@ -331,7 +327,7 @@ pub mod committee {
|
|||
}
|
||||
}
|
||||
|
||||
// now we have a map of all users that should get roles time to go through all the folks on teh server
|
||||
// now we have a map of all users that should get roles time to go through all the folks on the server
|
||||
for member in members {
|
||||
// if member.user.id != 136522490632601600 {
|
||||
// continue;
|
||||
|
@ -367,7 +363,7 @@ pub mod committee {
|
|||
let has_committee_role = roles_current_id.contains(&committee_member);
|
||||
|
||||
if on_committee && !has_committee_role {
|
||||
// if there are committee roles then give the general purporse role
|
||||
// if there are committee roles then give the general purpose role
|
||||
roles_add.push(committee_member);
|
||||
}
|
||||
if !on_committee && has_committee_role {
|
||||
|
@ -405,10 +401,10 @@ pub mod committee {
|
|||
if re_order {
|
||||
let channel_id = role.id_channel.to_owned();
|
||||
if let Some(channel) = channels.get_mut(&channel_id) {
|
||||
// record the position of each of teh C&S channels
|
||||
// record the position of each of the C&S channels
|
||||
positions.push(channel.position);
|
||||
|
||||
// pull out teh channel names
|
||||
// pull out the channel names
|
||||
channel_names.push((role.name_channel.to_owned(), channel_id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
/**
|
||||
This file relates to anything that directly interacts with teh wolves API
|
||||
This file relates to anything that directly interacts with the wolves API
|
||||
*/
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
|
@ -69,11 +69,10 @@ pub mod cns {
|
|||
}
|
||||
|
||||
pub async fn get_wolves(ctx: &Context) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Database in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
@ -81,7 +80,7 @@ pub mod cns {
|
|||
};
|
||||
let config = config_lock.read().await;
|
||||
|
||||
// set up teh client
|
||||
// set up the client
|
||||
let wolves = wolves_oxidised::Client::new(&config.wolves_url, Some(&config.wolves_api));
|
||||
|
||||
for server_config in get_server_config_bulk(&db).await {
|
||||
|
@ -224,11 +223,10 @@ pub mod committees {
|
|||
}
|
||||
|
||||
pub async fn get_cns(ctx: &Context) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Database in TypeMap.").clone()
|
||||
};
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
|
|
15
src/lib.rs
|
@ -12,7 +12,7 @@ use tokio::sync::RwLock;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
// manages where teh database is stored
|
||||
// manages where the database is stored
|
||||
pub home: String,
|
||||
pub database: String,
|
||||
|
||||
|
@ -36,7 +36,7 @@ pub struct Config {
|
|||
pub committee_role: RoleId,
|
||||
pub committee_category: Vec<ChannelId>,
|
||||
|
||||
// items pertaining to compsoc only
|
||||
// items pertaining to CompSoc only
|
||||
pub compsoc_server: GuildId,
|
||||
}
|
||||
impl TypeMapKey for Config {
|
||||
|
@ -106,21 +106,20 @@ pub fn get_config() -> Config {
|
|||
}
|
||||
}
|
||||
if let Ok(x) = env::var("COMMITTEE_ROLE") {
|
||||
if let Ok(x) = x.trim().parse::<u64>() {
|
||||
if let Ok(x) = x.trim().parse() {
|
||||
config.committee_role = RoleId::new(x);
|
||||
}
|
||||
}
|
||||
if let Ok(x) = env::var("COMMITTEE_CATEGORY") {
|
||||
for part in x.split(',') {
|
||||
if let Ok(x) = part.trim().parse::<u64>() {
|
||||
config.committee_category.push(ChannelId::new(x));
|
||||
}
|
||||
let Ok(x) = part.trim().parse() else { continue };
|
||||
silver
commented
Fix it properly, this just changes it for teh sake of changing it Fix it properly, this just changes it for teh sake of changing it
cordlesscoder
commented
The logic is identical - in what way is this "improper", it's just less nested. The logic is identical - in what way is this "improper", it's just less nested.
|
||||
config.committee_category.push(ChannelId::new(x));
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(x) = env::var("COMPSOC_DISCORD") {
|
||||
if let Ok(x) = x.trim().parse::<u64>() {
|
||||
config.compsoc_server = GuildId::new(x);
|
||||
if let Ok(x) = x.trim().parse() {
|
||||
config.compsoc_server = GuildId::new(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
src/main.rs
|
@ -27,12 +27,11 @@ use sqlx::{Pool, Sqlite};
|
|||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
// Need To Define The Stuct (Committed To Bump The Bot)
|
||||
struct Handler;
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
// this caches members of all servers teh bot is in
|
||||
// this caches members of all servers the bot is in
|
||||
async fn cache_ready(&self, ctx: Context, guilds: Vec<GuildId>) {
|
||||
for guild in guilds {
|
||||
ctx.shard.chunk_guild(guild, Some(2000), false, ChunkGuildFilter::None, None);
|
||||
|
@ -42,13 +41,11 @@ impl EventHandler for Handler {
|
|||
|
||||
// handles previously linked accounts joining the server
|
||||
async fn guild_member_addition(&self, ctx: Context, new_member: Member) {
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
let config_lock = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<Config>().expect("Expected Config in TypeMap.").clone()
|
||||
|
@ -110,14 +107,12 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use
|
|||
// handles role updates
|
||||
async fn guild_member_update(&self, ctx: Context, _old_data: Option<Member>, new_data: Option<Member>, _: GuildMemberUpdateEvent) {
|
||||
// get config/db
|
||||
let db_lock = {
|
||||
let db = {
|
||||
let data_read = ctx.data.read().await;
|
||||
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
|
||||
};
|
||||
|
||||
let db = db_lock.read().await;
|
||||
|
||||
// check if the role changed is part of the oens for this server
|
||||
// check if the role changed is part of the ones for this server
|
||||
if let Some(x) = new_data {
|
||||
on_role_change(&db, &ctx, x).await;
|
||||
}
|
||||
|
@ -159,13 +154,13 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use
|
|||
}
|
||||
}
|
||||
|
||||
// compsoc Server
|
||||
// CompSoc Server
|
||||
match config
|
||||
.compsoc_server
|
||||
.set_commands(
|
||||
&ctx.http,
|
||||
vec![
|
||||
// commands just for the compsoc server
|
||||
// commands just for the CompSoc server
|
||||
commands::count::servers::register(),
|
||||
commands::server_icon::user::register(),
|
||||
],
|
||||
|
@ -182,7 +177,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use
|
|||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||
if let Interaction::Command(command) = interaction {
|
||||
let _ = command.defer_ephemeral(&ctx.http).await;
|
||||
//println!("Received command interaction: {:#?}", command);
|
||||
// println!("Received command interaction: {:#?}", command);
|
||||
|
||||
let content = match command.data.name.as_str() {
|
||||
// user commands
|
||||
|
@ -217,7 +212,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use
|
|||
format!("not implemented :( committee {}", x.name.as_str())
|
||||
}
|
||||
},
|
||||
// TODO: move teh minecraft commands in here as a subgroup
|
||||
// TODO: move the minecraft commands in here as a subgroup
|
||||
// "link" => commands::count::servers::run(&command, &ctx).await,
|
||||
&_ => format!("not implemented :( committee {}", x.name.as_str()),
|
||||
},
|
||||
|
@ -305,7 +300,7 @@ async fn main() {
|
|||
let mut data = client.data.write().await;
|
||||
|
||||
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
||||
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
||||
data.insert::<DataBase>(Arc::new(db));
|
||||
}
|
||||
|
||||
// Finally, start a single shard, and start listening to events.
|
||||
|
|
:3 I really like this (not too many folks know about this)