From 0fa6878d82f0d1509ebf5a660f0eb9c8cf62973b Mon Sep 17 00:00:00 2001 From: 1Kill2Steal <171241044+1Git2Clone@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:59:05 +0200 Subject: [PATCH] Reformat URL gathering + add network tests --- Cargo.toml | 2 + src/commands/cmd_utils.rs | 27 +++++ src/commands/embed_commands/boom.rs | 4 +- src/data/bot_data.rs | 1 + src/data/embed_media.rs | 164 +++++++++++++++++++--------- src/event_handler/handler.rs | 16 ++- src/tests/mod.rs | 6 +- src/tests/urls.rs | 17 +++ 8 files changed, 175 insertions(+), 62 deletions(-) create mode 100644 src/tests/urls.rs diff --git a/Cargo.toml b/Cargo.toml index 8b62e51..3c977d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,9 @@ sqlx = { version = "0.8.2", features = ["runtime-tokio-rustls", "sqlite"] } chrono = "0.4.35" rayon = "1.10.0" regex = "1.11.1" +reqwest = "0.12.9" [features] serde = ["dep:serde"] debug = [] +network_test = [] diff --git a/src/commands/cmd_utils.rs b/src/commands/cmd_utils.rs index ad80b40..a92159d 100644 --- a/src/commands/cmd_utils.rs +++ b/src/commands/cmd_utils.rs @@ -8,6 +8,33 @@ use poise::serenity_prelude as serenity; use rand::prelude::SliceRandom; use sqlx::error::BoxDynError; +/// Works by prepending the `ASSETS_URL` to the `asset_file_name`. +/// +/// ```rust +/// use serenity_discord_bot::asset_url; +/// use serenity_discord_bot::commands::cmd_utils::HU_BOOM_URL; +/// +/// assert_eq!( +/// "https://raw.githubusercontent.com/1Git2Clone/serenity-discord-bot/main/src/assets/hu_boom.jpg", +/// asset_url!("hu_boom.jpg") +/// ); +/// assert_eq!( +/// "https://raw.githubusercontent.com/1Git2Clone/serenity-discord-bot/main/src/assets/hu_boom.jpg", +/// HU_BOOM_URL +/// ); +/// ``` +#[macro_export] +macro_rules! asset_url { + ($expr:expr) => { + concat!( + "https://raw.githubusercontent.com/1Git2Clone/serenity-discord-bot/main/src/assets/", + $expr + ) + }; +} + +pub const HU_BOOM_URL: &str = asset_url!("hu_boom.jpg"); + pub async fn get_replied_user(ctx: Context<'_>) -> &serenity::User { let poise::Context::Prefix(msg_ctx) = ctx else { return ctx.author(); diff --git a/src/commands/embed_commands/boom.rs b/src/commands/embed_commands/boom.rs index d331064..6b03415 100644 --- a/src/commands/embed_commands/boom.rs +++ b/src/commands/embed_commands/boom.rs @@ -1,3 +1,5 @@ +use cmd_utils::HU_BOOM_URL; + use super::*; /// Just try it. @@ -9,7 +11,7 @@ pub async fn boom(ctx: Context<'_>) -> Result<(), Error> { ctx.send( poise::CreateReply::default().embed( serenity::CreateEmbed::default() - .image("https://raw.githubusercontent.com/1Git2Clone/serenity-discord-bot/main/src/assets/hu_boom.jpg") + .image(HU_BOOM_URL) .color((255, 0, 0)) .footer(serenity::CreateEmbedFooter::new(bot_user.tag()).icon_url(bot_avatar)), ), diff --git a/src/data/bot_data.rs b/src/data/bot_data.rs index 1904340..886db2d 100644 --- a/src/data/bot_data.rs +++ b/src/data/bot_data.rs @@ -40,4 +40,5 @@ lazy_static! { // https://regex101.com/r/aX8vec/5 pub(crate) static ref EMOJIS_AND_EMBEDS_REGEX: Regex = Regex::new(r"(?(:)([a-zA-Z0-9_]+)(:))|(?(\[)([a-zA-Z0-9_]+)(\])\([^()]*\))").unwrap(); + } diff --git a/src/data/embed_media.rs b/src/data/embed_media.rs index 1199d15..4501af1 100644 --- a/src/data/embed_media.rs +++ b/src/data/embed_media.rs @@ -2,90 +2,104 @@ use crate::enums::command_enums::EmbedType; use lazy_static::lazy_static; use std::collections::HashMap; +#[macro_export] +macro_rules! cdn_url { + ($expr:expr) => { + concat!("https://cdn.discordapp.com/attachments/", $expr) + }; +} + +#[macro_export] +macro_rules! media_url { + ($expr:expr) => { + concat!("https://media.discordapp.net/attachments/", $expr) + }; +} + lazy_static! { pub(crate) static ref COMMANDS: HashMap> = { let tieup_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1183349571468918814/tied-up-aiura.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1183694079847059517/ezgif.com-video-to-gif.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183694247724077056/sasha-blouse.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1192391499376230511/8mb.video-Rjm-kx7W5rXN1.gif", + cdn_url!("614790390020833280/1183349571468918814/tied-up-aiura.gif"), + cdn_url!("1180115044218978425/1183694079847059517/ezgif.com-video-to-gif.gif"), + cdn_url!("614790390020833280/1183694247724077056/sasha-blouse.gif"), + cdn_url!("614790390020833280/1192391499376230511/8mb.video-Rjm-kx7W5rXN1.gif"), ]; let pat_array = vec![ - "https://media.discordapp.net/attachments/1187355380087537668/1212438556409077831/gQIhfkz.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183461602700316673/kanna-kamui-pat.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183461632718950460/pat.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183461661181497364/mai-sakurajima.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183493730339139694/hu-tao-hug.gif", + media_url!("1187355380087537668/1212438556409077831/gQIhfkz.gif"), + cdn_url!("614790390020833280/1183461602700316673/kanna-kamui-pat.gif"), + cdn_url!("614790390020833280/1183461632718950460/pat.gif"), + cdn_url!("614790390020833280/1183461661181497364/mai-sakurajima.gif"), + cdn_url!("614790390020833280/1183493730339139694/hu-tao-hug.gif"), ]; let hug_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1183462503364186112/hug.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183462503011844096/anime-hug-anime-hugging.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1183462502630174740/hug-surprise-chuunibyou.gif" + cdn_url!("614790390020833280/1183462503364186112/hug.gif"), + cdn_url!("614790390020833280/1183462503011844096/anime-hug-anime-hugging.gif"), + cdn_url!("614790390020833280/1183462502630174740/hug-surprise-chuunibyou.gif"), ]; let kiss_array = vec![ - "https://media.discordapp.net/attachments/614790390020833280/1184153815767855234/hutao-kiss.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184153816187277462/kiss.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184153816644468766/cute-kawai.gif", + media_url!("614790390020833280/1184153815767855234/hutao-kiss.gif"), + media_url!("614790390020833280/1184153816187277462/kiss.gif"), + media_url!("614790390020833280/1184153816644468766/cute-kawai.gif"), ]; let slap_array = vec![ - "https://media.discordapp.net/attachments/614790390020833280/1184154726238007349/genshin-impact-venti.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184154726670028882/slap.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184154727286579210/anime-slap-mad.gif", + media_url!("614790390020833280/1184154726238007349/genshin-impact-venti.gif"), + media_url!("614790390020833280/1184154726670028882/slap.gif"), + media_url!("614790390020833280/1184154727286579210/anime-slap-mad.gif"), ]; let punch_array = vec![ - "https://media.discordapp.net/attachments/614790390020833280/1184154350172508222/one-punch.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184154350575169568/anime-fight.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184154351049113761/anime-smash.gif", + media_url!("614790390020833280/1184154350172508222/one-punch.gif"), + media_url!("614790390020833280/1184154350575169568/anime-fight.gif"), + media_url!("614790390020833280/1184154351049113761/anime-smash.gif"), ]; let bonk_array = vec![ - "https://media.discordapp.net/attachments/614790390020833280/1184200805738348696/powerful-head-slap.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184200806245879828/atonnic-bonk.gif", - "https://media.discordapp.net/attachments/614790390020833280/1184200806673686608/shinji-shinji-broom.gif", + media_url!("614790390020833280/1184200805738348696/powerful-head-slap.gif"), + media_url!("614790390020833280/1184200806245879828/atonnic-bonk.gif"), + media_url!("614790390020833280/1184200806673686608/shinji-shinji-broom.gif"), ]; let ryan_gosling_drive_array = vec![ - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222721546756216/giphy.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222722037481573/ryan-gosling-car.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222722545000488/ryan-gosling.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222722926674013/ryan-gosling-ryan-gosling-drive.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222728068911134/ryan-gosling-drive.gif", - "https://cdn.discordapp.com/attachments/1180115044218978425/1185222728568021042/driving-ryan-gosling.gif", + cdn_url!("1180115044218978425/1185222721546756216/giphy.gif"), + cdn_url!("1180115044218978425/1185222722037481573/ryan-gosling-car.gif"), + cdn_url!("1180115044218978425/1185222722545000488/ryan-gosling.gif"), + cdn_url!("1180115044218978425/1185222722926674013/ryan-gosling-ryan-gosling-drive.gif"), + cdn_url!("1180115044218978425/1185222728068911134/ryan-gosling-drive.gif"), + cdn_url!("1180115044218978425/1185222728568021042/driving-ryan-gosling.gif"), ]; let nom_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1185289189097476216/vsauce-michael-stevens.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185289189697278162/eatin-anima.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185289190070550688/paimon-genshin.gif", + cdn_url!("614790390020833280/1185289189097476216/vsauce-michael-stevens.gif"), + cdn_url!("614790390020833280/1185289189697278162/eatin-anima.gif"), + cdn_url!("614790390020833280/1185289190070550688/paimon-genshin.gif"), ]; let kill_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1185293538485870724/dead.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185293538875936899/die-kill.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185293539232460820/ira-gamagoori-attack.gif", - "https://cdn.discordapp.com/attachments/904591166580879400/1185318839177728020/wasted-wastedmidi.gif", + cdn_url!("614790390020833280/1185293538485870724/dead.gif"), + cdn_url!("614790390020833280/1185293538875936899/die-kill.gif"), + cdn_url!("614790390020833280/1185293539232460820/ira-gamagoori-attack.gif"), + cdn_url!("904591166580879400/1185318839177728020/wasted-wastedmidi.gif"), ]; let kick_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1185566729104019486/falling-from-window-anime-death.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185566728541966458/mad-angry.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185566727845720195/kick-funny.gif", + cdn_url!("614790390020833280/1185566729104019486/falling-from-window-anime-death.gif"), + cdn_url!("614790390020833280/1185566728541966458/mad-angry.gif"), + cdn_url!("614790390020833280/1185566727845720195/kick-funny.gif"), ]; let bury_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1185635484412694549/mark-cooper-jones-jay-foreman.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185635484945354862/nohemy-noh.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185635485545144331/grave-rip.gif", + cdn_url!("614790390020833280/1185635484412694549/mark-cooper-jones-jay-foreman.gif"), + cdn_url!("614790390020833280/1185635484945354862/nohemy-noh.gif"), + cdn_url!("614790390020833280/1185635485545144331/grave-rip.gif"), ]; let self_bury_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1185635416989253652/spongebob-squarepants-spongebob.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1185635416594993172/dead-bury.gif" + cdn_url!("614790390020833280/1185635416989253652/spongebob-squarepants-spongebob.gif"), + cdn_url!("614790390020833280/1185635416594993172/dead-bury.gif"), ]; let chair_array = vec![ - "https://cdn.discordapp.com/attachments/614790390020833280/1186285033779122207/20231218_143252.gif", - "https://cdn.discordapp.com/attachments/614790390020833280/1186290567190171658/vergil-chair.gif", + cdn_url!("614790390020833280/1186285033779122207/20231218_143252.gif"), + cdn_url!("614790390020833280/1186290567190171658/vergil-chair.gif"), ]; let peek_array = vec![ - "https://media.discordapp.net/attachments/614790390020833280/1203304453512372235/Hh4nIiw.gif", - "https://media.discordapp.net/attachments/614790390020833280/1203304454074671155/wkPTm8l.gif", - "https://media.discordapp.net/attachments/614790390020833280/1203304454582173696/aI1RZsy.gif", - "https://media.discordapp.net/attachments/614790390020833280/1203304455043420200/4XviQL7.gif", - "https://media.discordapp.net/attachments/614790390020833280/1203304455554994226/wH7kSo2.gif", - "https://media.discordapp.net/attachments/614790390020833280/1203304456007974942/1SMUFuk.gif", + media_url!("614790390020833280/1203304453512372235/Hh4nIiw.gif"), + media_url!("614790390020833280/1203304454074671155/wkPTm8l.gif"), + media_url!("614790390020833280/1203304454582173696/aI1RZsy.gif"), + media_url!("614790390020833280/1203304455043420200/4XviQL7.gif"), + media_url!("614790390020833280/1203304455554994226/wH7kSo2.gif"), + media_url!("614790390020833280/1203304456007974942/1SMUFuk.gif"), ]; HashMap::from([ @@ -111,15 +125,57 @@ lazy_static! { #[cfg(test)] mod tests { use super::*; + use crate::data::command_data::Error; /// It is highly encouraged to run this test to check whether or not all your arrays have a /// vector with at least 1 link in it. If you don't run this test or if this test gives out an /// error, then that means that your program will panic if a user tries to get an embed_type /// from the key-value HashMap pair. #[test] - fn test_vecs_not_empty() { + fn test_vecs_not_empty() -> Result<(), Error> { for (embed_type, vec) in COMMANDS.iter() { assert!(!vec.is_empty(), "{:?} array is empty", embed_type); } + + Ok(()) + } + + // NOTE: I don't recommend you run this test more than once or twice due to the chance of you + // getting rate limited, however, it's still important to assert all the URLs are correct. + #[cfg(feature = "network_test")] + #[tokio::test] + async fn test_bad_request() -> Result<(), Error> { + use reqwest::{Client, StatusCode}; + let client = Client::new(); + + for (_, vec) in COMMANDS.iter() { + for url in vec.iter() { + match client.head(*url).send().await { + Ok(resp) => match resp.status() { + StatusCode::OK => (), + StatusCode::BAD_REQUEST => { + return Err(format!( + "Bad request! ({}) (at URL: {})", + resp.status(), + url + ) + .into()) + } + code @ StatusCode::NOT_FOUND => { + // NOTE: Not guaranteed to be a hard error! This is due to discord's + // url query parameters, giving a 404 if the content is expried. + eprintln!("{} | URL: {}", code, url); + + let response_body = reqwest::get(*url).await?.text().await?; + assert_eq!(response_body, "This content is no longer available."); + } + code => return Err(format!("{} | URL: {}", code, url).into()), + }, + Err(err) => return Err(format!("{} | URL: {}", err, url).into()), + } + } + } + + Ok(()) } } diff --git a/src/event_handler/handler.rs b/src/event_handler/handler.rs index 416224d..66ec671 100644 --- a/src/event_handler/handler.rs +++ b/src/event_handler/handler.rs @@ -5,9 +5,11 @@ //! poise::serenity_prelude::FullEvent enum can be found on the poise documentation page: //! https://docs.rs/poise/latest/poise/serenity_prelude/enum.FullEvent.html +#[cfg(feature = "debug")] +use crate::data::bot_data::START_TIME; use crate::{ data::{ - bot_data::{DATABASE_FILENAME, START_TIME}, + bot_data::DATABASE_FILENAME, command_data::{Data, Error}, database_interactions::*, }, @@ -23,14 +25,15 @@ pub async fn event_handler( data: &Data, ) -> Result<(), Error> { match event { + #[cfg(feature = "debug")] serenity::FullEvent::Ready { data_about_bot, .. } => { - #[cfg(feature = "debug")] println!( "\n!!! DISCORD BOT STARTED SUCCESSFULLY IN {} MILISECONDS !!!\nFrameworks : [serenity, poise]\nAsync runtime: [tokio]\n\n=> Logged in as: {}", START_TIME.elapsed().as_millis(), data_about_bot.user.tag() ); } + serenity::FullEvent::Ratelimit { data } => { eprintln!( "- (!) - There's a rate limit for the bot right now! [{:?} seconds left!]", @@ -45,8 +48,8 @@ pub async fn event_handler( msg => { #[cfg(feature = "debug")] println!( - "! NEW MESSAGE !\nGuildID: {}\nUserID: {}\nUsername: {}\nMsg: {}\n", - &new_message.guild_id.unwrap_or_default(), + "! NEW MESSAGE !\nGuildID: {:?}\nUserID: {}\nUsername: {}\nMsg: {}\n", + &new_message.guild_id, &new_message.author.id, &new_message.author.name, &new_message.content, @@ -76,8 +79,9 @@ pub async fn event_handler( let status = add_or_update_db_user(pool, new_message, ctx, obtained_xp).await; - #[cfg(feature = "debug")] - println!("Status: {:#?}", status); + if let Err(err) = status { + eprintln!("{}", err); + } } Err(why) => eprintln!("Failed to connect to the database: {why:?}"), } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index d7afa7f..793a4e9 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,4 +1,8 @@ -#[cfg(test)] +#![cfg(test)] + +#[cfg(feature = "network_test")] +mod urls; + fn sized_send_sunc_unpin() {} #[test] diff --git a/src/tests/urls.rs b/src/tests/urls.rs new file mode 100644 index 0000000..7965309 --- /dev/null +++ b/src/tests/urls.rs @@ -0,0 +1,17 @@ +use reqwest::StatusCode; + +use crate::commands::cmd_utils::HU_BOOM_URL; +use crate::data::command_data::Error; + +#[tokio::test] +async fn test_valid_asset_url() -> Result<(), Error> { + use reqwest::Client; + + let client = Client::new(); + + let response = client.head(HU_BOOM_URL).send().await?; + + assert_eq!(response.status(), StatusCode::OK); + + Ok(()) +}