Add delete button to all embeds, change how reminders work a little
This commit is contained in:
parent
b192de5222
commit
4d17115c09
10 changed files with 251 additions and 145 deletions
|
@ -14,8 +14,10 @@ from jarvis_core.db.models import (
|
||||||
Autoreact,
|
Autoreact,
|
||||||
Modlog,
|
Modlog,
|
||||||
Note,
|
Note,
|
||||||
|
Reminder,
|
||||||
Roleping,
|
Roleping,
|
||||||
Setting,
|
Setting,
|
||||||
|
Star,
|
||||||
Warning,
|
Warning,
|
||||||
)
|
)
|
||||||
from jarvis_core.filters import invites, url
|
from jarvis_core.filters import invites, url
|
||||||
|
@ -154,6 +156,9 @@ class Jarvis(StatsClient):
|
||||||
"{}&permissions=8&scope=bot%20applications.commands".format(self.user.id)
|
"{}&permissions=8&scope=bot%20applications.commands".format(self.user.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug("Hitting Reminders for faster loads")
|
||||||
|
_ = await Reminder.find().to_list(None)
|
||||||
|
|
||||||
async def on_error(self, source: str, error: Exception, *args, **kwargs) -> None:
|
async def on_error(self, source: str, error: Exception, *args, **kwargs) -> None:
|
||||||
"""NAFF on_error override."""
|
"""NAFF on_error override."""
|
||||||
if isinstance(error, HTTPException):
|
if isinstance(error, HTTPException):
|
||||||
|
@ -841,13 +846,11 @@ class Jarvis(StatsClient):
|
||||||
f"Failed to process edit {message.guild.id}/{message.channel.id}/{message.id}: {e}"
|
f"Failed to process edit {message.guild.id}/{message.channel.id}/{message.id}: {e}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@listen()
|
async def _handle_modcase_button(self, event: Button) -> None:
|
||||||
async def on_button(self, event: Button) -> None:
|
|
||||||
"""Process button events."""
|
|
||||||
context = event.context
|
context = event.context
|
||||||
|
|
||||||
if not context.custom_id.startswith("modcase|"):
|
if not context.custom_id.startswith("modcase|"):
|
||||||
return # await super().on_button(event)
|
return # Failsafe
|
||||||
|
|
||||||
if not context.deferred and not context.responded:
|
if not context.deferred and not context.responded:
|
||||||
await context.defer(ephemeral=True)
|
await context.defer(ephemeral=True)
|
||||||
|
@ -917,3 +920,61 @@ class Jarvis(StatsClient):
|
||||||
await context.send(msg)
|
await context.send(msg)
|
||||||
await self.redis.delete(user_key)
|
await self.redis.delete(user_key)
|
||||||
await self.redis.delete(action_key)
|
await self.redis.delete(action_key)
|
||||||
|
|
||||||
|
async def _handle_delete_button(self, event: Button) -> None:
|
||||||
|
context = event.context
|
||||||
|
|
||||||
|
if not context.custom_id.startswith("delete|"):
|
||||||
|
return # Failsafe
|
||||||
|
|
||||||
|
if not context.deferred and not context.responded:
|
||||||
|
await context.defer(ephemeral=True)
|
||||||
|
|
||||||
|
uid = context.custom_id.split("|")[1]
|
||||||
|
|
||||||
|
if (
|
||||||
|
not context.author.has_permission(Permissions.MANAGE_MESSAGES)
|
||||||
|
and not context.author.has_permission(Permissions.ADMINISTRATOR)
|
||||||
|
and not str(context.author) == uid
|
||||||
|
):
|
||||||
|
await context.send("I'm afraid I can't let you do that", ephemeral=True)
|
||||||
|
return # User does not have perms to delete
|
||||||
|
|
||||||
|
if star := await Star.find_one(q(star=context.message.id, guild=context.guild.id)):
|
||||||
|
await star.delete()
|
||||||
|
|
||||||
|
await context.message.delete()
|
||||||
|
await context.send("Message deleted", ephemeral=True)
|
||||||
|
|
||||||
|
async def _handle_copy_button(self, event: Button) -> None:
|
||||||
|
context = event.context
|
||||||
|
|
||||||
|
if not context.custom_id.startswith("copy|"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not context.deferred and not context.responded:
|
||||||
|
await context.defer(ephemeral=True)
|
||||||
|
|
||||||
|
what, rid = context.custom_id.split("|")[1:]
|
||||||
|
if what == "rme":
|
||||||
|
reminder = await Reminder.find_one(q(_id=rid))
|
||||||
|
if reminder:
|
||||||
|
new_reminder = Reminder(
|
||||||
|
user=context.author.id,
|
||||||
|
channel=context.channel.id,
|
||||||
|
guild=context.guild.id,
|
||||||
|
message=reminder.message,
|
||||||
|
remind_at=reminder.remind_at,
|
||||||
|
private=reminder.private,
|
||||||
|
active=reminder.active,
|
||||||
|
)
|
||||||
|
await new_reminder.commit()
|
||||||
|
|
||||||
|
await context.send("Reminder copied!", ephemeral=True)
|
||||||
|
|
||||||
|
@listen()
|
||||||
|
async def on_button(self, event: Button) -> None:
|
||||||
|
"""Process button events."""
|
||||||
|
await self._handle_modcase_button(event)
|
||||||
|
await self._handle_delete_button(event)
|
||||||
|
await self._handle_copy_button(event)
|
||||||
|
|
|
@ -7,7 +7,9 @@ from io import BytesIO
|
||||||
import psutil
|
import psutil
|
||||||
from aiofile import AIOFile, LineReader
|
from aiofile import AIOFile, LineReader
|
||||||
from naff import Client, Extension, PrefixedContext, prefixed_command
|
from naff import Client, Extension, PrefixedContext, prefixed_command
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.file import File
|
from naff.models.discord.file import File
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
|
@ -78,7 +80,10 @@ class BotutilCog(Extension):
|
||||||
)
|
)
|
||||||
embed = build_embed(title="System Info", description="", fields=fields)
|
embed = build_embed(title="System Info", description="", fields=fields)
|
||||||
embed.set_image(url=self.bot.user.avatar.url)
|
embed.set_image(url=self.bot.user.avatar.url)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@prefixed_command(name="update")
|
@prefixed_command(name="update")
|
||||||
async def _update(self, ctx: PrefixedContext) -> None:
|
async def _update(self, ctx: PrefixedContext) -> None:
|
||||||
|
@ -111,15 +116,25 @@ class BotutilCog(Extension):
|
||||||
|
|
||||||
self.logger.info("Updates applied")
|
self.logger.info("Updates applied")
|
||||||
content = f"```ansi\n{capture.get()}\n```"
|
content = f"```ansi\n{capture.get()}\n```"
|
||||||
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
if len(content) < 3000:
|
if len(content) < 3000:
|
||||||
await ctx.reply(content, embeds=embed)
|
await ctx.reply(content, embeds=embed, components=components)
|
||||||
else:
|
else:
|
||||||
await ctx.reply(f"Total Changes: {status.lines['total_lines']}", embeds=embed)
|
await ctx.reply(
|
||||||
|
f"Total Changes: {status.lines['total_lines']}",
|
||||||
|
embeds=embed,
|
||||||
|
components=components,
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
embed = build_embed(title="Update Status", description="No changes applied", fields=[])
|
embed = build_embed(title="Update Status", description="No changes applied", fields=[])
|
||||||
embed.set_thumbnail(url="https://dev.zevaryx.com/git.png")
|
embed.set_thumbnail(url="https://dev.zevaryx.com/git.png")
|
||||||
await ctx.reply(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.reply(embeds=embed, components=components)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: Client) -> None:
|
def setup(bot: Client) -> None:
|
||||||
|
|
|
@ -16,7 +16,9 @@ from jarvis_core.filters import invites, url
|
||||||
from jarvis_core.util import convert_bytesize, hash
|
from jarvis_core.util import convert_bytesize, hash
|
||||||
from jarvis_core.util.http import get_size
|
from jarvis_core.util.http import get_size
|
||||||
from naff import Client, Extension, InteractionContext
|
from naff import Client, Extension, InteractionContext
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.file import File
|
from naff.models.discord.file import File
|
||||||
from naff.models.discord.message import Attachment
|
from naff.models.discord.message import Attachment
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
|
@ -119,7 +121,10 @@ class DevCog(Extension):
|
||||||
]
|
]
|
||||||
|
|
||||||
embed = build_embed(title=title, description=description, fields=fields)
|
embed = build_embed(title=title, description=description, fields=fields)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(name="uuid", description="Generate a UUID")
|
@slash_command(name="uuid", description="Generate a UUID")
|
||||||
@slash_option(
|
@slash_option(
|
||||||
|
@ -235,7 +240,10 @@ class DevCog(Extension):
|
||||||
EmbedField(name=mstr, value=f"`{encoded}`", inline=False),
|
EmbedField(name=mstr, value=f"`{encoded}`", inline=False),
|
||||||
]
|
]
|
||||||
embed = build_embed(title="Decoded Data", description="", fields=fields)
|
embed = build_embed(title="Decoded Data", description="", fields=fields)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(name="decode", description="Decode some data")
|
@slash_command(name="decode", description="Decode some data")
|
||||||
@slash_option(
|
@slash_option(
|
||||||
|
@ -270,7 +278,10 @@ class DevCog(Extension):
|
||||||
EmbedField(name=mstr, value=f"`{decoded}`", inline=False),
|
EmbedField(name=mstr, value=f"`{decoded}`", inline=False),
|
||||||
]
|
]
|
||||||
embed = build_embed(title="Decoded Data", description="", fields=fields)
|
embed = build_embed(title="Decoded Data", description="", fields=fields)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(name="cloc", description="Get JARVIS lines of code")
|
@slash_command(name="cloc", description="Get JARVIS lines of code")
|
||||||
@cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30)
|
@cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30)
|
||||||
|
|
|
@ -8,7 +8,9 @@ import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from jarvis_core.util import convert_bytesize, unconvert_bytesize
|
from jarvis_core.util import convert_bytesize, unconvert_bytesize
|
||||||
from naff import Client, Extension, InteractionContext
|
from naff import Client, Extension, InteractionContext
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.file import File
|
from naff.models.discord.file import File
|
||||||
from naff.models.discord.message import Attachment
|
from naff.models.discord.message import Attachment
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
|
@ -147,9 +149,11 @@ class ImageCog(Extension):
|
||||||
]
|
]
|
||||||
embed = build_embed(title=filename, description="", fields=fields)
|
embed = build_embed(title=filename, description="", fields=fields)
|
||||||
embed.set_image(url="attachment://resized.png")
|
embed.set_image(url="attachment://resized.png")
|
||||||
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
embeds=embed,
|
embeds=embed, file=File(file=bufio, file_name="resized.png"), components=components
|
||||||
file=File(file=bufio, file_name="resized.png"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,15 @@ import re
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from bson import ObjectId
|
|
||||||
from dateparser import parse
|
from dateparser import parse
|
||||||
from dateparser_data.settings import default_parsers
|
from dateparser_data.settings import default_parsers
|
||||||
from jarvis_core.db import q
|
from jarvis_core.db import q
|
||||||
from jarvis_core.db.models import Reminder
|
from jarvis_core.db.models import Reminder
|
||||||
from naff import Client, Extension, InteractionContext
|
from naff import AutocompleteContext, Client, Extension, InteractionContext
|
||||||
from naff.client.utils.misc_utils import get
|
|
||||||
from naff.models.discord.channel import GuildChannel
|
from naff.models.discord.channel import GuildChannel
|
||||||
from naff.models.discord.components import ActionRow, Select, SelectOption
|
from naff.models.discord.components import ActionRow, Button
|
||||||
from naff.models.discord.embed import Embed, EmbedField
|
from naff.models.discord.embed import Embed, EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.modal import InputText, Modal, TextStyles
|
from naff.models.discord.modal import InputText, Modal, TextStyles
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
OptionTypes,
|
OptionTypes,
|
||||||
|
@ -22,6 +21,7 @@ from naff.models.naff.application_commands import (
|
||||||
slash_command,
|
slash_command,
|
||||||
slash_option,
|
slash_option,
|
||||||
)
|
)
|
||||||
|
from thefuzz import process
|
||||||
|
|
||||||
from jarvis.utils import build_embed
|
from jarvis.utils import build_embed
|
||||||
|
|
||||||
|
@ -52,16 +52,8 @@ class RemindmeCog(Extension):
|
||||||
ctx: InteractionContext,
|
ctx: InteractionContext,
|
||||||
private: bool = None,
|
private: bool = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if private is None:
|
if private is None and ctx.guild:
|
||||||
private = ctx.guild.member_count >= 5000
|
private = ctx.guild.member_count >= 5000
|
||||||
reminders = len([x async for x in Reminder.find(q(user=ctx.author.id, active=True))])
|
|
||||||
if reminders >= 5:
|
|
||||||
await ctx.send(
|
|
||||||
"You already have 5 (or more) active reminders. "
|
|
||||||
"Please either remove an old one, or wait for one to pass",
|
|
||||||
ephemeral=True,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
modal = Modal(
|
modal = Modal(
|
||||||
title="Set your reminder!",
|
title="Set your reminder!",
|
||||||
components=[
|
components=[
|
||||||
|
@ -145,7 +137,7 @@ class RemindmeCog(Extension):
|
||||||
r = Reminder(
|
r = Reminder(
|
||||||
user=ctx.author.id,
|
user=ctx.author.id,
|
||||||
channel=ctx.channel.id,
|
channel=ctx.channel.id,
|
||||||
guild=ctx.guild.id,
|
guild=ctx.guild.id if ctx.guild else ctx.author.id,
|
||||||
message=message,
|
message=message,
|
||||||
remind_at=remind_at,
|
remind_at=remind_at,
|
||||||
private=private,
|
private=private,
|
||||||
|
@ -173,7 +165,13 @@ class RemindmeCog(Extension):
|
||||||
)
|
)
|
||||||
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||||
|
|
||||||
await response.send(embeds=embed, ephemeral=private)
|
delete_button = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
copy_button = Button(style=ButtonStyles.GREEN, emoji="📋", custom_id=f"copy|rme|{r.id}")
|
||||||
|
components = [ActionRow(delete_button, copy_button)]
|
||||||
|
private = private if private is not None else False
|
||||||
|
await response.send(embeds=embed, components=components, ephemeral=private)
|
||||||
|
|
||||||
async def get_reminders_embed(
|
async def get_reminders_embed(
|
||||||
self, ctx: InteractionContext, reminders: List[Reminder]
|
self, ctx: InteractionContext, reminders: List[Reminder]
|
||||||
|
@ -222,75 +220,28 @@ class RemindmeCog(Extension):
|
||||||
return
|
return
|
||||||
|
|
||||||
embed = await self.get_reminders_embed(ctx, reminders)
|
embed = await self.get_reminders_embed(ctx, reminders)
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@reminders.subcommand(sub_cmd_name="delete", sub_cmd_description="Delete a reminder")
|
@reminders.subcommand(sub_cmd_name="delete", sub_cmd_description="Delete a reminder")
|
||||||
async def _delete(self, ctx: InteractionContext) -> None:
|
@slash_option(
|
||||||
reminders = await Reminder.find(q(user=ctx.author.id, active=True)).to_list(None)
|
name="content",
|
||||||
if not reminders:
|
description="Content of the reminder",
|
||||||
await ctx.send("You have no reminders set", ephemeral=True)
|
opt_type=OptionTypes.STRING,
|
||||||
|
required=True,
|
||||||
|
autocomplete=True,
|
||||||
|
)
|
||||||
|
async def _delete(self, ctx: InteractionContext, content: str) -> None:
|
||||||
|
reminder = await Reminder.find_one(q(_id=content))
|
||||||
|
if not reminder:
|
||||||
|
await ctx.send(f"Reminder `{content}` does not exist", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
options = []
|
ts = int(reminder.remind_at.timestamp())
|
||||||
for reminder in reminders:
|
|
||||||
option = SelectOption(
|
|
||||||
label=f"{reminder.remind_at}",
|
|
||||||
value=str(reminder.id),
|
|
||||||
emoji="⏰",
|
|
||||||
)
|
|
||||||
options.append(option)
|
|
||||||
|
|
||||||
select = Select(
|
fields = [EmbedField(name=f"<t:{ts}:F>", value=reminder.message, inline=False)]
|
||||||
options=options,
|
|
||||||
custom_id="to_delete",
|
|
||||||
placeholder="Select reminders to delete",
|
|
||||||
min_values=1,
|
|
||||||
max_values=len(reminders),
|
|
||||||
)
|
|
||||||
|
|
||||||
components = [ActionRow(select)]
|
|
||||||
embed = await self.get_reminders_embed(ctx, reminders)
|
|
||||||
message = await ctx.send(
|
|
||||||
content=f"You have {len(reminders)} reminder(s) set:",
|
|
||||||
embeds=embed,
|
|
||||||
components=components,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
context = await self.bot.wait_for_component(
|
|
||||||
check=lambda x: ctx.author.id == x.context.author.id,
|
|
||||||
messages=message,
|
|
||||||
timeout=60 * 5,
|
|
||||||
)
|
|
||||||
|
|
||||||
fields = []
|
|
||||||
for to_delete in context.context.values:
|
|
||||||
reminder = get(reminders, user=ctx.author.id, id=ObjectId(to_delete))
|
|
||||||
if reminder.private and isinstance(ctx.channel, GuildChannel):
|
|
||||||
fields.append(
|
|
||||||
EmbedField(
|
|
||||||
name=f"<t:{int(reminder.remind_at.timestamp())}:F>",
|
|
||||||
value="Private reminder",
|
|
||||||
inline=False,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
fields.append(
|
|
||||||
EmbedField(
|
|
||||||
name=f"<t:{int(reminder.remind_at.timestamp())}:F>",
|
|
||||||
value=reminder.message,
|
|
||||||
inline=False,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await reminder.delete()
|
|
||||||
except Exception:
|
|
||||||
self.logger.debug("Ignoring deletion error")
|
|
||||||
|
|
||||||
for row in components:
|
|
||||||
for component in row.components:
|
|
||||||
component.disabled = True
|
|
||||||
|
|
||||||
embed = build_embed(
|
embed = build_embed(
|
||||||
title="Deleted Reminder(s)",
|
title="Deleted Reminder(s)",
|
||||||
|
@ -304,44 +255,64 @@ class RemindmeCog(Extension):
|
||||||
)
|
)
|
||||||
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||||
|
|
||||||
await context.context.edit_origin(
|
components = Button(
|
||||||
content=f"Deleted {len(context.context.values)} reminder(s)",
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
components=components,
|
|
||||||
embeds=embed,
|
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
try:
|
||||||
for row in components:
|
await reminder.delete()
|
||||||
for component in row.components:
|
except Exception:
|
||||||
component.disabled = True
|
self.logger.debug("Ignoring deletion error")
|
||||||
await message.edit(components=components)
|
await ctx.send(embeds=embed, ephemeral=reminder.private, components=components)
|
||||||
|
|
||||||
@reminders.subcommand(
|
@reminders.subcommand(
|
||||||
sub_cmd_name="fetch",
|
sub_cmd_name="fetch",
|
||||||
sub_cmd_description="Fetch a reminder that failed to send",
|
sub_cmd_description="Fetch a reminder that failed to send",
|
||||||
)
|
)
|
||||||
@slash_option(
|
@slash_option(
|
||||||
name="id", description="ID of the reminder", opt_type=OptionTypes.STRING, required=True
|
name="content",
|
||||||
|
description="Content of the reminder",
|
||||||
|
opt_type=OptionTypes.STRING,
|
||||||
|
required=True,
|
||||||
|
autocomplete=True,
|
||||||
)
|
)
|
||||||
async def _fetch(self, ctx: InteractionContext, id: str) -> None:
|
async def _fetch(self, ctx: InteractionContext, content: str) -> None:
|
||||||
reminder = await Reminder.find_one(q(id=id))
|
reminder = await Reminder.find_one(q(_id=content))
|
||||||
if not reminder:
|
if not reminder:
|
||||||
await ctx.send(f"Reminder `{id}` does not exist", ephemeral=True)
|
await ctx.send(f"Reminder `{content}` does not exist", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
embed = build_embed(title="You have a reminder!", description=reminder.message, fields=[])
|
ts = int(reminder.remind_at.timestamp())
|
||||||
|
|
||||||
|
fields = [EmbedField(name="Remind At", value=f"<t:{ts}:F> (<t:{ts}:R>)")]
|
||||||
|
|
||||||
|
embed = build_embed(
|
||||||
|
title="You have a reminder!", description=reminder.message, fields=fields
|
||||||
|
)
|
||||||
embed.set_author(
|
embed.set_author(
|
||||||
name=ctx.author.display_name + "#" + ctx.author.discriminator,
|
name=ctx.author.display_name + "#" + ctx.author.discriminator,
|
||||||
icon_url=ctx.author.display_avatar,
|
icon_url=ctx.author.display_avatar.url,
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.set_thumbnail(url=ctx.author.display_avatar)
|
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||||
await ctx.send(embeds=embed, ephemeral=reminder.private)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, ephemeral=reminder.private, components=components)
|
||||||
if reminder.remind_at <= datetime.now(tz=timezone.utc) and not reminder.active:
|
if reminder.remind_at <= datetime.now(tz=timezone.utc) and not reminder.active:
|
||||||
try:
|
try:
|
||||||
await reminder.delete()
|
await reminder.delete()
|
||||||
except Exception:
|
except Exception:
|
||||||
self.logger.debug("Ignoring deletion error")
|
self.logger.debug("Ignoring deletion error")
|
||||||
|
|
||||||
|
@_fetch.autocomplete("content")
|
||||||
|
@_delete.autocomplete("content")
|
||||||
|
async def _search_reminders(self, ctx: AutocompleteContext, content: str) -> None:
|
||||||
|
reminders = await Reminder.find(q(user=ctx.author.id)).to_list(None)
|
||||||
|
lookup = {r.message: str(r.id) for r in reminders}
|
||||||
|
results = process.extract(content, list(lookup.keys()), limit=5)
|
||||||
|
choices = [{"name": r[0], "value": lookup[r[0]]} for r in results]
|
||||||
|
await ctx.send(choices=choices)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: Client) -> None:
|
def setup(bot: Client) -> None:
|
||||||
"""Add RemindmeCog to JARVIS"""
|
"""Add RemindmeCog to JARVIS"""
|
||||||
|
|
|
@ -6,8 +6,9 @@ from jarvis_core.db import q
|
||||||
from jarvis_core.db.models import Rolegiver
|
from jarvis_core.db.models import Rolegiver
|
||||||
from naff import Client, Extension, InteractionContext, Permissions
|
from naff import Client, Extension, InteractionContext, Permissions
|
||||||
from naff.client.utils.misc_utils import get
|
from naff.client.utils.misc_utils import get
|
||||||
from naff.models.discord.components import ActionRow, Select, SelectOption
|
from naff.models.discord.components import ActionRow, Button, Select, SelectOption
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.role import Role
|
from naff.models.discord.role import Role
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
OptionTypes,
|
OptionTypes,
|
||||||
|
@ -92,8 +93,10 @@ class RolegiverCog(Extension):
|
||||||
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url)
|
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url)
|
||||||
|
|
||||||
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@rolegiver.subcommand(sub_cmd_name="remove", sub_cmd_description="Remove a role from rolegiver")
|
@rolegiver.subcommand(sub_cmd_name="remove", sub_cmd_description="Remove a role from rolegiver")
|
||||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||||
|
@ -210,8 +213,10 @@ class RolegiverCog(Extension):
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
role = SlashCommand(name="role", description="Get/Remove Rolegiver roles")
|
role = SlashCommand(name="role", description="Get/Remove Rolegiver roles")
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ from jarvis_core.db.models import Star, Starboard
|
||||||
from naff import Client, Extension, InteractionContext, Permissions
|
from naff import Client, Extension, InteractionContext, Permissions
|
||||||
from naff.client import errors
|
from naff.client import errors
|
||||||
from naff.models.discord.channel import GuildText
|
from naff.models.discord.channel import GuildText
|
||||||
from naff.models.discord.components import ActionRow, Select, SelectOption
|
from naff.models.discord.components import ActionRow, Button, Select, SelectOption
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.message import Message
|
from naff.models.discord.message import Message
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
CommandTypes,
|
CommandTypes,
|
||||||
|
@ -231,8 +232,10 @@ class StarboardCog(Extension):
|
||||||
embed.set_footer(text=ctx.guild.name + " | " + channel.name)
|
embed.set_footer(text=ctx.guild.name + " | " + channel.name)
|
||||||
if image_url:
|
if image_url:
|
||||||
embed.set_image(url=image_url)
|
embed.set_image(url=image_url)
|
||||||
|
star_components = Button(
|
||||||
star = await starboard.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
star = await starboard.send(embeds=embed, components=star_components)
|
||||||
|
|
||||||
await Star(
|
await Star(
|
||||||
index=count,
|
index=count,
|
||||||
|
|
|
@ -7,8 +7,9 @@ from typing import Dict, List
|
||||||
from jarvis_core.db import q
|
from jarvis_core.db import q
|
||||||
from jarvis_core.db.models import Setting, Tag
|
from jarvis_core.db.models import Setting, Tag
|
||||||
from naff import AutocompleteContext, Client, Extension, InteractionContext
|
from naff import AutocompleteContext, Client, Extension, InteractionContext
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
from naff.models.discord.enums import Permissions
|
from naff.models.discord.enums import ButtonStyles, Permissions
|
||||||
from naff.models.discord.modal import InputText, Modal, TextStyles
|
from naff.models.discord.modal import InputText, Modal, TextStyles
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
OptionTypes,
|
OptionTypes,
|
||||||
|
@ -128,7 +129,11 @@ class TagCog(Extension):
|
||||||
icon_url=ctx.author.display_avatar.url,
|
icon_url=ctx.author.display_avatar.url,
|
||||||
)
|
)
|
||||||
|
|
||||||
await response.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
await response.send(embeds=embed, components=components)
|
||||||
if ctx.guild.id not in self.cache:
|
if ctx.guild.id not in self.cache:
|
||||||
self.cache[ctx.guild.id] = []
|
self.cache[ctx.guild.id] = []
|
||||||
self.cache[ctx.guild.id].append(tag.name)
|
self.cache[ctx.guild.id].append(tag.name)
|
||||||
|
@ -230,8 +235,10 @@ class TagCog(Extension):
|
||||||
name=ctx.author.username + "#" + ctx.author.discriminator,
|
name=ctx.author.username + "#" + ctx.author.discriminator,
|
||||||
icon_url=ctx.author.display_avatar.url,
|
icon_url=ctx.author.display_avatar.url,
|
||||||
)
|
)
|
||||||
|
components = Button(
|
||||||
await response.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await response.send(embeds=embed, components=components)
|
||||||
if tag.name not in self.cache[ctx.guild.id]:
|
if tag.name not in self.cache[ctx.guild.id]:
|
||||||
self.cache[ctx.guild.id].remove(old_name)
|
self.cache[ctx.guild.id].remove(old_name)
|
||||||
self.cache[ctx.guild.id].append(tag.name)
|
self.cache[ctx.guild.id].append(tag.name)
|
||||||
|
@ -309,15 +316,20 @@ class TagCog(Extension):
|
||||||
name=f"{username}#{discrim}" if username else "Unknown User",
|
name=f"{username}#{discrim}" if username else "Unknown User",
|
||||||
icon_url=url,
|
icon_url=url,
|
||||||
)
|
)
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@tag.subcommand(sub_cmd_name="list", sub_cmd_description="List tag names")
|
@tag.subcommand(sub_cmd_name="list", sub_cmd_description="List tag names")
|
||||||
async def _list(self, ctx: InteractionContext) -> None:
|
async def _list(self, ctx: InteractionContext) -> None:
|
||||||
tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None)
|
tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None)
|
||||||
names = "\n".join(f"`{t.name}`" for t in tags)
|
names = "\n".join(f"`{t.name}`" for t in tags)
|
||||||
embed = build_embed(title="All Tags", description=names, fields=[])
|
embed = build_embed(title="All Tags", description=names, fields=[])
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@_get.autocomplete("name")
|
@_get.autocomplete("name")
|
||||||
@_edit.autocomplete("name")
|
@_edit.autocomplete("name")
|
||||||
|
|
|
@ -6,7 +6,9 @@ from dateparser import parse
|
||||||
from dateparser_data.settings import default_parsers
|
from dateparser_data.settings import default_parsers
|
||||||
from jarvis_core.db.models import Temprole
|
from jarvis_core.db.models import Temprole
|
||||||
from naff import Client, Extension, InteractionContext, Permissions
|
from naff import Client, Extension, InteractionContext, Permissions
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.role import Role
|
from naff.models.discord.role import Role
|
||||||
from naff.models.discord.user import Member
|
from naff.models.discord.user import Member
|
||||||
from naff.models.naff.application_commands import (
|
from naff.models.naff.application_commands import (
|
||||||
|
@ -117,8 +119,10 @@ class TemproleCog(Extension):
|
||||||
embed.set_author(
|
embed.set_author(
|
||||||
name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url
|
name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url
|
||||||
)
|
)
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: Client) -> None:
|
def setup(bot: Client) -> None:
|
||||||
|
|
|
@ -10,7 +10,9 @@ import numpy as np
|
||||||
from dateparser import parse
|
from dateparser import parse
|
||||||
from naff import Client, Extension, InteractionContext, const
|
from naff import Client, Extension, InteractionContext, const
|
||||||
from naff.models.discord.channel import GuildCategory, GuildText, GuildVoice
|
from naff.models.discord.channel import GuildCategory, GuildText, GuildVoice
|
||||||
|
from naff.models.discord.components import Button
|
||||||
from naff.models.discord.embed import EmbedField
|
from naff.models.discord.embed import EmbedField
|
||||||
|
from naff.models.discord.enums import ButtonStyles
|
||||||
from naff.models.discord.file import File
|
from naff.models.discord.file import File
|
||||||
from naff.models.discord.guild import Guild
|
from naff.models.discord.guild import Guild
|
||||||
from naff.models.discord.role import Role
|
from naff.models.discord.role import Role
|
||||||
|
@ -67,7 +69,10 @@ class UtilCog(Extension):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
embed = build_embed(title=title, description=desc, fields=fields, color=color)
|
embed = build_embed(title=title, description=desc, fields=fields, color=color)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(
|
@slash_command(
|
||||||
name="logo",
|
name="logo",
|
||||||
|
@ -79,7 +84,10 @@ class UtilCog(Extension):
|
||||||
JARVIS_LOGO.save(image_bytes, "PNG")
|
JARVIS_LOGO.save(image_bytes, "PNG")
|
||||||
image_bytes.seek(0)
|
image_bytes.seek(0)
|
||||||
logo = File(image_bytes, file_name="logo.png")
|
logo = File(image_bytes, file_name="logo.png")
|
||||||
await ctx.send(file=logo)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(file=logo, components=components)
|
||||||
|
|
||||||
@slash_command(name="rchk", description="Robot Camo HK416")
|
@slash_command(name="rchk", description="Robot Camo HK416")
|
||||||
async def _rchk(self, ctx: InteractionContext) -> None:
|
async def _rchk(self, ctx: InteractionContext) -> None:
|
||||||
|
@ -130,7 +138,10 @@ class UtilCog(Extension):
|
||||||
embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE")
|
embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE")
|
||||||
embed.set_image(url=avatar)
|
embed.set_image(url=avatar)
|
||||||
embed.set_author(name=f"{user.username}#{user.discriminator}", icon_url=avatar)
|
embed.set_author(name=f"{user.username}#{user.discriminator}", icon_url=avatar)
|
||||||
await ctx.send(embeds=embed)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(
|
@slash_command(
|
||||||
name="roleinfo",
|
name="roleinfo",
|
||||||
|
@ -177,8 +188,10 @@ class UtilCog(Extension):
|
||||||
im.save(image_bytes, "PNG")
|
im.save(image_bytes, "PNG")
|
||||||
image_bytes.seek(0)
|
image_bytes.seek(0)
|
||||||
color_show = File(image_bytes, file_name="color_show.png")
|
color_show = File(image_bytes, file_name="color_show.png")
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed, file=color_show)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, file=color_show, components=components)
|
||||||
|
|
||||||
async def _userinfo(self, ctx: InteractionContext, user: User = None) -> None:
|
async def _userinfo(self, ctx: InteractionContext, user: User = None) -> None:
|
||||||
await ctx.defer()
|
await ctx.defer()
|
||||||
|
@ -224,8 +237,10 @@ class UtilCog(Extension):
|
||||||
)
|
)
|
||||||
embed.set_thumbnail(url=user.display_avatar.url)
|
embed.set_thumbnail(url=user.display_avatar.url)
|
||||||
embed.set_footer(text=f"ID: {user.id}")
|
embed.set_footer(text=f"ID: {user.id}")
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(
|
@slash_command(
|
||||||
name="userinfo",
|
name="userinfo",
|
||||||
|
@ -279,8 +294,10 @@ class UtilCog(Extension):
|
||||||
embed.set_author(name=guild.name, icon_url=guild.icon.url)
|
embed.set_author(name=guild.name, icon_url=guild.icon.url)
|
||||||
embed.set_thumbnail(url=guild.icon.url)
|
embed.set_thumbnail(url=guild.icon.url)
|
||||||
embed.set_footer(text=f"ID: {guild.id} | Server Created")
|
embed.set_footer(text=f"ID: {guild.id} | Server Created")
|
||||||
|
components = Button(
|
||||||
await ctx.send(embeds=embed)
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, components=components)
|
||||||
|
|
||||||
@slash_command(
|
@slash_command(
|
||||||
name="pw",
|
name="pw",
|
||||||
|
@ -375,7 +392,10 @@ class UtilCog(Extension):
|
||||||
EmbedField(name="ISO8601", value=timestamp.isoformat()),
|
EmbedField(name="ISO8601", value=timestamp.isoformat()),
|
||||||
]
|
]
|
||||||
embed = build_embed(title="Converted Time", description=f"`{string}`", fields=fields)
|
embed = build_embed(title="Converted Time", description=f"`{string}`", fields=fields)
|
||||||
await ctx.send(embeds=embed, ephemeral=private)
|
components = Button(
|
||||||
|
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||||
|
)
|
||||||
|
await ctx.send(embeds=embed, ephemeral=private, components=components)
|
||||||
|
|
||||||
@slash_command(name="support", description="Got issues?")
|
@slash_command(name="support", description="Got issues?")
|
||||||
async def _support(self, ctx: InteractionContext) -> None:
|
async def _support(self, ctx: InteractionContext) -> None:
|
||||||
|
|
Loading…
Add table
Reference in a new issue