From 5b02a2621791984b9eff34b970190c08ac15b994 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 9 May 2021 10:38:55 +0200 Subject: [PATCH 1/2] Add "fuck" command closes #30 Signed-off-by: trivernis --- src/commands/misc/fuck.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/commands/misc/mod.rs | 4 +++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/commands/misc/fuck.rs diff --git a/src/commands/misc/fuck.rs b/src/commands/misc/fuck.rs new file mode 100644 index 0000000..22ec9c1 --- /dev/null +++ b/src/commands/misc/fuck.rs @@ -0,0 +1,38 @@ +use serenity::client::Context; +use serenity::framework::standard::macros::command; +use serenity::framework::standard::{Args, CommandResult}; +use serenity::model::channel::Message; +use serenity::model::id::UserId; + +#[command] +#[description("Fuck this person in particular")] +#[usage("[] []")] +#[min_args(1)] +#[max_args(3)] +#[bucket("general")] +#[aliases("frick", "fock")] +async fn fuck(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { + let person = args.single::()?; + let mut amount = args.single::().unwrap_or(3); + if amount > 10 { + amount = 10; + } + let mut verbosity = args.single::().unwrap_or(1); + if verbosity == 0 { + verbosity = 1 + } + let fuck_word = match verbosity { + 1 => "frick", + 2 => "flock", + 3 => "fock", + 4 => "fck", + _ => "fuck", + }; + for _ in 0..amount { + msg.channel_id + .say(&ctx, format!("{} <@{}>", fuck_word, person)) + .await?; + } + + Ok(()) +} diff --git a/src/commands/misc/mod.rs b/src/commands/misc/mod.rs index a0fa73e..e5be547 100644 --- a/src/commands/misc/mod.rs +++ b/src/commands/misc/mod.rs @@ -3,6 +3,7 @@ use serenity::framework::standard::macros::group; use about::ABOUT_COMMAND; use add_media::ADD_MEDIA_COMMAND; use clear::CLEAR_COMMAND; +use fuck::FUCK_COMMAND; use media::MEDIA_COMMAND; use pain::PAIN_COMMAND; use ping::PING_COMMAND; @@ -16,6 +17,7 @@ use xkcd::XKCD_COMMAND; mod about; mod add_media; mod clear; +mod fuck; pub(crate) mod help; mod media; mod pain; @@ -29,6 +31,6 @@ mod xkcd; #[group] #[commands( - ping, stats, shutdown, time, timezones, qalc, about, add_media, media, pain, clear, xkcd + ping, stats, shutdown, time, timezones, qalc, about, add_media, media, pain, clear, xkcd, fuck )] pub struct Misc; From 40f9a90a06f1664833198e99d266f6c425c3adb1 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 22 May 2021 14:46:55 +0200 Subject: [PATCH 2/2] Add theme command for anime themes Signed-off-by: trivernis --- Cargo.lock | 20 ++++++++--- Cargo.toml | 3 +- src/commands/weeb/mod.rs | 4 ++- src/commands/weeb/theme.rs | 38 +++++++++++++++++++++ src/messages/mod.rs | 1 + src/messages/theme.rs | 69 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 src/commands/weeb/theme.rs create mode 100644 src/messages/theme.rs diff --git a/Cargo.lock b/Cargo.lock index d1a5ca6..941fe67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "animethemes-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f85ae35b6d7efdd387a743cbf2d2bd1b8e9545d2c3e5abc85a1aa0e5ca99e5af" +dependencies = [ + "reqwest", + "serde", + "thiserror", +] + [[package]] name = "anyhow" version = "1.0.40" @@ -2058,9 +2069,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] @@ -2078,9 +2089,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -2528,6 +2539,7 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" name = "tobi-rs" version = "0.8.1" dependencies = [ + "animethemes-rs", "aspotify", "bot-coreutils", "bot-database", diff --git a/Cargo.toml b/Cargo.toml index 1acfa6d..dcdae68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,4 +40,5 @@ trigram = "0.4.4" typemap_rev = "0.1.5" youtube-metadata = "0.1.1" xkcd-search = "0.1.1" -lavalink-rs = {version="0.7.1", features=["native", "serenity"]} \ No newline at end of file +lavalink-rs = {version="0.7.1", features=["native", "serenity"]} +animethemes-rs = "0.2.1" \ No newline at end of file diff --git a/src/commands/weeb/mod.rs b/src/commands/weeb/mod.rs index de75e24..a4b8a6e 100644 --- a/src/commands/weeb/mod.rs +++ b/src/commands/weeb/mod.rs @@ -7,6 +7,7 @@ mod miko; mod pekofy; mod rushia; mod sauce; +mod theme; use crate::utils::context_data::get_database_from_context; use crate::utils::error::BotError; @@ -22,9 +23,10 @@ use miko::MIKO_COMMAND; use pekofy::PEKOFY_COMMAND; use rushia::RUSHIA_COMMAND; use sauce::SAUCE_COMMAND; +use theme::THEME_COMMAND; #[group] -#[commands(pekofy, sauce, matsuri, korone, rushia, fubuki, miko)] +#[commands(pekofy, sauce, matsuri, korone, rushia, fubuki, miko, theme)] pub struct Weeb; /// Posts a random media entry with the given category diff --git a/src/commands/weeb/theme.rs b/src/commands/weeb/theme.rs new file mode 100644 index 0000000..84fb763 --- /dev/null +++ b/src/commands/weeb/theme.rs @@ -0,0 +1,38 @@ +use crate::messages::theme::create_theme_menu; +use animethemes_rs::client::AnimeThemesClient; +use serenity::client::Context; +use serenity::framework::standard::macros::command; +use serenity::framework::standard::{Args, CommandResult}; +use serenity::model::channel::Message; +use serenity_rich_interaction::core::MEDIUM_TIMEOUT; +use serenity_rich_interaction::ephemeral_message::EphemeralMessage; + +#[command] +#[description("Query for the opening/ending/insert song of an anime")] +#[usage("")] +#[aliases("animetheme", "anime-theme", "opening", "ending", "ost")] +#[bucket("general")] +async fn theme(ctx: &Context, msg: &Message, args: Args) -> CommandResult { + let query = args.message(); + let client = AnimeThemesClient::default(); + let themes = client + .search(query, &["entries"], &["theme", "theme.anime", "videos"]) + .await?; + if let Some(entries) = themes.entries { + if entries.is_empty() { + EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| { + c.reference_message(msg).content("No themes found") + }) + .await?; + } else { + create_theme_menu(ctx, msg.channel_id, entries).await?; + } + } else { + EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| { + c.reference_message(msg).content("No themes found") + }) + .await?; + } + + Ok(()) +} diff --git a/src/messages/mod.rs b/src/messages/mod.rs index bad0c06..3cc3f3c 100644 --- a/src/messages/mod.rs +++ b/src/messages/mod.rs @@ -8,6 +8,7 @@ pub mod gifs; pub mod minecraft; pub mod music; pub mod sauce; +pub mod theme; pub mod xkcd; /// Adds an ephemeral message to the database diff --git a/src/messages/theme.rs b/src/messages/theme.rs new file mode 100644 index 0000000..f321534 --- /dev/null +++ b/src/messages/theme.rs @@ -0,0 +1,69 @@ +use crate::utils::error::BotResult; +use animethemes_rs::models::{ThemeEntry, ThemeType}; +use serenity::builder::CreateMessage; +use serenity::client::Context; +use serenity::model::id::ChannelId; +use serenity_rich_interaction::core::EXTRA_LONG_TIMEOUT; +use serenity_rich_interaction::menu::{MenuBuilder, Page}; + +/// Creates a new Anime Theme Menu +pub async fn create_theme_menu( + ctx: &Context, + channel_id: ChannelId, + mut entries: Vec, +) -> BotResult<()> { + let nsfw = ctx.http.get_channel(channel_id.0).await?.is_nsfw(); + entries.sort_by_key(|t| { + if let Some(theme) = &t.theme { + match &theme.theme_type { + ThemeType::OP => theme.sequence.unwrap_or(1), + ThemeType::ED => theme.sequence.unwrap_or(1) * 100, + } + } else { + 10000 + } + }); + MenuBuilder::new_paginator() + .add_pages( + entries + .into_iter() + .filter(|e| { + if !nsfw && e.nsfw { + return false; + } + if let Some(videos) = &e.videos { + !videos.is_empty() + } else { + false + } + }) + .map(|e| create_theme_page(e, nsfw)), + ) + .timeout(EXTRA_LONG_TIMEOUT) + .build(ctx, channel_id) + .await?; + + Ok(()) +} + +/// Creates a new anime theme page +fn create_theme_page(entry: ThemeEntry, nsfw: bool) -> Page<'static> { + let mut message = CreateMessage::default(); + let videos = entry.videos.unwrap(); + let theme = entry.theme.unwrap(); + let anime = theme.anime.unwrap(); + let theme_type = match theme.theme_type { + ThemeType::OP => "Opening", + ThemeType::ED => "Ending", + }; + + message.content(format!( + "**{} {}** of **{}**\nhttps://animethemes.moe/video/{}", + theme_type, + theme.sequence.unwrap_or(1), + anime.name, + videos.first().unwrap().basename + )); + + Page::Static(message) +}