Memegen slash commands + autocompletion

pull/104/head
Stijn De Clercq 2022-02-06 17:58:57 +01:00
parent a71232e292
commit 93ede132a2
5 changed files with 104 additions and 31 deletions

View File

@ -1,15 +1,16 @@
from data.embeds.xkcd import XKCDEmbed
from data.menus import leaderboards
from decorators import help
import discord
from discord.ext import commands
from enums.help_categories import Category
from functions import checks, stringFormatters
from functions.database import memes, trump, dadjoke
from functions.memes import generate
import json import json
import random import random
import requests import requests
from discord.ext import commands
from data.embeds.xkcd import XKCDEmbed
from data.menus.memes import MemesList
from decorators import help
from enums.help_categories import Category
from functions import checks
from functions.database import memes, trump, dadjoke
from functions.memes import generate
class Fun(commands.Cog): class Fun(commands.Cog):
@ -98,17 +99,10 @@ class Fun(commands.Cog):
if result is None: if result is None:
return await ctx.send("Deze meme staat niet in de database.") return await ctx.send("Deze meme staat niet in de database.")
# Convert to list to support item assignment
fields = list(fields)
generated = generate(result, fields) generated = generate(result, fields)
# If the request was successful, remove the message calling it
if generated["success"]:
await self.utilsCog.removeMessage(ctx.message)
# Send the meme's url or the error message # Send the meme's url or the error message
await ctx.send(generated["message"]) await ctx.reply(generated["message"], mention_author=False)
@commands.command(name="Memes") @commands.command(name="Memes")
@commands.check(checks.allowedChannels) @commands.check(checks.allowedChannels)
@ -118,16 +112,7 @@ class Fun(commands.Cog):
Command that shows a list of memes in the database. Command that shows a list of memes in the database.
:param ctx: Discord Context :param ctx: Discord Context
""" """
memeList = memes.getAllMemes() return await MemesList(ctx=ctx).send()
# Turn the list into a list of [Name: fields]
memeList = [": ".join([stringFormatters.title_case(meme[1]),
str(meme[2])]) for meme in sorted(memeList, key=lambda x: x[1])]
pages = paginated_leaderboard.Pages(
source=paginated_leaderboard.Source(memeList, "Memes", discord.Colour.blue()),
clear_reactions_after=True)
await pages.start(ctx)
@commands.command(name="Pjoke") @commands.command(name="Pjoke")
@help.Category(category=Category.Fun) @help.Category(category=Category.Fun)

View File

@ -24,7 +24,7 @@ class FootballSlash(commands.Cog):
@_jpl_group.command(name="table", description="Huidige rangschikking") @_jpl_group.command(name="table", description="Huidige rangschikking")
async def _jpl_table_slash(self, ctx: ApplicationContext): async def _jpl_table_slash(self, ctx: ApplicationContext):
await ctx.response.defer() await ctx.response.defer()
await ctx.respond(get_table()) await ctx.send_followup(get_table())
@_jpl_group.command(name="update", description="Update de code voor deze competitie (owner-only)", default_permission=False) @_jpl_group.command(name="update", description="Update de code voor deze competitie (owner-only)", default_permission=False)
@permissions.is_owner() @permissions.is_owner()

View File

