Port autoreact, no more manual autoreact creation, closes #92

This commit is contained in:
Zeva Rose 2022-02-03 04:56:20 -07:00
parent f147da994a
commit c15510b74d
2 changed files with 112 additions and 127 deletions

View file

@ -1,7 +1,7 @@
<div align="center"> <div align="center">
<img width=15% alt="J.A.R.V.I.S" src="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./-/raw/main/jarvis_small.png"> <img width=15% alt="J.A.R.V.I.S" src="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./-/raw/main/jarvis_small.png">
# Just Another Very Intelligent System (J.A.R.V.I.S.) # Just AnotheR Very Intelligent System (J.A.R.V.I.S.)
<br /> <br />
@ -38,19 +38,17 @@ If you wish to contribute to the J.A.R.V.I.S codebase or documentation, join the
Join the [Stark R&D Department Discord server](https://discord.gg/VtgZntXcnZ) to be kept up-to-date on code updates and issues. Join the [Stark R&D Department Discord server](https://discord.gg/VtgZntXcnZ) to be kept up-to-date on code updates and issues.
## Requirements ## Requirements
- MongoDB 4.4 or higher - MongoDB 5.0 or higher
- Python 3.8 or higher - Python 3.10 or higher
- [tokei](https://github.com/XAMPPRocky/tokei) 12.1 or higher - [tokei](https://github.com/XAMPPRocky/tokei) 12.1 or higher
On top of the above requirements, the following pip packages are also required: On top of the above requirements, the following pip packages are also required:
- `discord-py>=1.7, <2` - `dis-snek>=5.0.0`
- `psutil>=5.8, <6` - `psutil>=5.8, <6`
- `GitPython>=3.1, <4` - `GitPython>=3.1, <4`
- `PyYaml>=5.4, <6` - `PyYaml>=5.4, <6`
- `discord-py-slash-command>=2.3.2, <3`
- `pymongo>=3.12.0, <4` - `pymongo>=3.12.0, <4`
- `opencv-python>=4.5, <5` - `opencv-python>=4.5, <5`
- `ButtonPaginator>=0.0.3`
- `Pillow>=8.2.0, <9` - `Pillow>=8.2.0, <9`
- `python-gitlab>=2.9.0, <3` - `python-gitlab>=2.9.0, <3`
- `ulid-py>=1.1.0, <2` - `ulid-py>=1.1.0, <2`

View file

@ -1,46 +1,44 @@
"""J.A.R.V.I.S. Autoreact Cog.""" """J.A.R.V.I.S. Autoreact Cog."""
import re import re
from typing import Optional, Tuple
from discord import TextChannel from dis_snek import InteractionContext, Permissions, Scale, Snek
from discord.ext import commands from dis_snek.models.discord.channel import GuildText
from discord.utils import find from dis_snek.models.snek.application_commands import (
from discord_slash import SlashContext, cog_ext OptionTypes,
from discord_slash.utils.manage_commands import create_option slash_command,
slash_option,
)
from jarvis.data.unicode import emoji_list from jarvis.data.unicode import emoji_list
from jarvis.db.models import Autoreact from jarvis.db.models import Autoreact
from jarvis.utils import find
from jarvis.utils.permissions import admin_or_permissions from jarvis.utils.permissions import admin_or_permissions
class AutoReactCog(commands.Cog): class AutoReactCog(Scale):
"""J.A.R.V.I.S. Autoreact Cog.""" """J.A.R.V.I.S. Autoreact Cog."""
def __init__(self, bot: commands.Bot): def __init__(self, bot: Snek):
self.bot = bot self.bot = bot
self.custom_emote = re.compile(r"^<:\w+:(\d+)>$") self.custom_emote = re.compile(r"^<:\w+:(\d+)>$")
@cog_ext.cog_subcommand( async def create_autoreact(
base="autoreact", self, ctx: InteractionContext, channel: GuildText
name="create", ) -> Tuple[bool, Optional[str]]:
description="Add an autoreact to a channel", """
options=[ Create an autoreact monitor on a channel.
create_option(
name="channel", Args:
description="Channel to monitor", ctx: Interaction context of command
option_type=7, channel: Channel to monitor
required=True,
) Returns:
], Tuple of success? and error message
) """
@admin_or_permissions(manage_guild=True)
async def _autoreact_create(self, ctx: SlashContext, channel: TextChannel) -> None:
if not isinstance(channel, TextChannel):
await ctx.send("Channel must be a text channel", hidden=True)
return
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first() exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if exists: if exists:
await ctx.send(f"Autoreact already exists for {channel.mention}.", hidden=True) return False, f"Autoreact already exists for {channel.mention}."
return
_ = Autoreact( _ = Autoreact(
guild=ctx.guild.id, guild=ctx.guild.id,
@ -48,50 +46,38 @@ class AutoReactCog(commands.Cog):
reactions=[], reactions=[],
admin=ctx.author.id, admin=ctx.author.id,
).save() ).save()
await ctx.send(f"Autoreact created for {channel.mention}!")
@cog_ext.cog_subcommand( return True, None
base="autoreact",
name="delete",
description="Delete an autoreact from a channel",
options=[
create_option(
name="channel",
description="Channel to stop monitoring",
option_type=7,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _autoreact_delete(self, ctx: SlashContext, channel: TextChannel) -> None:
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).delete()
if exists:
await ctx.send(f"Autoreact removed from {channel.mention}")
else:
await ctx.send(f"Autoreact not found on {channel.mention}", hidden=True)
@cog_ext.cog_subcommand( async def delete_autoreact(self, ctx: InteractionContext, channel: GuildText) -> bool:
base="autoreact", """
name="add", Remove an autoreact monitor on a channel.
description="Add an autoreact emote to an existing autoreact",
options=[ Args:
create_option( ctx: Interaction context of command
name="channel", channel: Channel to stop monitoring
description="Autoreact channel to add emote to",
option_type=7, Returns:
required=True, Success?
), """
create_option( return Autoreact.objects(guild=ctx.guild.id, channel=channel.id).delete() is not None
name="emote",
description="Emote to add", @slash_command(
option_type=3, name="autoreact",
required=True, sub_cmd_name="add",
), sub_cmd_description="Add an autoreact emote to a channel",
],
) )
@admin_or_permissions(manage_guild=True) @slash_option(
async def _autoreact_add(self, ctx: SlashContext, channel: TextChannel, emote: str) -> None: name="channel",
description="Autoreact channel to add emote to",
option_type=OptionTypes.CHANNEL,
required=True,
)
@slash_option(
name="emote", description="Emote to add", option_type=OptionTypes.STRING, required=True
)
@admin_or_permissions(Permissions.MANAGE_GUILD)
async def _autoreact_add(self, ctx: InteractionContext, channel: GuildText, emote: str) -> None:
await ctx.defer() await ctx.defer()
custom_emoji = self.custom_emote.match(emote) custom_emoji = self.custom_emote.match(emote)
standard_emoji = emote in emoji_list standard_emoji = emote in emoji_list
@ -106,85 +92,86 @@ class AutoReactCog(commands.Cog):
if not find(lambda x: x.id == emoji_id, ctx.guild.emojis): if not find(lambda x: x.id == emoji_id, ctx.guild.emojis):
await ctx.send("Please use a custom emote from this server.", hidden=True) await ctx.send("Please use a custom emote from this server.", hidden=True)
return return
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first() autoreact = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not exists: if not autoreact:
await ctx.send( self.create_autoreact(ctx, channel)
f"Please create autoreact first with /autoreact create {channel.mention}" autoreact = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
) if emote in autoreact.reactions:
return
if emote in exists.reactions:
await ctx.send( await ctx.send(
f"Emote already added to {channel.mention} autoreactions.", f"Emote already added to {channel.mention} autoreactions.",
hidden=True, hidden=True,
) )
return return
if len(exists.reactions) >= 5: if len(autoreact.reactions) >= 5:
await ctx.send( await ctx.send(
"Max number of reactions hit. Remove a different one to add this one", "Max number of reactions hit. Remove a different one to add this one",
hidden=True, hidden=True,
) )
return return
exists.reactions.append(emote) autoreact.reactions.append(emote)
exists.save() autoreact.save()
await ctx.send(f"Added {emote} to {channel.mention} autoreact.") await ctx.send(f"Added {emote} to {channel.mention} autoreact.")
@cog_ext.cog_subcommand( @slash_command(
base="autoreact", name="autoreact",
name="remove", sub_cmd_name="remove",
description="Remove an autoreact emote from an existing autoreact", sub_cmd_description="Remove an autoreact emote to a channel",
options=[
create_option(
name="channel",
description="Autoreact channel to remove emote from",
option_type=7,
required=True,
),
create_option(
name="emote",
description="Emote to remove",
option_type=3,
required=True,
),
],
) )
@admin_or_permissions(manage_guild=True) @slash_option(
async def _autoreact_remove(self, ctx: SlashContext, channel: TextChannel, emote: str) -> None: name="channel",
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first() description="Autoreact channel to remove emote from",
if not exists: option_type=OptionTypes.CHANNEL,
required=True,
)
@slash_option(
name="emote",
description="Emote to remove (use all to delete)",
option_type=OptionTypes.STRING,
required=True,
)
@admin_or_permissions(Permissions.MANAGE_GUILD)
async def _autoreact_remove(
self, ctx: InteractionContext, channel: GuildText, emote: str
) -> None:
autoreact = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not autoreact:
await ctx.send( await ctx.send(
f"Please create autoreact first with /autoreact create {channel.mention}", f"Please create autoreact first with /autoreact add {channel.mention} {emote}",
hidden=True, hidden=True,
) )
return return
if emote not in exists.reactions: if emote.lower() == "all":
self.delete_autoreact(ctx, channel)
await ctx.send(f"Autoreact removed from {channel.mention}")
elif emote not in autoreact.reactions:
await ctx.send( await ctx.send(
f"{emote} not used in {channel.mention} autoreactions.", f"{emote} not used in {channel.mention} autoreactions.",
hidden=True, hidden=True,
) )
return return
exists.reactions.remove(emote) else:
exists.save() autoreact.reactions.remove(emote)
await ctx.send(f"Removed {emote} from {channel.mention} autoreact.") autoreact.save()
if len(autoreact.reactions) == 0:
self.delete_autoreact(ctx, channel)
await ctx.send(f"Removed {emote} from {channel.mention} autoreact.")
@cog_ext.cog_subcommand( @slash_command(
base="autoreact", name="autoreact",
name="list", sub_cmd_name="list",
description="List all autoreacts on a channel", sub_cmd_description="List all autoreacts on a channel",
options=[
create_option(
name="channel",
description="Autoreact channel to list",
option_type=7,
required=True,
),
],
) )
@admin_or_permissions(manage_guild=True) @slash_option(
async def _autoreact_list(self, ctx: SlashContext, channel: TextChannel) -> None: name="channel",
description="Autoreact channel to list",
option_type=OptionTypes.CHANNEL,
required=True,
)
async def _autoreact_list(self, ctx: InteractionContext, channel: GuildText) -> None:
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first() exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not exists: if not exists:
await ctx.send( await ctx.send(
f"Please create autoreact first with /autoreact create {channel.mention}", f"Please create autoreact first with /autoreact add {channel.mention} <emote>",
hidden=True, hidden=True,
) )
return return
@ -198,6 +185,6 @@ class AutoReactCog(commands.Cog):
await ctx.send(message) await ctx.send(message)
def setup(bot: commands.Bot) -> None: def setup(bot: Snek) -> None:
"""Add AutoReactCog to J.A.R.V.I.S.""" """Add AutoReactCog to J.A.R.V.I.S."""
bot.add_cog(AutoReactCog(bot)) bot.add_cog(AutoReactCog(bot))