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">
|
<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`
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Add table
Reference in a new issue