Port autoreact, no more manual autoreact creation, closes #92
This commit is contained in:
parent
f147da994a
commit
c15510b74d
2 changed files with 112 additions and 127 deletions
10
README.md
10
README.md
|
@ -1,7 +1,7 @@
|
|||
<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">
|
||||
|
||||
# Just Another Very Intelligent System (J.A.R.V.I.S.)
|
||||
# Just AnotheR Very Intelligent System (J.A.R.V.I.S.)
|
||||
<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.
|
||||
|
||||
## Requirements
|
||||
- MongoDB 4.4 or higher
|
||||
- Python 3.8 or higher
|
||||
- MongoDB 5.0 or higher
|
||||
- Python 3.10 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:
|
||||
- `discord-py>=1.7, <2`
|
||||
- `dis-snek>=5.0.0`
|
||||
- `psutil>=5.8, <6`
|
||||
- `GitPython>=3.1, <4`
|
||||
- `PyYaml>=5.4, <6`
|
||||
- `discord-py-slash-command>=2.3.2, <3`
|
||||
- `pymongo>=3.12.0, <4`
|
||||
- `opencv-python>=4.5, <5`
|
||||
- `ButtonPaginator>=0.0.3`
|
||||
- `Pillow>=8.2.0, <9`
|
||||
- `python-gitlab>=2.9.0, <3`
|
||||
- `ulid-py>=1.1.0, <2`
|
||||
|
|
|
@ -1,46 +1,44 @@
|
|||
"""J.A.R.V.I.S. Autoreact Cog."""
|
||||
import re
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from discord import TextChannel
|
||||
from discord.ext import commands
|
||||
from discord.utils import find
|
||||
from discord_slash import SlashContext, cog_ext
|
||||
from discord_slash.utils.manage_commands import create_option
|
||||
from dis_snek import InteractionContext, Permissions, Scale, Snek
|
||||
from dis_snek.models.discord.channel import GuildText
|
||||
from dis_snek.models.snek.application_commands import (
|
||||
OptionTypes,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
||||
from jarvis.data.unicode import emoji_list
|
||||
from jarvis.db.models import Autoreact
|
||||
from jarvis.utils import find
|
||||
from jarvis.utils.permissions import admin_or_permissions
|
||||
|
||||
|
||||
class AutoReactCog(commands.Cog):
|
||||
class AutoReactCog(Scale):
|
||||
"""J.A.R.V.I.S. Autoreact Cog."""
|
||||
|
||||
def __init__(self, bot: commands.Bot):
|
||||
def __init__(self, bot: Snek):
|
||||
self.bot = bot
|
||||
self.custom_emote = re.compile(r"^<:\w+:(\d+)>$")
|
||||
|
||||
@cog_ext.cog_subcommand(
|
||||
base="autoreact",
|
||||
name="create",
|
||||
description="Add an autoreact to a channel",
|
||||
options=[
|
||||
create_option(
|
||||
name="channel",
|
||||
description="Channel to monitor",
|
||||
option_type=7,
|
||||
required=True,
|
||||
)
|
||||
],
|
||||
)
|
||||
@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
|
||||
async def create_autoreact(
|
||||
self, ctx: InteractionContext, channel: GuildText
|
||||
) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Create an autoreact monitor on a channel.
|
||||
|
||||
Args:
|
||||
ctx: Interaction context of command
|
||||
channel: Channel to monitor
|
||||
|
||||
Returns:
|
||||
Tuple of success? and error message
|
||||
"""
|
||||
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
|
||||
if exists:
|
||||
await ctx.send(f"Autoreact already exists for {channel.mention}.", hidden=True)
|
||||
return
|
||||
return False, f"Autoreact already exists for {channel.mention}."
|
||||
|
||||
_ = Autoreact(
|
||||
guild=ctx.guild.id,
|
||||
|
@ -48,50 +46,38 @@ class AutoReactCog(commands.Cog):
|
|||
reactions=[],
|
||||
admin=ctx.author.id,
|
||||
).save()
|
||||
await ctx.send(f"Autoreact created for {channel.mention}!")
|
||||
|
||||
@cog_ext.cog_subcommand(
|
||||
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)
|
||||
return True, None
|
||||
|
||||
@cog_ext.cog_subcommand(
|
||||
base="autoreact",
|
||||
name="add",
|
||||
description="Add an autoreact emote to an existing autoreact",
|
||||
options=[
|
||||
create_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to add emote to",
|
||||
option_type=7,
|
||||
required=True,
|
||||
),
|
||||
create_option(
|
||||
name="emote",
|
||||
description="Emote to add",
|
||||
option_type=3,
|
||||
required=True,
|
||||
),
|
||||
],
|
||||
async def delete_autoreact(self, ctx: InteractionContext, channel: GuildText) -> bool:
|
||||
"""
|
||||
Remove an autoreact monitor on a channel.
|
||||
|
||||
Args:
|
||||
ctx: Interaction context of command
|
||||
channel: Channel to stop monitoring
|
||||
|
||||
Returns:
|
||||
Success?
|
||||
"""
|
||||
return Autoreact.objects(guild=ctx.guild.id, channel=channel.id).delete() is not None
|
||||
|
||||
@slash_command(
|
||||
name="autoreact",
|
||||
sub_cmd_name="add",
|
||||
sub_cmd_description="Add an autoreact emote to a channel",
|
||||
)
|
||||
@admin_or_permissions(manage_guild=True)
|
||||
async def _autoreact_add(self, ctx: SlashContext, channel: TextChannel, emote: str) -> None:
|
||||
@slash_option(
|
||||
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()
|
||||
custom_emoji = self.custom_emote.match(emote)
|
||||
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):
|
||||
await ctx.send("Please use a custom emote from this server.", hidden=True)
|
||||
return
|
||||
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
|
||||
if not exists:
|
||||
await ctx.send(
|
||||
f"Please create autoreact first with /autoreact create {channel.mention}"
|
||||
)
|
||||
return
|
||||
if emote in exists.reactions:
|
||||
autoreact = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
|
||||
if not autoreact:
|
||||
self.create_autoreact(ctx, channel)
|
||||
autoreact = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
|
||||
if emote in autoreact.reactions:
|
||||
await ctx.send(
|
||||
f"Emote already added to {channel.mention} autoreactions.",
|
||||
hidden=True,
|
||||
)
|
||||
return
|
||||
if len(exists.reactions) >= 5:
|
||||
if len(autoreact.reactions) >= 5:
|
||||
await ctx.send(
|
||||
"Max number of reactions hit. Remove a different one to add this one",
|
||||
hidden=True,
|
||||
)
|
||||
return
|
||||
exists.reactions.append(emote)
|
||||
exists.save()
|
||||
autoreact.reactions.append(emote)
|
||||
autoreact.save()
|
||||
await ctx.send(f"Added {emote} to {channel.mention} autoreact.")
|
||||
|
||||
@cog_ext.cog_subcommand(
|
||||
base="autoreact",
|
||||
name="remove",
|
||||
description="Remove an autoreact emote from an existing autoreact",
|
||||
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,
|
||||
),
|
||||
],
|
||||
@slash_command(
|
||||
name="autoreact",
|
||||
sub_cmd_name="remove",
|
||||
sub_cmd_description="Remove an autoreact emote to a channel",
|
||||
)
|
||||
@admin_or_permissions(manage_guild=True)
|
||||
async def _autoreact_remove(self, ctx: SlashContext, channel: TextChannel, emote: str) -> None:
|
||||
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
|
||||
if not exists:
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to remove emote from",
|
||||
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(
|
||||
f"Please create autoreact first with /autoreact create {channel.mention}",
|
||||
f"Please create autoreact first with /autoreact add {channel.mention} {emote}",
|
||||
hidden=True,
|
||||
)
|
||||
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(
|
||||
f"{emote} not used in {channel.mention} autoreactions.",
|
||||
hidden=True,
|
||||
)
|
||||
return
|
||||
exists.reactions.remove(emote)
|
||||
exists.save()
|
||||
await ctx.send(f"Removed {emote} from {channel.mention} autoreact.")
|
||||
else:
|
||||
autoreact.reactions.remove(emote)
|
||||
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(
|
||||
base="autoreact",
|
||||
name="list",
|
||||
description="List all autoreacts on a channel",
|
||||
options=[
|
||||
create_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to list",
|
||||
option_type=7,
|
||||
required=True,
|
||||
),
|
||||
],
|
||||
@slash_command(
|
||||
name="autoreact",
|
||||
sub_cmd_name="list",
|
||||
sub_cmd_description="List all autoreacts on a channel",
|
||||
)
|
||||
@admin_or_permissions(manage_guild=True)
|
||||
async def _autoreact_list(self, ctx: SlashContext, channel: TextChannel) -> None:
|
||||
@slash_option(
|
||||
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()
|
||||
if not exists:
|
||||
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,
|
||||
)
|
||||
return
|
||||
|
@ -198,6 +185,6 @@ class AutoReactCog(commands.Cog):
|
|||
await ctx.send(message)
|
||||
|
||||
|
||||
def setup(bot: commands.Bot) -> None:
|
||||
def setup(bot: Snek) -> None:
|
||||
"""Add AutoReactCog to J.A.R.V.I.S."""
|
||||
bot.add_cog(AutoReactCog(bot))
|
||||
|
|
Loading…
Add table
Reference in a new issue