Update dependencies, remote unnecessary RwLock on database, fix typos #43

Closed
cordlesscoder wants to merge 8 commits from cordlesscoder/discord-bot:main into main
25 changed files with 1165 additions and 1044 deletions

2
.git-blame-ignore-revs Normal file
View file

@ -0,0 +1,2 @@
# Fix typos
4b4e5cb2894346684034cba93a5ac1ec6f884f9f
silver marked this conversation as resolved

:3 I really like this (not too many folks know about this)

:3 I really like this (not too many folks know about this)

View file

@ -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
View file

@ -0,0 +1,2 @@
[formatting]
column_width = 120

1889
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -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

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"

View file

@ -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

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.

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.
- 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

```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;
}

View file

@ -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 {

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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) => {

View file

@ -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;

View file

@ -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()
}

View file

@ -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);

View file

@ -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;

View file

@ -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()

View file

@ -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)]

View file

@ -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

View file

@ -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());

Please double check this replacement logic for FitTo

Please double check this replacement logic for FitTo

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;

View file

@ -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;

View file

@ -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));
}
}

View file

@ -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;

View file

@ -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 };

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

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)
}
}

View file

@ -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.