commit
ad69f78bd6
@ -0,0 +1,9 @@
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
/// Chooses a random value from the given iterator
|
||||
/// panics when the iterator is empty
|
||||
pub fn choose_unchecked<'a, I: SliceRandom<Item = &'a T>, T>(i: I) -> &'a T {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
i.choose(&mut rng).unwrap()
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE gifs;
|
@ -0,0 +1,8 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE gifs (
|
||||
id BIGSERIAL PRIMARY KEY ,
|
||||
category VARCHAR(128),
|
||||
name VARCHAR(128),
|
||||
url VARCHAR(128) NOT NULL,
|
||||
UNIQUE (category, name)
|
||||
)
|
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE statistics;
|
@ -0,0 +1,9 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE statistics (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
version VARCHAR(32) NOT NULL,
|
||||
command VARCHAR(255) NOT NULL,
|
||||
executed_at TIMESTAMP NOT NULL,
|
||||
success BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
error_msg TEXT
|
||||
)
|
@ -0,0 +1,31 @@
|
||||
use crate::utils::context_data::get_database_from_context;
|
||||
use bot_coreutils::url;
|
||||
use serenity::client::Context;
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::{Args, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
|
||||
#[command]
|
||||
#[description("Simple ping test command")]
|
||||
#[usage("<url> (<category>) (<name>)")]
|
||||
#[bucket("general")]
|
||||
#[aliases("add-gif", "addgif")]
|
||||
#[min_args(1)]
|
||||
#[max_args(3)]
|
||||
#[owners_only]
|
||||
async fn add_gif(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let url = args.single::<String>()?;
|
||||
|
||||
if !url::is_valid(&url) {
|
||||
msg.reply(ctx, "Invalid url").await?;
|
||||
return Ok(());
|
||||
}
|
||||
let category = args.single_quoted::<String>().ok();
|
||||
let name = args.single_quoted::<String>().ok();
|
||||
let database = get_database_from_context(&ctx).await;
|
||||
|
||||
database.add_gif(&url, category, name).await?;
|
||||
msg.reply(ctx, "Gif added to database").await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
use crate::messages::gifs::create_gifs_menu;
|
||||
use crate::utils::context_data::get_database_from_context;
|
||||
use serenity::client::Context;
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::CommandResult;
|
||||
use serenity::model::channel::Message;
|
||||
|
||||
#[command]
|
||||
#[description("Displays a list of all gifs used by the bot")]
|
||||
#[bucket("general")]
|
||||
async fn gifs(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let database = get_database_from_context(ctx).await;
|
||||
let gifs = database.get_all_gifs().await?;
|
||||
create_gifs_menu(ctx, msg.channel_id, gifs).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
use serenity::framework::standard::macros::group;
|
||||
|
||||
use about::ABOUT_COMMAND;
|
||||
use pekofy::PEKOFY_COMMAND;
|
||||
use add_gif::ADD_GIF_COMMAND;
|
||||
use gifs::GIFS_COMMAND;
|
||||
use ping::PING_COMMAND;
|
||||
use qalc::QALC_COMMAND;
|
||||
use sauce::SAUCE_COMMAND;
|
||||
use shutdown::SHUTDOWN_COMMAND;
|
||||
use stats::STATS_COMMAND;
|
||||
use time::TIME_COMMAND;
|
||||
use timezones::TIMEZONES_COMMAND;
|
||||
|
||||
mod about;
|
||||
mod add_gif;
|
||||
mod gifs;
|
||||
pub(crate) mod help;
|
||||
mod pekofy;
|
||||
mod ping;
|
||||
mod qalc;
|
||||
mod sauce;
|
||||
mod shutdown;
|
||||
mod stats;
|
||||
mod time;
|
||||
mod timezones;
|
||||
|
||||
#[group]
|
||||
#[commands(ping, stats, shutdown, pekofy, time, timezones, qalc, sauce, about)]
|
||||
#[commands(ping, stats, shutdown, time, timezones, qalc, about, add_gif, gifs)]
|
||||
pub struct Misc;
|
||||
|
@ -0,0 +1,26 @@
|
||||
use crate::utils::context_data::get_database_from_context;
|
||||
use crate::utils::error::BotError;
|
||||
use rand::prelude::IteratorRandom;
|
||||
use serenity::client::Context;
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::CommandResult;
|
||||
use serenity::model::channel::Message;
|
||||
|
||||
static GIF_CATEGORY: &str = "matsuri";
|
||||
|
||||
#[command]
|
||||
#[description("Posts a random matsuri gif")]
|
||||
#[usage("")]
|
||||
#[bucket("general")]
|
||||
async fn matsuri(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let database = get_database_from_context(ctx).await;
|
||||
let gifs = database.get_gifs_by_category(GIF_CATEGORY).await?;
|
||||
let gif = gifs
|
||||
.into_iter()
|
||||
.choose(&mut rand::thread_rng())
|
||||
.ok_or(BotError::from("No gifs found."))?;
|
||||
|
||||
msg.channel_id.say(ctx, gif.url).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
use serenity::framework::standard::macros::group;
|
||||
|
||||
mod matsuri;
|
||||
mod pekofy;
|
||||
mod sauce;
|
||||
|
||||
use matsuri::MATSURI_COMMAND;
|
||||
use pekofy::PEKOFY_COMMAND;
|
||||
use sauce::SAUCE_COMMAND;
|
||||
|
||||
#[group]
|
||||
#[commands(pekofy, sauce, matsuri)]
|
||||
pub struct Weeb;
|
@ -0,0 +1,52 @@
|
||||
use crate::utils::error::BotResult;
|
||||
use bot_database::models::Gif;
|
||||
use bot_serenityutils::menu::{MenuBuilder, Page};
|
||||
use serenity::builder::CreateMessage;
|
||||
use serenity::client::Context;
|
||||
use serenity::model::id::ChannelId;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Creates a new gifs embed
|
||||
pub async fn create_gifs_menu(
|
||||
ctx: &Context,
|
||||
channel_id: ChannelId,
|
||||
gifs: Vec<Gif>,
|
||||
) -> BotResult<()> {
|
||||
let total_pages = (gifs.len() as f32 / 10.0).ceil() as usize;
|
||||
let pages: Vec<Page> = gifs
|
||||
.chunks(10)
|
||||
.enumerate()
|
||||
.map(|(page, gifs)| create_gifs_page(page + 1, total_pages, gifs.to_vec()))
|
||||
.collect();
|
||||
|
||||
MenuBuilder::new_paginator()
|
||||
.timeout(Duration::from_secs(120))
|
||||
.add_pages(pages)
|
||||
.build(ctx, channel_id)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates a new gif page
|
||||
pub fn create_gifs_page(page: usize, total_pages: usize, gifs: Vec<Gif>) -> Page<'static> {
|
||||
let mut message = CreateMessage::default();
|
||||
let description_lines: Vec<String> = gifs
|
||||
.into_iter()
|
||||
.map(|g| {
|
||||
format!(
|
||||
"{} - {} - [Source]({})",
|
||||
g.category.unwrap_or("*N/A*".to_string()),
|
||||
g.name.unwrap_or("*N/A*".to_string()),
|
||||
g.url
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
message.embed(|e| {
|
||||
e.title("Gifs")
|
||||
.description(description_lines.join("\n"))
|
||||
.footer(|f| f.text(format!("Page {} of {}", page, total_pages)))
|
||||
});
|
||||
|
||||
Page::new_static(message)
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod gifs;
|
||||
pub mod music;
|
||||
pub mod sauce;
|
||||
|
Loading…
Reference in New Issue