Migrate remindme, closes #100

This commit is contained in:
Zeva Rose 2022-02-03 07:00:48 -07:00
parent 93381d7da0
commit 1594ae32ab

View file

@ -5,26 +5,24 @@ from datetime import datetime, timedelta
from typing import List, Optional from typing import List, Optional
from bson import ObjectId from bson import ObjectId
from discord import Embed from dis_snek import InteractionContext, Snake
from discord.ext.commands import Bot from dis_snek.ext.tasks.task import Task
from discord.ext.tasks import loop from dis_snek.ext.tasks.triggers import IntervalTrigger
from discord_slash import SlashContext, cog_ext from dis_snek.models.discord.components import ActionRow, Select, SelectOption
from discord_slash.utils.manage_commands import create_option from dis_snek.models.discord.embed import Embed, EmbedField
from discord_slash.utils.manage_components import ( from dis_snek.models.snek.application_commands import (
create_actionrow, OptionTypes,
create_select, slash_command,
create_select_option, slash_option,
wait_for_component,
) )
from jarvis.db.models import Reminder from jarvis.db.models import Reminder
from jarvis.utils import build_embed from jarvis.utils import build_embed
from jarvis.utils.cachecog import CacheCog from jarvis.utils.cachecog import CacheCog
from jarvis.utils.field import Field
valid = re.compile(r"[\w\s\-\\/.!@#$%^*()+=<>,\u0080-\U000E0FFF]*") valid = re.compile(r"[\w\s\-\\/.!@#$%^*()+=<>,\u0080-\U000E0FFF]*")
invites = re.compile( invites = re.compile(
r"(?:https?://)?(?:www.)?(?:discord.(?:gg|io|me|li)|discord(?:app)?.com/invite)/([^\s/]+?)(?=\b)", r"(?:https?://)?(?:www.)?(?:discord.(?:gg|io|me|li)|discord(?:app)?.com/invite)/([^\s/]+?)(?=\b)", # noqa: E501
flags=re.IGNORECASE, flags=re.IGNORECASE,
) )
@ -32,49 +30,41 @@ invites = re.compile(
class RemindmeCog(CacheCog): class RemindmeCog(CacheCog):
"""J.A.R.V.I.S. Remind Me Cog.""" """J.A.R.V.I.S. Remind Me Cog."""
def __init__(self, bot: Bot): def __init__(self, bot: Snake):
super().__init__(bot) super().__init__(bot)
self._remind.start() self._remind.start()
@cog_ext.cog_slash( @slash_command(name="remindme", description="Set a reminder")
name="remindme", @slash_option(
description="Set a reminder",
options=[
create_option(
name="message", name="message",
description="What to remind you of", description="What to remind you of?",
option_type=3, option_type=OptionTypes.STRING,
required=True, required=True,
), )
create_option( @slash_option(
name="weeks", name="weeks",
description="Number of weeks?", description="Number of weeks?",
option_type=4, option_type=OptionTypes.INTEGER,
required=False, required=False,
), )
create_option( @slash_option(
name="days", name="days", description="Number of days?", option_type=OptionTypes.INTEGER, required=False
description="Number of days?", )
option_type=4, @slash_option(
required=False,
),
create_option(
name="hours", name="hours",
description="Number of hours?", description="Number of hours?",
option_type=4, option_type=OptionTypes.INTEGER,
required=False, required=False,
), )
create_option( @slash_option(
name="minutes", name="minutes",
description="Number of minutes?", description="Number of minutes?",
option_type=4, option_type=OptionTypes.INTEGER,
required=False, required=False,
),
],
) )
async def _remindme( async def _remindme(
self, self,
ctx: SlashContext, ctx: InteractionContext,
message: Optional[str] = None, message: Optional[str] = None,
weeks: Optional[int] = 0, weeks: Optional[int] = 0,
days: Optional[int] = 0, days: Optional[int] = 0,
@ -148,8 +138,8 @@ class RemindmeCog(CacheCog):
title="Reminder Set", title="Reminder Set",
description=f"{ctx.author.mention} set a reminder", description=f"{ctx.author.mention} set a reminder",
fields=[ fields=[
Field(name="Message", value=message), EmbedField(name="Message", value=message),
Field( EmbedField(
name="When", name="When",
value=remind_at.strftime("%Y-%m-%d %H:%M UTC"), value=remind_at.strftime("%Y-%m-%d %H:%M UTC"),
inline=False, inline=False,
@ -158,19 +148,21 @@ class RemindmeCog(CacheCog):
) )
embed.set_author( embed.set_author(
name=ctx.author.name + "#" + ctx.author.discriminator, name=ctx.author.username + "#" + ctx.author.discriminator,
icon_url=ctx.author.avatar_url, icon_url=ctx.author.avatar_url,
) )
embed.set_thumbnail(url=ctx.author.avatar_url) embed.set_thumbnail(url=ctx.author.avatar_url)
await ctx.send(embed=embed) await ctx.send(embed=embed)
async def get_reminders_embed(self, ctx: SlashContext, reminders: List[Reminder]) -> Embed: async def get_reminders_embed(
self, ctx: InteractionContext, reminders: List[Reminder]
) -> Embed:
"""Build embed for paginator.""" """Build embed for paginator."""
fields = [] fields = []
for reminder in reminders: for reminder in reminders:
fields.append( fields.append(
Field( EmbedField(
name=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"), name=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"),
value=f"{reminder.message}\n\u200b", value=f"{reminder.message}\n\u200b",
inline=False, inline=False,
@ -184,19 +176,15 @@ class RemindmeCog(CacheCog):
) )
embed.set_author( embed.set_author(
name=ctx.author.name + "#" + ctx.author.discriminator, name=ctx.author.username + "#" + ctx.author.discriminator,
icon_url=ctx.author.avatar_url, icon_url=ctx.author.avatar_url,
) )
embed.set_thumbnail(url=ctx.author.avatar_url) embed.set_thumbnail(url=ctx.author.avatar_url)
return embed return embed
@cog_ext.cog_subcommand( @slash_command(name="reminders", sub_cmd_name="list", sub_cmd_description="List reminders")
base="reminders", async def _list(self, ctx: InteractionContext) -> None:
name="list",
description="List reminders for a user",
)
async def _list(self, ctx: SlashContext) -> None:
exists = self.check_cache(ctx) exists = self.check_cache(ctx)
if exists: if exists:
await ctx.defer(hidden=True) await ctx.defer(hidden=True)
@ -214,12 +202,8 @@ class RemindmeCog(CacheCog):
await ctx.send(embed=embed) await ctx.send(embed=embed)
@cog_ext.cog_subcommand( @slash_command(name="reminders", sub_cmd_name="delete", sub_cmd_description="Delete a reminder")
base="reminders", async def _delete(self, ctx: InteractionContext) -> None:
name="delete",
description="Delete a reminder",
)
async def _delete(self, ctx: SlashContext) -> None:
reminders = Reminder.objects(user=ctx.author.id, active=True) reminders = Reminder.objects(user=ctx.author.id, active=True)
if not reminders: if not reminders:
await ctx.send("You have no reminders set", hidden=True) await ctx.send("You have no reminders set", hidden=True)
@ -227,14 +211,14 @@ class RemindmeCog(CacheCog):
options = [] options = []
for reminder in reminders: for reminder in reminders:
option = create_select_option( option = SelectOption(
label=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"), label=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"),
value=str(reminder.id), value=str(reminder.id),
emoji="", emoji="",
) )
options.append(option) options.append(option)
select = create_select( select = Select(
options=options, options=options,
custom_id="to_delete", custom_id="to_delete",
placeholder="Select reminders to delete", placeholder="Select reminders to delete",
@ -242,7 +226,7 @@ class RemindmeCog(CacheCog):
max_values=len(reminders), max_values=len(reminders),
) )
components = [create_actionrow(select)] components = [ActionRow(select)]
embed = await self.get_reminders_embed(ctx, reminders) embed = await self.get_reminders_embed(ctx, reminders)
message = await ctx.send( message = await ctx.send(
content=f"You have {len(reminders)} reminder(s) set:", content=f"You have {len(reminders)} reminder(s) set:",
@ -251,13 +235,13 @@ class RemindmeCog(CacheCog):
) )
try: try:
context = await wait_for_component( used_component = await self.bot.wait_for_component(
self.bot,
check=lambda x: ctx.author.id == x.author_id, check=lambda x: ctx.author.id == x.author_id,
messages=message, messages=message,
components=components,
timeout=60 * 5, timeout=60 * 5,
) )
for to_delete in context.selected_options: for to_delete in used_component.context.values:
_ = Reminder.objects(user=ctx.author.id, id=ObjectId(to_delete)).delete() _ = Reminder.objects(user=ctx.author.id, id=ObjectId(to_delete)).delete()
for row in components: for row in components:
@ -265,9 +249,9 @@ class RemindmeCog(CacheCog):
component["disabled"] = True component["disabled"] = True
fields = [] fields = []
for reminder in filter(lambda x: str(x.id) in context.selected_options, reminders): for reminder in filter(lambda x: str(x.id) in used_component.context.values, reminders):
fields.append( fields.append(
Field( EmbedField(
name=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"), name=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"),
value=reminder.message, value=reminder.message,
inline=False, inline=False,
@ -285,8 +269,8 @@ class RemindmeCog(CacheCog):
) )
embed.set_thumbnail(url=ctx.author.avatar_url) embed.set_thumbnail(url=ctx.author.avatar_url)
await context.edit_origin( await used_component.context.edit_origin(
content=f"Deleted {len(context.selected_options)} reminder(s)", content=f"Deleted {len(used_component.context.values)} reminder(s)",
components=components, components=components,
embed=embed, embed=embed,
) )
@ -296,7 +280,7 @@ class RemindmeCog(CacheCog):
component["disabled"] = True component["disabled"] = True
await message.edit(components=components) await message.edit(components=components)
@loop(seconds=15) @Task.create(trigger=IntervalTrigger(seconds=15))
async def _remind(self) -> None: async def _remind(self) -> None:
reminders = Reminder.objects(remind_at__lte=datetime.utcnow() + timedelta(seconds=30)) reminders = Reminder.objects(remind_at__lte=datetime.utcnow() + timedelta(seconds=30))
for reminder in reminders: for reminder in reminders:
@ -326,6 +310,6 @@ class RemindmeCog(CacheCog):
reminder.delete() reminder.delete()
def setup(bot: Bot) -> None: def setup(bot: Snake) -> None:
"""Add RemindmeCog to J.A.R.V.I.S.""" """Add RemindmeCog to J.A.R.V.I.S."""
bot.add_cog(RemindmeCog(bot)) bot.add_cog(RemindmeCog(bot))