@ -1,10 +1,34 @@
from discord.ext import commands from discord.ext import commands
from discord.commands import slash_command, ApplicationContext, Option from discord.commands import slash_command, ApplicationContext, Option, AutocompleteContext
from functions.database import memes
from functions.database.memes import getAllMemes
from data.embeds.xkcd import XKCDEmbed from data.embeds.xkcd import XKCDEmbed
from data.menus.memes import MemesList
from functions.memes import generate
from functions.stringFormatters import title_case
from startup.didier import Didier from startup.didier import Didier
all_memes = getAllMemes()
def autocomplete_memes(ctx: AutocompleteContext) -> list[str]:
starting = []
containing = []
val = ctx.value.lower()
# First show matches that start with this word, then matches that contain it
for meme in all_memes:
if meme[1].startswith(val):
starting.append(title_case(meme[1]))
elif val in meme[1]:
containing.append(title_case(meme[1]))
return [*starting, *containing]
class FunSlash(commands.Cog): class FunSlash(commands.Cog):
def __init__(self, client: Didier): def __init__(self, client: Didier):
self.client: Didier = client self.client: Didier = client
@ -15,6 +39,32 @@ class FunSlash(commands.Cog):
): ):
return await ctx.respond(embed=XKCDEmbed(num).create()) return await ctx.respond(embed=XKCDEmbed(num).create())
@slash_command(name="memes", description="Lijst van memegen-memes")
async def _memes_slash(self, ctx: ApplicationContext):
return await MemesList(ctx=ctx).respond()
@slash_command(name="memegen", description="Genereer memes")
async def _memegen_slash(self, ctx: ApplicationContext,
meme: Option(str, description="Naam van de template", required=True, autocomplete=autocomplete_memes),
field1: Option(str, required=True),
field2: Option(str, required=False, default=""),
field3: Option(str, required=False, default=""),
field4: Option(str, required=False, default="")):
# Get the meme info that corresponds to this name
result: memes.Meme = memes.getMeme(meme)
# No meme found
if result is None:
return await ctx.respond("Deze meme staat niet in de database.", ephemeral=True)
await ctx.response.defer()
fields = (field1, field2, field3, field4)
generated = generate(result, fields)
# Send generated meme or error message
await ctx.send_followup(generated["message"])
def setup(client: Didier): def setup(client: Didier):
client.add_cog(FunSlash(client)) client.add_cog(FunSlash(client))

View File

@ -0,0 +1,26 @@
from dataclasses import dataclass, field
from data.menus.paginated import Paginated
from functions import stringFormatters
from functions.database import memes
@dataclass
class MemesList(Paginated):
title: str = field(default="Memes")
def __post_init__(self):
self.data = self.get_data()
def get_data(self) -> list[tuple]:
data = []
meme_list = memes.getAllMemes()
for meme in sorted(meme_list, key=lambda x: x[1]):
name = stringFormatters.title_case(meme[1])
fields = meme[2]
data.append((name, fields,))
return data
def format_entry(self, index: int, value: tuple) -> str:
return f"{value[0]} ({value[1]})"

View File

@ -10,6 +10,8 @@ def generate(meme: Meme, fields):
""" """
Main function that takes a Meme as input & generates an image. Main function that takes a Meme as input & generates an image.
""" """
fields = list(fields)
# If there's only one field, the user isn't required to use quotes # If there's only one field, the user isn't required to use quotes
if meme.fields == 1: if meme.fields == 1:
fields = [" ".join(fields)] fields = [" ".join(fields)]
@ -37,11 +39,14 @@ def generate(meme: Meme, fields):
# Adding a message parameter makes the code in the cog a lot cleaner # Adding a message parameter makes the code in the cog a lot cleaner
if not reply["success"]: if not reply["success"]:
reply["success"] = False
reply["message"] = "Error! Controleer of je de juiste syntax hebt gebruikt. Gebruik het commando " \ reply["message"] = "Error! Controleer of je de juiste syntax hebt gebruikt. Gebruik het commando " \
"\"memes\" voor een lijst aan geaccepteerde meme-namen." "\"memes\" voor een lijst aan geaccepteerde meme-namen."
else: else:
reply["message"] = reply["data"]["url"] reply["message"] = reply["data"]["url"]
reply["success"] = False
return reply return reply
@ -77,7 +82,8 @@ def _apply_meme(meme: Meme, fields):
102156234: mocking_spongebob, 102156234: mocking_spongebob,
91538330: _x_x_everywhere, 91538330: _x_x_everywhere,
252600902: _always_has_been, 252600902: _always_has_been,
167754325: _math_is_math 167754325: _math_is_math,
206493414: _i_used_the_x_to_destroy_the_x
} }
# Meme needs no special treatment # Meme needs no special treatment
@ -104,6 +110,12 @@ def _always_has_been(fields):
def _math_is_math(fields): def _math_is_math(fields):
word = fields[0].upper()
return ["", f"{word} IS {word}!"]
def _i_used_the_x_to_destroy_the_x(fields):
word = fields[0] word = fields[0]
return [f"{word.upper()} IS {word.upper()}!"] return ["", f"I used the {word} to destroy the {word}"]