Merge pull request #37 from Trivernis/develop

Develop
pull/38/head v0.9.4
Julius Riegel 3 years ago committed by GitHub
commit 53dec9740e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

10
Cargo.lock generated

@ -28,9 +28,9 @@ dependencies = [
[[package]] [[package]]
name = "animethemes-rs" name = "animethemes-rs"
version = "0.2.1" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f85ae35b6d7efdd387a743cbf2d2bd1b8e9545d2c3e5abc85a1aa0e5ca99e5af" checksum = "b717f29f786445f30818874943f9c7c6ad370804cc7a345d3f0bae3c85163d17"
dependencies = [ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
@ -2208,9 +2208,9 @@ dependencies = [
[[package]] [[package]]
name = "serenity-rich-interaction" name = "serenity-rich-interaction"
version = "0.2.3" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8151b0ce52fdbcc8834a0b6788ff67baf83dea37a4050462c2b5ae2621b87821" checksum = "9e29c534ec1387d4a0849587494e03acfb9780335468d9936f19af00f5fd0178"
dependencies = [ dependencies = [
"futures", "futures",
"log 0.4.14", "log 0.4.14",
@ -2575,7 +2575,7 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tobi-rs" name = "tobi-rs"
version = "0.9.3" version = "0.9.4"
dependencies = [ dependencies = [
"animethemes-rs", "animethemes-rs",
"aspotify", "aspotify",

@ -1,6 +1,6 @@
[package] [package]
name = "tobi-rs" name = "tobi-rs"
version = "0.9.3" version = "0.9.4"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
@ -12,7 +12,7 @@ panic = 'abort'
[dependencies] [dependencies]
bot-database = {path="./bot-database"} bot-database = {path="./bot-database"}
bot-coreutils = {path="./bot-coreutils"} bot-coreutils = {path="./bot-coreutils"}
serenity-rich-interaction = "0.2.2" serenity-rich-interaction = "0.2.5"
serenity = "0.10.5" serenity = "0.10.5"
dotenv = "0.15.0" dotenv = "0.15.0"
tokio = { version = "1.4.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.4.0", features = ["macros", "rt-multi-thread"] }
@ -41,4 +41,4 @@ typemap_rev = "0.1.5"
youtube-metadata = "0.1.1" youtube-metadata = "0.1.1"
xkcd-search = "0.1.1" xkcd-search = "0.1.1"
lavalink-rs = {version="0.7.1", features=["native", "serenity"]} lavalink-rs = {version="0.7.1", features=["native", "serenity"]}
animethemes-rs = "0.2.1" animethemes-rs = "0.3.0"

@ -10,7 +10,7 @@ use serenity::model::channel::Message;
#[aliases("inspireme", "inspire-me", "inspiro")] #[aliases("inspireme", "inspire-me", "inspiro")]
#[bucket("general")] #[bucket("general")]
async fn inspirobot(ctx: &Context, msg: &Message) -> CommandResult { async fn inspirobot(ctx: &Context, msg: &Message) -> CommandResult {
create_inspirobot_menu(ctx, msg.channel_id).await?; create_inspirobot_menu(ctx, msg.channel_id, msg.author.id).await?;
Ok(()) Ok(())
} }

@ -12,7 +12,7 @@ use serenity::model::channel::Message;
async fn media(ctx: &Context, msg: &Message) -> CommandResult { async fn media(ctx: &Context, msg: &Message) -> CommandResult {
let database = get_database_from_context(ctx).await; let database = get_database_from_context(ctx).await;
let gifs = database.get_all_media().await?; let gifs = database.get_all_media().await?;
create_media_menu(ctx, msg.channel_id, gifs).await?; create_media_menu(ctx, msg.channel_id, gifs, msg.author.id).await?;
Ok(()) Ok(())
} }

@ -29,7 +29,7 @@ async fn xkcd(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
vec![xkcd_search::get_latest_comic().await?] vec![xkcd_search::get_latest_comic().await?]
}; };
create_xkcd_menu(ctx, msg.channel_id, comics).await?; create_xkcd_menu(ctx, msg.channel_id, comics, msg.author.id).await?;
Ok(()) Ok(())
} }

@ -7,7 +7,7 @@ use serenity::model::channel::Message;
#[command] #[command]
#[description("Posts a random gura")] #[description("Posts a random gura")]
#[usage("")] #[usage("")]
#[aliases("shark", "city-pop-shark", "same")] #[aliases("a", "shark", "city-pop-shark", "same")]
#[bucket("general")] #[bucket("general")]
async fn gura(ctx: &Context, msg: &Message) -> CommandResult { async fn gura(ctx: &Context, msg: &Message) -> CommandResult {
post_random_media(ctx, msg, "gura").await post_random_media(ctx, msg, "gura").await

@ -1,5 +1,6 @@
use crate::messages::theme::create_theme_menu; use crate::messages::theme::create_theme_menu;
use animethemes_rs::client::AnimeThemesClient; use animethemes_rs::client::AnimeThemesClient;
use animethemes_rs::includes;
use serenity::client::Context; use serenity::client::Context;
use serenity::framework::standard::macros::command; use serenity::framework::standard::macros::command;
use serenity::framework::standard::{Args, CommandResult}; use serenity::framework::standard::{Args, CommandResult};
@ -10,22 +11,31 @@ use serenity_rich_interaction::ephemeral_message::EphemeralMessage;
#[command] #[command]
#[description("Query for the opening/ending/insert song of an anime")] #[description("Query for the opening/ending/insert song of an anime")]
#[usage("<query..>")] #[usage("<query..>")]
#[min_args(1)]
#[aliases("animetheme", "anime-theme", "opening", "ending", "ost")] #[aliases("animetheme", "anime-theme", "opening", "ending", "ost")]
#[bucket("general")] #[bucket("general")]
async fn theme(ctx: &Context, msg: &Message, args: Args) -> CommandResult { async fn theme(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
let query = args.message(); let query = args.message();
let client = AnimeThemesClient::default(); let client = AnimeThemesClient::default();
let themes = client let search_results = client
.search(query, &["entries"], &["theme", "theme.anime", "videos"]) .search(
query,
&[includes::ANIME],
&[
"animethemes",
"animethemes.animethemeentries",
"animethemes.animethemeentries.videos",
],
)
.await?; .await?;
if let Some(entries) = themes.entries { if let Some(anime) = search_results.anime {
if entries.is_empty() { if anime.is_empty() {
EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| { EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| {
c.reference_message(msg).content("No themes found") c.reference_message(msg).content("No themes found")
}) })
.await?; .await?;
} else { } else {
create_theme_menu(ctx, msg.channel_id, entries).await?; create_theme_menu(ctx, msg.channel_id, anime, msg.author.id).await?;
} }
} else { } else {
EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| { EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |c| {

@ -2,7 +2,7 @@ use crate::utils::error::BotResult;
use bot_database::models::Media; use bot_database::models::Media;
use serenity::builder::CreateMessage; use serenity::builder::CreateMessage;
use serenity::client::Context; use serenity::client::Context;
use serenity::model::id::ChannelId; use serenity::model::id::{ChannelId, UserId};
use serenity_rich_interaction::menu::{MenuBuilder, Page}; use serenity_rich_interaction::menu::{MenuBuilder, Page};
use std::time::Duration; use std::time::Duration;
@ -11,6 +11,7 @@ pub async fn create_media_menu(
ctx: &Context, ctx: &Context,
channel_id: ChannelId, channel_id: ChannelId,
media: Vec<Media>, media: Vec<Media>,
owner: UserId,
) -> BotResult<()> { ) -> BotResult<()> {
let total_pages = (media.len() as f32 / 10.0).ceil() as usize; let total_pages = (media.len() as f32 / 10.0).ceil() as usize;
let pages: Vec<Page> = media let pages: Vec<Page> = media
@ -23,6 +24,7 @@ pub async fn create_media_menu(
.timeout(Duration::from_secs(120)) .timeout(Duration::from_secs(120))
.add_pages(pages) .add_pages(pages)
.show_help() .show_help()
.owner(owner)
.build(ctx, channel_id) .build(ctx, channel_id)
.await?; .await?;

@ -2,21 +2,29 @@ use crate::providers::music::inspirobot::get_inspirobot_image;
use crate::utils::error::BotResult; use crate::utils::error::BotResult;
use serenity::builder::CreateMessage; use serenity::builder::CreateMessage;
use serenity::client::Context; use serenity::client::Context;
use serenity::model::id::ChannelId; use serenity::model::id::{ChannelId, UserId};
use serenity_rich_interaction::core::EXTRA_LONG_TIMEOUT; use serenity_rich_interaction::core::EXTRA_LONG_TIMEOUT;
use serenity_rich_interaction::menu::{display_page, MenuBuilder, Page}; use serenity_rich_interaction::menu::{
close_menu, display_page, MenuBuilder, Page, CLOSE_MENU_EMOJI,
};
static REFRESH_CONTROL: &str = "🔄"; static REFRESH_EMOJI: &str = "🔄";
pub async fn create_inspirobot_menu(ctx: &Context, channel_id: ChannelId) -> BotResult<()> { pub async fn create_inspirobot_menu(
ctx: &Context,
channel_id: ChannelId,
owner: UserId,
) -> BotResult<()> {
MenuBuilder::default() MenuBuilder::default()
.add_control(0, REFRESH_CONTROL, |ctx, menu, _r| { .add_control(0, REFRESH_EMOJI, |ctx, menu, _r| {
Box::pin(async move { Box::pin(async move {
display_page(ctx, menu).await?; display_page(ctx, menu).await?;
Ok(()) Ok(())
}) })
}) })
.add_help(REFRESH_CONTROL, "Creates a new inspiring image.") .add_help(REFRESH_EMOJI, "Creates a new inspiring image.")
.add_control(1, CLOSE_MENU_EMOJI, |c, m, r| Box::pin(close_menu(c, m, r)))
.add_help(CLOSE_MENU_EMOJI, "Closes this menu.")
.show_help() .show_help()
.add_page(Page::new_builder(|| { .add_page(Page::new_builder(|| {
Box::pin(async { Box::pin(async {
@ -26,6 +34,7 @@ pub async fn create_inspirobot_menu(ctx: &Context, channel_id: ChannelId) -> Bot
Ok(message) Ok(message)
}) })
})) }))
.owner(owner)
.timeout(EXTRA_LONG_TIMEOUT) .timeout(EXTRA_LONG_TIMEOUT)
.build(ctx, channel_id) .build(ctx, channel_id)
.await?; .await?;
@ -36,7 +45,11 @@ pub async fn create_inspirobot_menu(ctx: &Context, channel_id: ChannelId) -> Bot
async fn create_inspirobot_page<'a>() -> BotResult<CreateMessage<'a>> { async fn create_inspirobot_page<'a>() -> BotResult<CreateMessage<'a>> {
let image = get_inspirobot_image().await?; let image = get_inspirobot_image().await?;
let mut message = CreateMessage::default(); let mut message = CreateMessage::default();
message.embed(|e| e.image(image).title("Be inspired")); message.embed(|e| {
e.image(image)
.title("Be inspired")
.footer(|f| f.text("Powered by inspirobot.me"))
});
Ok(message) Ok(message)
} }

@ -1,8 +1,8 @@
use crate::utils::error::BotResult; use crate::utils::error::BotResult;
use animethemes_rs::models::{ThemeEntry, ThemeType}; use animethemes_rs::models::{Anime, ThemeEntry, ThemeType};
use serenity::builder::CreateMessage; use serenity::builder::CreateMessage;
use serenity::client::Context; use serenity::client::Context;
use serenity::model::id::ChannelId; use serenity::model::id::{ChannelId, UserId};
use serenity_rich_interaction::core::EXTRA_LONG_TIMEOUT; use serenity_rich_interaction::core::EXTRA_LONG_TIMEOUT;
use serenity_rich_interaction::menu::{MenuBuilder, Page}; use serenity_rich_interaction::menu::{MenuBuilder, Page};
@ -10,11 +10,12 @@ use serenity_rich_interaction::menu::{MenuBuilder, Page};
pub async fn create_theme_menu( pub async fn create_theme_menu(
ctx: &Context, ctx: &Context,
channel_id: ChannelId, channel_id: ChannelId,
mut entries: Vec<ThemeEntry>, mut anime_entries: Vec<Anime>,
owner: UserId,
) -> BotResult<()> { ) -> BotResult<()> {
let nsfw = ctx.http.get_channel(channel_id.0).await?.is_nsfw(); let nsfw = ctx.http.get_channel(channel_id.0).await?.is_nsfw();
entries.sort_by_key(|t| { anime_entries.sort_by_key(|a| {
if let Some(theme) = &t.theme { if let Some(theme) = a.themes.as_ref().and_then(|t| t.first()) {
match &theme.theme_type { match &theme.theme_type {
ThemeType::OP => theme.sequence.unwrap_or(1), ThemeType::OP => theme.sequence.unwrap_or(1),
ThemeType::ED => theme.sequence.unwrap_or(1) * 100, ThemeType::ED => theme.sequence.unwrap_or(1) * 100,
@ -23,36 +24,52 @@ pub async fn create_theme_menu(
10000 10000
} }
}); });
let pages = create_theme_pages(anime_entries, nsfw);
MenuBuilder::new_paginator() MenuBuilder::new_paginator()
.add_pages( .add_pages(pages)
entries
.into_iter()
.filter(|e| {
if !nsfw && e.nsfw {
return false;
}
if let Some(videos) = &e.videos {
!videos.is_empty()
} else {
false
}
})
.map(create_theme_page),
)
.timeout(EXTRA_LONG_TIMEOUT) .timeout(EXTRA_LONG_TIMEOUT)
.owner(owner)
.build(ctx, channel_id) .build(ctx, channel_id)
.await?; .await?;
Ok(()) Ok(())
} }
fn create_theme_pages(anime_entries: Vec<Anime>, nsfw: bool) -> Vec<Page<'static>> {
let mut pages = Vec::new();
for anime in anime_entries {
if anime.themes.is_none() {
continue;
}
for theme in anime.themes.unwrap() {
if theme.entries.is_none() {
continue;
}
let sequence = theme.sequence.clone().unwrap_or(1);
for entry in theme.entries.unwrap() {
if entry.nsfw && !nsfw {
continue;
}
let page = create_theme_page(&anime.name, &theme.theme_type, sequence, entry);
pages.push(page);
}
}
}
pages
}
/// Creates a new anime theme page /// Creates a new anime theme page
fn create_theme_page(entry: ThemeEntry) -> Page<'static> { fn create_theme_page(
anime_name: &str,
theme_type: &ThemeType,
theme_sequence: u16,
entry: ThemeEntry,
) -> Page<'static> {
let mut message = CreateMessage::default(); let mut message = CreateMessage::default();
let videos = entry.videos.unwrap(); let videos = entry.videos.unwrap();
let theme = entry.theme.unwrap();
let anime = theme.anime.unwrap(); let theme_type = match theme_type {
let theme_type = match theme.theme_type {
ThemeType::OP => "Opening", ThemeType::OP => "Opening",
ThemeType::ED => "Ending", ThemeType::ED => "Ending",
}; };
@ -60,8 +77,8 @@ fn create_theme_page(entry: ThemeEntry) -> Page<'static> {
message.content(format!( message.content(format!(
"**{} {}** of **{}**\nhttps://animethemes.moe/video/{}", "**{} {}** of **{}**\nhttps://animethemes.moe/video/{}",
theme_type, theme_type,
theme.sequence.unwrap_or(1), theme_sequence,
anime.name, anime_name,
videos.first().unwrap().basename videos.first().unwrap().basename
)); ));

@ -1,7 +1,7 @@
use crate::utils::error::BotResult; use crate::utils::error::BotResult;
use serenity::builder::CreateMessage; use serenity::builder::CreateMessage;
use serenity::client::Context; use serenity::client::Context;
use serenity::model::id::ChannelId; use serenity::model::id::{ChannelId, UserId};
use serenity_rich_interaction::core::LONG_TIMEOUT; use serenity_rich_interaction::core::LONG_TIMEOUT;
use serenity_rich_interaction::menu::{MenuBuilder, Page}; use serenity_rich_interaction::menu::{MenuBuilder, Page};
use xkcd_search::Comic; use xkcd_search::Comic;
@ -11,6 +11,7 @@ pub async fn create_xkcd_menu(
ctx: &Context, ctx: &Context,
channel_id: ChannelId, channel_id: ChannelId,
comics: Vec<Comic>, comics: Vec<Comic>,
owner: UserId,
) -> BotResult<()> { ) -> BotResult<()> {
let mut builder = if comics.len() > 1 { let mut builder = if comics.len() > 1 {
MenuBuilder::new_paginator() MenuBuilder::new_paginator()
@ -25,6 +26,7 @@ pub async fn create_xkcd_menu(
builder builder
.add_pages(comics.into_iter().map(|c| create_xkcd_page(c))) .add_pages(comics.into_iter().map(|c| create_xkcd_page(c)))
.timeout(LONG_TIMEOUT) .timeout(LONG_TIMEOUT)
.owner(owner)
.build(ctx, channel_id) .build(ctx, channel_id)
.await?; .await?;

Loading…
Cancel
Save