From cfa9642fb36a467637d34198d704fcbe1770a9f9 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Sun, 25 Jul 2021 22:32:56 -0600 Subject: [PATCH 1/7] Use CacheCog where applicable --- jarvis/cogs/ctc2.py | 27 +++------------------------ jarvis/cogs/gitlab.py | 26 +++----------------------- jarvis/cogs/remindme.py | 28 +++------------------------- jarvis/cogs/settings.py | 1 - 4 files changed, 9 insertions(+), 73 deletions(-) diff --git a/jarvis/cogs/ctc2.py b/jarvis/cogs/ctc2.py index 66ca27b..7fdf00c 100644 --- a/jarvis/cogs/ctc2.py +++ b/jarvis/cogs/ctc2.py @@ -14,6 +14,7 @@ from discord_slash.model import ButtonStyle from jarvis.config import get_config from jarvis.db import DBManager from jarvis.utils import build_embed +from jarvis.utils.cachecog import CacheCog from jarvis.utils.field import Field guild_ids = [578757004059738142, 520021794380447745, 862402786116763668] @@ -25,26 +26,13 @@ invites = re.compile( ) -class CTCCog(commands.Cog): +class CTCCog(CacheCog): def __init__(self, bot): - self.bot = bot + super().__init__(bot) mconf = get_config().mongo self.db = DBManager(mconf).mongo self._session = aiohttp.ClientSession() self.url = "https://completethecodetwo.cards/pw" - self.cache = {} - self._expire_interaction.start() - - def check_cache(self, ctx: SlashContext, **kwargs): - if not kwargs: - kwargs = {} - return find( - lambda x: x["command"] == ctx.subcommand_name - and x["user"] == ctx.author.id - and x["guild"] == ctx.guild.id - and all(x[k] == v for k, v in kwargs.items()), - self.cache.values(), - ) @cog_ext.cog_subcommand( base="ctc2", @@ -178,15 +166,6 @@ class CTCCog(commands.Cog): await paginator.start() - @loop(minutes=1) - async def _expire_interaction(self): - keys = list(self.cache.keys()) - for key in keys: - if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta( - minutes=1 - ): - del self.cache[key] - def setup(bot): bot.add_cog(CTCCog(bot)) diff --git a/jarvis/cogs/gitlab.py b/jarvis/cogs/gitlab.py index eab291f..32c54b9 100644 --- a/jarvis/cogs/gitlab.py +++ b/jarvis/cogs/gitlab.py @@ -11,32 +11,21 @@ from discord_slash.utils.manage_commands import create_choice, create_option from jarvis.config import get_config from jarvis.utils import build_embed +from jarvis.utils.cachecog import CacheCog from jarvis.utils.field import Field guild_ids = [862402786116763668] -class GitlabCog(commands.Cog): +class GitlabCog(CacheCog): def __init__(self, bot): - self.bot = bot + super().__init__(bot) config = get_config() self._gitlab = gitlab.Gitlab( "https://git.zevaryx.com", private_token=config.gitlab_token ) # J.A.R.V.I.S. GitLab ID is 29 self.project = self._gitlab.projects.get(29) - self.cache = {} - self._expire_interaction.start() - - def check_cache(self, ctx: SlashContext, **kwargs): - if not kwargs: - kwargs = {} - return find( - lambda x: x["command"] == ctx.subcommand_name - and x["user"] == ctx.author.id - and all(x[k] == v for k, v in kwargs.items()), - self.cache.values(), - ) @cog_ext.cog_subcommand( base="gl", @@ -546,15 +535,6 @@ class GitlabCog(commands.Cog): await paginator.start() - @loop(minutes=1) - async def _expire_interaction(self): - keys = list(self.cache.keys()) - for key in keys: - if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta( - minutes=1 - ): - del self.cache[key] - def setup(bot): if get_config().gitlab_token: diff --git a/jarvis/cogs/remindme.py b/jarvis/cogs/remindme.py index df0cc58..550b90e 100644 --- a/jarvis/cogs/remindme.py +++ b/jarvis/cogs/remindme.py @@ -4,12 +4,10 @@ from datetime import datetime, timedelta from typing import Optional from bson import ObjectId -from ButtonPaginator import Paginator from discord.ext import commands from discord.ext.tasks import loop from discord.utils import find from discord_slash import SlashContext, cog_ext -from discord_slash.model import ButtonStyle from discord_slash.utils.manage_commands import create_option from discord_slash.utils.manage_components import ( create_actionrow, @@ -20,6 +18,7 @@ from discord_slash.utils.manage_components import ( from jarvis.db.types import Reminder from jarvis.utils import build_embed +from jarvis.utils.cachecog import CacheCog from jarvis.utils.field import Field valid = re.compile(r"[\w\s\-\\/.!@#$%^*()+=<>,\u0080-\U000E0FFF]*") @@ -29,23 +28,11 @@ invites = re.compile( ) -class RemindmeCog(commands.Cog): +class RemindmeCog(CacheCog): def __init__(self, bot): - self.bot = bot - self.cache = {} + super().__init__(bot) self._remind.start() - def check_cache(self, ctx: SlashContext, **kwargs): - if not kwargs: - kwargs = {} - return find( - lambda x: x["command"] == ctx.subcommand_name - and x["user"] == ctx.author.id - and x["guild"] == ctx.guild.id - and all(x[k] == v for k, v in kwargs.items()), - self.cache.values(), - ) - @cog_ext.cog_slash( name="remindme", description="Set a reminder", @@ -318,15 +305,6 @@ class RemindmeCog(commands.Cog): component["disabled"] = True await message.edit(components=components) - @loop(minutes=1) - async def _expire_interaction(self): - keys = list(self.cache.keys()) - for key in keys: - if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta( - minutes=1 - ): - del self.cache[key] - @loop(seconds=15) async def _remind(self): reminders = Reminder.get_active( diff --git a/jarvis/cogs/settings.py b/jarvis/cogs/settings.py index 215e0c8..52f9142 100644 --- a/jarvis/cogs/settings.py +++ b/jarvis/cogs/settings.py @@ -10,7 +10,6 @@ from jarvis.utils.permissions import admin_or_permissions class SettingsCog(commands.Cog): def __init__(self, bot): self.bot = bot - self.cache = {} def update_settings(self, setting, value, guild): setting = Setting(setting=setting, value=value, guild=guild) From 9a3c86815d43fa173db525a506fc2d26146094be Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:10:07 -0600 Subject: [PATCH 2/7] Permissions updates --- jarvis/cogs/admin/lock.py | 5 +- jarvis/cogs/admin/lockdown.py | 3 +- jarvis/cogs/admin/warning.py | 7 +- jarvis/cogs/autoreact.py | 10 +-- jarvis/cogs/gitlab.py | 3 + jarvis/cogs/rolegiver.py | 5 +- jarvis/cogs/settings.py | 12 ++-- jarvis/cogs/starboard.py | 122 +++++++++++++++++----------------- 8 files changed, 89 insertions(+), 78 deletions(-) diff --git a/jarvis/cogs/admin/lock.py b/jarvis/cogs/admin/lock.py index 1ee896b..c8c557f 100644 --- a/jarvis/cogs/admin/lock.py +++ b/jarvis/cogs/admin/lock.py @@ -7,6 +7,7 @@ from discord_slash.utils.manage_commands import create_option from jarvis.db.types import Lock from jarvis.utils.cachecog import CacheCog +from jarvis.utils.permissions import admin_or_permissions class LockCog(CacheCog): @@ -65,7 +66,7 @@ class LockCog(CacheCog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_channels=True) async def _lock( self, ctx: SlashContext, @@ -111,7 +112,7 @@ class LockCog(CacheCog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_channels=True) async def _unlock( self, ctx: SlashContext, diff --git a/jarvis/cogs/admin/lockdown.py b/jarvis/cogs/admin/lockdown.py index c023039..38c09ce 100644 --- a/jarvis/cogs/admin/lockdown.py +++ b/jarvis/cogs/admin/lockdown.py @@ -9,6 +9,7 @@ from jarvis.config import get_config from jarvis.db import DBManager from jarvis.db.types import Lock from jarvis.utils.cachecog import CacheCog +from jarvis.utils.permissions import admin_or_permissions class LockdownCog(CacheCog): @@ -35,7 +36,7 @@ class LockdownCog(CacheCog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_channels=True) async def _lockdown_start( self, ctx: SlashContext, diff --git a/jarvis/cogs/admin/warning.py b/jarvis/cogs/admin/warning.py index bd7bd12..da37235 100644 --- a/jarvis/cogs/admin/warning.py +++ b/jarvis/cogs/admin/warning.py @@ -11,6 +11,7 @@ from jarvis.db.types import MongoSort, Warning from jarvis.utils import build_embed from jarvis.utils.cachecog import CacheCog from jarvis.utils.field import Field +from jarvis.utils.permissions import admin_or_permissions class WarningCog(CacheCog): @@ -41,7 +42,7 @@ class WarningCog(CacheCog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _warn( self, ctx: SlashContext, user: User, reason: str, duration: int = 24 ): @@ -99,7 +100,7 @@ class WarningCog(CacheCog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _warnings(self, ctx: SlashContext, user: User, active: bool = 1): active = bool(active) exists = self.check_cache(ctx, user_id=user.id, active=active) @@ -132,7 +133,7 @@ class WarningCog(CacheCog): else: fields = [] for warn in active_warns: - admin = ctx.guild.get(warn.admin) + admin = ctx.guild.get_member(warn.admin) admin_name = "||`[redacted]`||" if admin: admin_name = f"{admin.name}#{admin.discriminator}" diff --git a/jarvis/cogs/autoreact.py b/jarvis/cogs/autoreact.py index ac83e11..1291c48 100644 --- a/jarvis/cogs/autoreact.py +++ b/jarvis/cogs/autoreact.py @@ -8,6 +8,7 @@ from discord_slash.utils.manage_commands import create_option from jarvis.data.unicode import emoji_list from jarvis.db.types import Autoreact +from jarvis.utils.permissions import admin_or_permissions class AutoReactCog(commands.Cog): @@ -28,7 +29,7 @@ class AutoReactCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _autoreact_create(self, ctx: SlashContext, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a text channel", hidden=True) @@ -62,6 +63,7 @@ class AutoReactCog(commands.Cog): ) ], ) + @admin_or_permissions(manage_server=True) async def _autoreact_delete(self, ctx, channel: TextChannel): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id).delete() if exists: @@ -90,7 +92,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _autoreact_add(self, ctx, channel: TextChannel, emote: str): await ctx.defer() custom_emoji = self.custom_emote.match(emote) @@ -152,7 +154,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _autoreact_remove(self, ctx, channel: TextChannel, emote: str): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id) if not exists: @@ -185,7 +187,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _autoreact_list(self, ctx, channel: TextChannel): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id) if not exists: diff --git a/jarvis/cogs/gitlab.py b/jarvis/cogs/gitlab.py index 32c54b9..bfe0198 100644 --- a/jarvis/cogs/gitlab.py +++ b/jarvis/cogs/gitlab.py @@ -368,6 +368,7 @@ class GitlabCog(CacheCog): self.cache[hash(paginator)] = { "user": ctx.author.id, + "guild": ctx.guild.id, "timeout": datetime.utcnow() + timedelta(minutes=5), "command": ctx.subcommand_name, "state": state, @@ -459,6 +460,7 @@ class GitlabCog(CacheCog): self.cache[hash(paginator)] = { "user": ctx.author.id, + "guild": ctx.guild.id, "timeout": datetime.utcnow() + timedelta(minutes=5), "command": ctx.subcommand_name, "state": state, @@ -528,6 +530,7 @@ class GitlabCog(CacheCog): self.cache[hash(paginator)] = { "user": ctx.author.id, + "guild": ctx.guild.id, "timeout": datetime.utcnow() + timedelta(minutes=5), "command": ctx.subcommand_name, "paginator": paginator, diff --git a/jarvis/cogs/rolegiver.py b/jarvis/cogs/rolegiver.py index 47aa7b9..2ddc932 100644 --- a/jarvis/cogs/rolegiver.py +++ b/jarvis/cogs/rolegiver.py @@ -6,6 +6,7 @@ from discord_slash.utils.manage_commands import create_option from jarvis.db.types import Setting from jarvis.utils import build_embed from jarvis.utils.field import Field +from jarvis.utils.permissions import admin_or_permissions class RolegiverCog(commands.Cog): @@ -25,7 +26,7 @@ class RolegiverCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _rolegiver_add(self, ctx: SlashContext, role: Role): setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") if setting and role.id in setting.value: @@ -82,7 +83,7 @@ class RolegiverCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _rolegiver_remove(self, ctx: SlashContext, role: Role): setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") if not setting or (setting and not setting.value): diff --git a/jarvis/cogs/settings.py b/jarvis/cogs/settings.py index 52f9142..530c15c 100644 --- a/jarvis/cogs/settings.py +++ b/jarvis/cogs/settings.py @@ -30,7 +30,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(mute_members=True) + @admin_or_permissions(manage_server=True) async def _mute(self, ctx, role: Role): await ctx.defer() self.update_settings("mute", role.id, ctx.guild.id) @@ -49,7 +49,7 @@ class SettingsCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _modlog(self, ctx, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a TextChannel", hidden=True) @@ -72,7 +72,7 @@ class SettingsCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _userlog(self, ctx, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a TextChannel", hidden=True) @@ -95,7 +95,7 @@ class SettingsCog(commands.Cog): ) ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _massmention(self, ctx, amount: int): await ctx.defer() self.update_settings("massmention", amount, ctx.guild.id) @@ -114,7 +114,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(kick_members=True, ban_members=True) + @admin_or_permissions(manage_server=True) async def _verified(self, ctx, role: Role): await ctx.defer() self.update_settings("verified", role.id, ctx.guild.id) @@ -133,7 +133,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(kick_members=True, ban_members=True) + @admin_or_permissions(manage_server=True) async def _unverified(self, ctx, role: Role): await ctx.defer() self.update_settings("unverified", role.id, ctx.guild.id) diff --git a/jarvis/cogs/starboard.py b/jarvis/cogs/starboard.py index dd27a43..e7f2604 100644 --- a/jarvis/cogs/starboard.py +++ b/jarvis/cogs/starboard.py @@ -5,6 +5,7 @@ from discord_slash.utils.manage_commands import create_option from jarvis.db.types import Star, Starboard from jarvis.utils import build_embed +from jarvis.utils.permissions import admin_or_permissions supported_images = [ "image/png", @@ -24,7 +25,7 @@ class StarboardCog(commands.Cog): name="list", description="Lists all Starboards", ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _list(self, ctx): starboards = Starboard.get_many(guild=ctx.guild.id) if starboards != []: @@ -48,7 +49,7 @@ class StarboardCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _create(self, ctx, channel: TextChannel): if channel not in ctx.guild.channels: await ctx.send( @@ -88,7 +89,7 @@ class StarboardCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _delete(self, ctx, channel: TextChannel): deleted = Starboard.get( channel=channel.id, guild=ctx.guild.id @@ -129,7 +130,7 @@ class StarboardCog(commands.Cog): ), ], ) - @commands.has_permissions(administrator=True) + @admin_or_permissions(manage_server=True) async def _star_add( self, ctx: SlashContext, @@ -216,66 +217,67 @@ class StarboardCog(commands.Cog): "Message saved to Starboard.\n" + f"See it in {starboard.mention}" ) - @cog_ext.cog_subcommand( - base="star", - name="delete", - description="Delete a starred message", - guild_ids=[ - 862402786116763668, - 418094694325813248, - 578757004059738142, - ], - options=[ - create_option( - name="id", - description="Star to delete", - option_type=4, - required=True, - ), - create_option( - name="starboard", - description="Starboard to delete star from", - option_type=7, - required=True, - ), - ], - ) - async def _star_get( - self, - ctx: SlashContext, - id: int, - starboard: TextChannel, - ): - if not isinstance(starboard, TextChannel): - await ctx.send("Channel must be a TextChannel", hidden=True) - return - exists = Starboard.get(channel=starboard.id, guild=ctx.guild.id) - if not exists: - await ctx.send( - f"Starboard does not exist in {starboard.mention}. " - + "Please create it first", - hidden=True, - ) - return - - star = Star.get( - starboard=starboard.id, - id=id, - guild=ctx.guild.id, - active=True, + @cog_ext.cog_subcommand( + base="star", + name="delete", + description="Delete a starred message", + guild_ids=[ + 862402786116763668, + 418094694325813248, + 578757004059738142, + ], + options=[ + create_option( + name="id", + description="Star to delete", + option_type=4, + required=True, + ), + create_option( + name="starboard", + description="Starboard to delete star from", + option_type=7, + required=True, + ), + ], + ) + @admin_or_permissions(manage_server=True) + async def _star_delete( + self, + ctx: SlashContext, + id: int, + starboard: TextChannel, + ): + if not isinstance(starboard, TextChannel): + await ctx.send("Channel must be a TextChannel", hidden=True) + return + exists = Starboard.get(channel=starboard.id, guild=ctx.guild.id) + if not exists: + await ctx.send( + f"Starboard does not exist in {starboard.mention}. " + + "Please create it first", + hidden=True, ) - if not star: - await ctx.send(f"No star exists with id {id}", hidden=True) - return + return - message = await starboard.fetch_message(star.star) - if message: - await message.delete() + star = Star.get( + starboard=starboard.id, + id=id, + guild=ctx.guild.id, + active=True, + ) + if not star: + await ctx.send(f"No star exists with id {id}", hidden=True) + return - star.active = False - star.update() + message = await starboard.fetch_message(star.star) + if message: + await message.delete() - await ctx.send(f"Star {id} deleted") + star.active = False + star.update() + + await ctx.send(f"Star {id} deleted") def setup(bot): From feda3036ab69c7f488bb54e17ab52a6227041a18 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:10:31 -0600 Subject: [PATCH 3/7] Fix events, also close #59 --- jarvis/events/guild.py | 39 +++-- jarvis/events/member.py | 35 +++-- jarvis/events/message.py | 324 ++++++++++++++++++++++----------------- 3 files changed, 226 insertions(+), 172 deletions(-) diff --git a/jarvis/events/guild.py b/jarvis/events/guild.py index 15528ce..708ffae 100644 --- a/jarvis/events/guild.py +++ b/jarvis/events/guild.py @@ -2,25 +2,30 @@ import asyncio from discord.utils import find -from jarvis import jarvis from jarvis.db.types import Setting -@jarvis.event -async def on_guild_join(guild): - general = find(lambda x: x.name == "general", guild.channels) - if general and general.permissions_for(guild.me).send_messages: - await general.send( - "Allow me to introduce myself. I am J.A.R.V.I.S., a virtual " - + "artificial intelligence, and I'm here to assist you with a " - + "variety of tasks as best I can, " - + "24 hours a day, seven days a week." - ) - await asyncio.sleep(1) - await general.send("Importing all preferences from home interface...") +class GuildEventHandler(object): + def __init__(self, bot): + self.bot = bot + self.bot.add_listener(self.on_guild_join) - # Set some default settings - setting = Setting(guild=guild.id, setting="massmention", value=5) - setting.insert() + async def on_guild_join(self, guild): + general = find(lambda x: x.name == "general", guild.channels) + if general and general.permissions_for(guild.me).send_messages: + await general.send( + "Allow me to introduce myself. I am J.A.R.V.I.S., a virtual " + + "artificial intelligence, and I'm here to assist you with a " + + "variety of tasks as best I can, " + + "24 hours a day, seven days a week." + ) + await asyncio.sleep(1) + await general.send( + "Importing all preferences from home interface..." + ) - await general.send("Systems are now fully operational") + # Set some default settings + setting = Setting(guild=guild.id, setting="massmention", value=5) + setting.insert() + + await general.send("Systems are now fully operational") diff --git a/jarvis/events/member.py b/jarvis/events/member.py index d706f62..91a0094 100644 --- a/jarvis/events/member.py +++ b/jarvis/events/member.py @@ -1,20 +1,25 @@ from discord import Member -from jarvis import jarvis from jarvis.db.types import Mute, Setting -@jarvis.event -async def on_member_join(user: Member): - guild = user.guild - mutes = Mute.get_active(guild=guild.id) - if mutes and len(mutes) >= 1: - mute_role = Setting.get(guild=guild.id, setting="mute") - role = guild.get_role(mute_role.value) - await user.add_roles( - role, reason="User is muted still muted from prior mute" - ) - unverified = Setting.get(guild=guild.id, setting="unverified") - if unverified: - role = guild.get_role(unverified.value) - await user.add_roles(role, reason="User just joined and is unverified") +class MemberEventHandler(object): + def __init__(self, bot): + self.bot = bot + self.bot.add_listener(self.on_member_join) + + async def on_member_join(self, user: Member): + guild = user.guild + mutes = Mute.get_active(guild=guild.id) + if mutes and len(mutes) >= 1: + mute_role = Setting.get(guild=guild.id, setting="mute") + role = guild.get_role(mute_role.value) + await user.add_roles( + role, reason="User is muted still muted from prior mute" + ) + unverified = Setting.get(guild=guild.id, setting="unverified") + if unverified: + role = guild.get_role(unverified.value) + await user.add_roles( + role, reason="User just joined and is unverified" + ) diff --git a/jarvis/events/message.py b/jarvis/events/message.py index d148b57..df89fff 100644 --- a/jarvis/events/message.py +++ b/jarvis/events/message.py @@ -3,9 +3,8 @@ import re from discord import DMChannel, Message from discord.utils import find -from jarvis import jarvis from jarvis.config import get_config -from jarvis.db.types import Autopurge, Autoreact, Setting +from jarvis.db.types import Autopurge, Autoreact, Roleping, Setting, Warning from jarvis.utils import build_embed from jarvis.utils.field import Field @@ -15,57 +14,182 @@ invites = re.compile( ) -async def autopurge(message): - autopurge = Autopurge.get( - guild=message.guild.id, channel=message.channel.id - ) - if autopurge: - await message.delete(delay=autopurge.delay) +class MessageEventHandler(object): + def __init__(self, bot): + self.bot = bot + self.bot.add_listener(self.on_message) - -async def autoreact(message): - autoreact = Autoreact.get( - guild=message.guild.id, - channel=message.channel.id, - ) - if autoreact: - for reaction in autoreact.reactions: - await message.add_reaction(reaction) - - -async def checks(message): - # #tech - channel = find( - lambda x: x.id == 599068193339736096, message.channel_mentions - ) - if channel and message.author.id == 293795462752894976: - await channel.send( - content="https://cdn.discordapp.com/attachments/" - + "664621130044407838/805218508866453554/tech.gif" + async def autopurge(self, message: Message): + autopurge = Autopurge.get( + guild=message.guild.id, channel=message.channel.id ) - content = re.sub(r"\s+", "", message.content) - match = invites.search(content) - if match: - guild_invites = await message.guild.invites() - allowed = [x.code for x in guild_invites] + [ - "dbrand", - "VtgZntXcnZ", - ] - if match.group(1) not in allowed: - await message.delete() + if autopurge: + await message.delete(delay=autopurge.delay) + + async def autoreact(self, message: Message): + autoreact = Autoreact.get( + guild=message.guild.id, + channel=message.channel.id, + ) + if autoreact: + for reaction in autoreact.reactions: + await message.add_reaction(reaction) + + async def checks(self, message: Message): + # #tech + channel = find( + lambda x: x.id == 599068193339736096, message.channel_mentions + ) + if channel and message.author.id == 293795462752894976: + await channel.send( + content="https://cdn.discordapp.com/attachments/" + + "664621130044407838/805218508866453554/tech.gif" + ) + content = re.sub(r"\s+", "", message.content) + match = invites.search(content) + if match: + guild_invites = await message.guild.invites() + allowed = [x.code for x in guild_invites] + [ + "dbrand", + "VtgZntXcnZ", + ] + if match.group(1) not in allowed: + await message.delete() + warning = Warning( + active=True, + admin=get_config().client_id, + duration=24, + guild=message.guild.id, + reason="Sent an invite link", + user=message.author.id, + ) + warning.insert() + fields = [ + Field( + "Reason", + "Sent an invite link", + False, + ) + ] + embed = build_embed( + title="Warning", + description=f"{message.author.mention} has been warned", + fields=fields, + ) + embed.set_author( + name=message.author.nick + if message.author.nick + else message.author.name, + icon_url=message.author.avatar_url, + ) + embed.set_footer( + text=f"{message.author.name}#" + + f"{message.author.discriminator} " + + f"| {message.author.id}" + ) + await message.channel.send(embed=embed) + + async def massmention(self, message: Message): + massmention = Setting.get( + guild=message.guild.id, + setting="massmention", + ) + if ( + massmention.value > 0 + and len(message.mentions) + - (1 if message.author in message.mentions else 0) + > massmention.value + ): warning = Warning( active=True, admin=get_config().client_id, duration=24, guild=message.guild.id, - reason="Sent an invite link", + reason="Mass Mention", + user=message.author.id, + ) + warning.insert() + fields = [Field("Reason", "Mass Mention", False)] + embed = build_embed( + title="Warning", + description=f"{message.author.mention} has been warned", + fields=fields, + ) + embed.set_author( + name=message.author.nick + if message.author.nick + else message.author.name, + icon_url=message.author.avatar_url, + ) + embed.set_footer( + text=f"{message.author.name}#{message.author.discriminator} " + + f"| {message.author.id}" + ) + await message.channel.send(embed=embed) + + async def roleping(self, message: Message): + rolepings = Roleping.get_active(guild=message.guild.id) + + if not rolepings: + return + + # Get all role IDs involved with message + roles = [] + for mention in message.role_mentions: + roles.append(mention.id) + for mention in message.mentions: + for role in mention.roles: + roles.append(role.id) + + if not roles: + return + + # Get all roles that are rolepinged + roleping_ids = [r.role for r in rolepings] + + # Get roles in rolepings + role_in_rolepings = list(filter(lambda x: x in roleping_ids, roles)) + + # Check if the user has the role, so they are allowed to ping it + user_missing_role = any( + x.id not in roleping_ids for x in message.author.roles + ) + + # Admins can ping whoever + user_is_admin = message.author.guild_permissions.administrator + + # Check if user in a bypass list + user_has_bypass = False + for roleping in rolepings: + if message.author.id in roleping.bypass["users"]: + user_has_bypass = True + break + if any( + role.id in roleping.bypass["roles"] + for role in message.author.roles + ): + user_has_bypass = True + break + + if ( + role_in_rolepings + and user_missing_role + and not user_is_admin + and not user_has_bypass + ): + warning = Warning( + active=True, + admin=get_config().client_id, + duration=24, + guild=message.guild.id, + reason="Pinged a blocked role/user with a blocked role", user=message.author.id, ) warning.insert() fields = [ Field( "Reason", - "Sent an invite link", + "Pinged a blocked role/user with a blocked role", False, ) ] @@ -81,108 +205,28 @@ async def checks(message): icon_url=message.author.avatar_url, ) embed.set_footer( - text=f"{message.author.name}#" - + f"{message.author.discriminator} " + text=f"{message.author.name}#{message.author.discriminator} " + f"| {message.author.id}" ) await message.channel.send(embed=embed) + async def on_message(self, message: Message): + if ( + not isinstance(message.channel, DMChannel) + and not message.author.bot + ): + await self.autoreact(message) + await self.massmention(message) + await self.roleping(message) + await self.autopurge(message) + await self.checks(message) + await self.bot.process_commands(message) -async def massmention(message): - massmention = Setting.get( - guild=message.guild.id, - setting="massmention", - ) - if ( - massmention.value > 0 - and len(message.mentions) - - (1 if message.author in message.mentions else 0) - > massmention.value - ): - warning = Warning( - active=True, - admin=get_config().client_id, - duration=24, - guild=message.guild.id, - reason="Mass Mention", - user=message.author.id, - ) - warning.insert() - fields = [Field("Reason", "Mass Mention", False)] - embed = build_embed( - title="Warning", - description=f"{message.author.mention} has been warned", - fields=fields, - ) - embed.set_author( - name=message.author.nick - if message.author.nick - else message.author.name, - icon_url=message.author.avatar_url, - ) - embed.set_footer( - text=f"{message.author.name}#{message.author.discriminator} " - + f"| {message.author.id}" - ) - await message.channel.send(embed=embed) - - -async def roleping(message): - roleping = Setting.get(guild=message.guild.id, setting="roleping") - roles = [] - for mention in message.role_mentions: - roles.append(mention.id) - for mention in message.mentions: - for role in mention.roles: - roles.append(role.id) - if ( - roleping - and any(x in roleping.value for x in roles) - and not any(x.id in roleping.value for x in message.author.roles) - ): - warning = Warning( - active=True, - admin=get_config().client_id, - duration=24, - guild=message.guild.id, - reason="Pinged a blocked role/user with a blocked role", - user=message.author.id, - ) - warning.insert() - fields = [ - Field( - "Reason", - "Pinged a blocked role/user with a blocked role", - False, - ) - ] - embed = build_embed( - title="Warning", - description=f"{message.author.mention} has been warned", - fields=fields, - ) - embed.set_author( - name=message.author.nick - if message.author.nick - else message.author.name, - icon_url=message.author.avatar_url, - ) - embed.set_footer( - text=f"{message.author.name}#{message.author.discriminator} " - + f"| {message.author.id}" - ) - await message.channel.send(embed=embed) - - -@jarvis.event -async def on_message(message: Message): - if ( - not isinstance(message.channel, DMChannel) - and message.author.id != jarvis.user.id - ): - await autoreact(message) - await massmention(message) - await roleping(message) - await autopurge(message) - await checks(message) - await jarvis.process_commands(message) + async def on_message_edit(self, message: Message): + if ( + not isinstance(message.channel, DMChannel) + and not message.author.bot + ): + await self.massmention(message) + await self.roleping(message) + await self.checks(message) From e48c987bcd7f1ec53b4ad7688ecf7d823e35a03f Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:10:49 -0600 Subject: [PATCH 4/7] Add roleping expansion, closes #38 --- jarvis/__init__.py | 9 + jarvis/cogs/admin/roleping.py | 379 +++++++++++++++++++++++++++++----- jarvis/db/types.py | 22 ++ 3 files changed, 364 insertions(+), 46 deletions(-) diff --git a/jarvis/__init__.py b/jarvis/__init__.py index 7feedcc..4c91d02 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -10,6 +10,7 @@ from psutil import Process from jarvis import logo, tasks, utils from jarvis.config import get_config from jarvis.db import DBManager +from jarvis.events import guild, member, message if asyncio.get_event_loop().is_closed(): asyncio.set_event_loop(asyncio.new_event_loop()) @@ -70,6 +71,14 @@ def run(ctx=None): jarvis.max_messages = config.max_messages tasks.init() + + # Add event listeners + listeners = [ + guild.GuildEventHandler(jarvis), + member.MemberEventHandler(jarvis), + message.MessageEventHandler(jarvis), + ] + jarvis.run(config.token, bot=True, reconnect=True) for cog in jarvis.cogs: session = getattr(cog, "_session", None) diff --git a/jarvis/cogs/admin/roleping.py b/jarvis/cogs/admin/roleping.py index 49786a6..f17b54a 100644 --- a/jarvis/cogs/admin/roleping.py +++ b/jarvis/cogs/admin/roleping.py @@ -1,71 +1,79 @@ -from discord import Role +from datetime import datetime, timedelta + +from ButtonPaginator import Paginator +from discord import Member, Role from discord.ext import commands from discord_slash import SlashContext, cog_ext +from discord_slash.model import ButtonStyle from discord_slash.utils.manage_commands import create_option -from jarvis.db.types import Setting +from jarvis.db.types import Roleping +from jarvis.utils import build_embed +from jarvis.utils.cachecog import CacheCog +from jarvis.utils.field import Field +from jarvis.utils.permissions import admin_or_permissions -class RolepingCog(commands.Cog): +class RolepingCog(CacheCog): def __init__(self, bot): - self.bot = bot + super().__init__(bot) @cog_ext.cog_subcommand( base="roleping", - name="block", - description="Add a role to the roleping blocklist", + name="add", + description="Add a role to roleping", options=[ create_option( name="role", - description="Role to add to blocklist", + description="Role to add to roleping", option_type=8, required=True, ) ], ) - @commands.has_permissions(administrator=True) - async def _roleping_block(self, ctx: SlashContext, role: Role): - roles = Setting.get(guild=ctx.guild.id, setting="roleping") - if not roles: - roles = Setting(guild=ctx.guild.id, setting="roleping", value=[]) + @admin_or_permissions(manage_server=True) + async def _roleping_add(self, ctx: SlashContext, role: Role): + roleping = Roleping.get(guild=ctx.guild.id, role=role.id) + if not roleping: + roleping = Roleping( + role=role.id, + guild=ctx.guild.id, + admin=ctx.author.id, + active=True, + bypass={"roles": [], "users": []}, + ) - if role.id in roles.value: + else: await ctx.send( - f"Role `{role.name}` already in blocklist.", hidden=True + f"Role `{role.name}` already in roleping.", hidden=True ) return - roles.value.append(role.id) - roles.update() - await ctx.send(f"Role `{role.name}` added to blocklist.") + + roleping.insert() + await ctx.send(f"Role `{role.name}` added to roleping.") @cog_ext.cog_subcommand( base="roleping", - name="allow", - description="Remove a role from the roleping blocklist", + name="remove", + description="Remove a role from the roleping", options=[ create_option( name="role", - description="Role to remove from blocklist", + description="Role to remove from roleping", option_type=8, required=True, ) ], ) - @commands.has_permissions(administrator=True) - async def _roleping_allow(self, ctx: SlashContext, role: Role): - roles = Setting.get(guild=ctx.guild.id, setting="roleping") - if not roles: - await ctx.send("No blocklist configured.", hidden=True) + @admin_or_permissions(manage_server=True) + async def _roleping_remove(self, ctx: SlashContext, role: Role): + roleping = Roleping.get(guild=ctx.guild.id, role=role.id) + if not roleping: + await ctx.send("Roleping does not exist", hidden=True) return - if role.id not in roles.value: - await ctx.send( - f"Role `{role.name}` not in blocklist.", hidden=True - ) - return - roles.value.remove(role.id) - roles.update() - await ctx.send(f"Role `{role.name}` removed blocklist.") + roleping.delete() + await ctx.send(f"Role `{role.name}` removed from roleping.") @cog_ext.cog_subcommand( base="roleping", @@ -73,19 +81,298 @@ class RolepingCog(commands.Cog): description="List all blocklisted roles", ) async def _roleping_list(self, ctx: SlashContext): - roles = Setting.get(guild=ctx.guild.id, setting="roleping") - if not roles: - await ctx.send("No blocklist configured.", hidden=True) + exists = self.check_cache(ctx) + if exists: + await ctx.defer(hidden=True) + await ctx.send( + "Please use existing interaction: " + + f"{exists['paginator']._message.jump_url}", + hidden=True, + ) return - message = "Blocklisted Roles:\n```\n" - if not roles.value: - await ctx.send("No roles blocklisted.", hidden=True) + rolepings = Roleping.get_many(guild=ctx.guild.id) + if not rolepings: + await ctx.send("No rolepings configured", hidden=True) return - for role in roles.value: - role = ctx.guild.get_role(role) - if not role: - continue - message += role.name + "\n" - message += "```" - await ctx.send(message) + + embeds = [] + for roleping in rolepings: + role = ctx.guild.get_role(roleping.role) + bypass_roles = list( + filter( + lambda x: x.id in roleping.bypass["roles"], ctx.guild.roles + ) + ) + bypass_roles = [ + r.mention or "||`[redacted]`||" for r in bypass_roles + ] + bypass_users = [ + ctx.guild.get_member(u).mention or "||`[redacted]`||" + for u in roleping.bypass["users"] + ] + bypass_roles = bypass_roles or ["None"] + bypass_users = bypass_users or ["None"] + embed = build_embed( + title="Roleping", + description=role.mention, + color=str(role.color), + fields=[ + Field( + name="Created At", + value=roleping.created_at.strftime( + "%a, %b %d, %Y %I:%M %p" + ), + inline=False, + ), + Field(name="Active", value=str(roleping.active)), + Field( + name="Bypass Users", + value="\n".join(bypass_users), + ), + Field( + name="Bypass Roles", + value="\n".join(bypass_roles), + ), + ], + ) + + admin = ctx.guild.get_member(roleping.admin) + if not admin: + admin = self.bot.user + + embed.set_author( + name=admin.nick or admin.name, icon_url=admin.avatar_url + ) + embed.set_footer( + text=f"{admin.name}#{admin.discriminator} | {admin.id}" + ) + + embeds.append(embed) + + paginator = Paginator( + bot=self.bot, + ctx=ctx, + embeds=embeds, + only=ctx.author, + timeout=60 * 5, # 5 minute timeout + disable_after_timeout=True, + use_extend=len(embeds) > 2, + left_button_style=ButtonStyle.grey, + right_button_style=ButtonStyle.grey, + basic_buttons=["◀", "▶"], + ) + + self.cache[hash(paginator)] = { + "user": ctx.author.id, + "guild": ctx.guild.id, + "timeout": datetime.utcnow() + timedelta(minutes=5), + "command": ctx.subcommand_name, + "paginator": paginator, + } + + await paginator.start() + + @cog_ext.cog_subcommand( + base="roleping", + subcommand_group="bypass", + name="user", + description="Add a user as a bypass to a roleping", + base_desc="Block roles from being pinged", + sub_group_desc="Allow specific users/roles to ping rolepings", + options=[ + create_option( + name="user", + description="User to add", + option_type=6, + required=True, + ), + create_option( + name="rping", + description="Rolepinged role", + option_type=8, + required=True, + ), + ], + ) + @admin_or_permissions(manage_server=True) + async def _roleping_bypass_user( + self, ctx: SlashContext, user: Member, rping: Role + ): + roleping = Roleping.get(guild=ctx.guild.id, role=rping.id) + if not roleping: + await ctx.send( + f"Roleping not configured for {rping.mention}", hidden=True + ) + return + + if user.id in roleping.bypass["users"]: + await ctx.send(f"{user.mention} already in bypass", hidden=True) + return + + if len(roleping.bypass["users"]) == 10: + await ctx.send( + "Already have 10 users in bypass. " + "Please consider using roles for roleping bypass", + hidden=True, + ) + return + + matching_role = list( + filter(lambda x: x.id in roleping.bypass["roles"], user.roles) + ) + + if matching_role: + await ctx.send( + f"{user.mention} already has bypass " + f"via {matching_role[0].mention}", + hidden=True, + ) + return + + roleping.bypass["users"].append(user.id) + roleping.update() + await ctx.send( + f"{user.nick or user.name} user bypass added for `{rping.name}`" + ) + + @cog_ext.cog_subcommand( + base="roleping", + subcommand_group="bypass", + name="role", + description="Add a role as a bypass to a roleping", + base_desc="Block roles from being pinged", + sub_group_desc="Allow specific users/roles to ping rolepings", + options=[ + create_option( + name="role", + description="Role to add", + option_type=8, + required=True, + ), + create_option( + name="rping", + description="Rolepinged role", + option_type=8, + required=True, + ), + ], + ) + @admin_or_permissions(manage_server=True) + async def _roleping_bypass_role( + self, ctx: SlashContext, role: Role, rping: Role + ): + roleping = Roleping.get(guild=ctx.guild.id, role=rping.id) + if not roleping: + await ctx.send( + f"Roleping not configured for {rping.mention}", hidden=True + ) + return + + if role.id in roleping.bypass["roles"]: + await ctx.send(f"{role.mention} already in bypass", hidden=True) + return + + if len(roleping.bypass["roles"]) == 10: + await ctx.send( + "Already have 10 roles in bypass. " + "Please consider consolidating roles for roleping bypass", + hidden=True, + ) + return + + roleping.bypass["roles"].append(role.id) + roleping.update() + await ctx.send(f"{role.name} role bypass added for `{rping.name}`") + + @cog_ext.cog_subcommand( + base="roleping", + subcommand_group="restore", + name="user", + description="Remove a role bypass", + base_desc="Block roles from being pinged", + sub_group_desc="Remove a bypass from a roleping (restoring it)", + options=[ + create_option( + name="user", + description="User to add", + option_type=6, + required=True, + ), + create_option( + name="rping", + description="Rolepinged role", + option_type=8, + required=True, + ), + ], + ) + @admin_or_permissions(manage_server=True) + async def _roleping_restore_user( + self, ctx: SlashContext, user: Member, rping: Role + ): + roleping = Roleping.get(guild=ctx.guild.id, role=rping.id) + if not roleping: + await ctx.send( + f"Roleping not configured for {rping.mention}", hidden=True + ) + return + + if user.id not in roleping.bypass["users"]: + await ctx.send(f"{user.mention} not in bypass", hidden=True) + return + + roleping.bypass["users"].delete(user.id) + roleping.update() + await ctx.send( + f"{user.nick or user.name} user bypass removed for `{rping.name}`" + ) + + @cog_ext.cog_subcommand( + base="roleping", + subcommand_group="restore", + name="role", + description="Remove a role bypass", + base_desc="Block roles from being pinged", + sub_group_desc="Remove a bypass from a roleping (restoring it)", + options=[ + create_option( + name="role", + description="Role to add", + option_type=8, + required=True, + ), + create_option( + name="rping", + description="Rolepinged role", + option_type=8, + required=True, + ), + ], + ) + @admin_or_permissions(manage_server=True) + async def _roleping_restore_role( + self, ctx: SlashContext, role: Role, rping: Role + ): + roleping = Roleping.get(guild=ctx.guild.id, role=rping.id) + if not roleping: + await ctx.send( + f"Roleping not configured for {rping.mention}", hidden=True + ) + return + + if role.id in roleping.bypass["roles"]: + await ctx.send(f"{role.mention} already in bypass", hidden=True) + return + + if len(roleping.bypass["roles"]) == 10: + await ctx.send( + "Already have 10 roles in bypass. " + "Please consider consolidating roles for roleping bypass", + hidden=True, + ) + return + + roleping.bypass["roles"].append(role.id) + roleping.update() + await ctx.send(f"{role.name} role bypass added for `{rping.name}`") diff --git a/jarvis/db/types.py b/jarvis/db/types.py index d70094e..19ba060 100644 --- a/jarvis/db/types.py +++ b/jarvis/db/types.py @@ -28,6 +28,7 @@ coll_lookup = { "Mute": "mutes", "Purge": "purges", "Reminder": "reminders", + "Roleping": "rolepings", "Setting": "settings", "Starboard": "starboard", "Star": "stars", @@ -460,6 +461,27 @@ class Reminder(MongoObject, ActiveObject): created_at: datetime = field(default_factory=datetime.utcnow) +@dataclass +class Roleping(MongoObject, ActiveObject): + """ + Guild Roleping object + + :param _id: MongoDB ID + :param role: Blocked role + :param guild: ID of origin guild + :param admin: Admin who added roleping + :param bypass: Roles/users who may bypass this roleping + :param active: If the roleping is disabled + :param created_at: Time the roleping was created + """ + + role: int + guild: int + admin: int + bypass: dict + created_at: datetime = field(default_factory=datetime.utcnow) + + @dataclass class Setting(MongoObject): """ From acb2d6ff3eef6020f4eaedc3331a995904469377 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:12:23 -0600 Subject: [PATCH 5/7] manage_server -> manage_guild --- jarvis/cogs/admin/roleping.py | 12 ++++++------ jarvis/cogs/admin/warning.py | 4 ++-- jarvis/cogs/autoreact.py | 10 +++++----- jarvis/cogs/rolegiver.py | 4 ++-- jarvis/cogs/settings.py | 12 ++++++------ jarvis/cogs/starboard.py | 10 +++++----- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/jarvis/cogs/admin/roleping.py b/jarvis/cogs/admin/roleping.py index f17b54a..283f3eb 100644 --- a/jarvis/cogs/admin/roleping.py +++ b/jarvis/cogs/admin/roleping.py @@ -31,7 +31,7 @@ class RolepingCog(CacheCog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_add(self, ctx: SlashContext, role: Role): roleping = Roleping.get(guild=ctx.guild.id, role=role.id) if not roleping: @@ -65,7 +65,7 @@ class RolepingCog(CacheCog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_remove(self, ctx: SlashContext, role: Role): roleping = Roleping.get(guild=ctx.guild.id, role=role.id) if not roleping: @@ -195,7 +195,7 @@ class RolepingCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_bypass_user( self, ctx: SlashContext, user: Member, rping: Role ): @@ -258,7 +258,7 @@ class RolepingCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_bypass_role( self, ctx: SlashContext, role: Role, rping: Role ): @@ -307,7 +307,7 @@ class RolepingCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_restore_user( self, ctx: SlashContext, user: Member, rping: Role ): @@ -350,7 +350,7 @@ class RolepingCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _roleping_restore_role( self, ctx: SlashContext, role: Role, rping: Role ): diff --git a/jarvis/cogs/admin/warning.py b/jarvis/cogs/admin/warning.py index da37235..cb424eb 100644 --- a/jarvis/cogs/admin/warning.py +++ b/jarvis/cogs/admin/warning.py @@ -42,7 +42,7 @@ class WarningCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _warn( self, ctx: SlashContext, user: User, reason: str, duration: int = 24 ): @@ -100,7 +100,7 @@ class WarningCog(CacheCog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _warnings(self, ctx: SlashContext, user: User, active: bool = 1): active = bool(active) exists = self.check_cache(ctx, user_id=user.id, active=active) diff --git a/jarvis/cogs/autoreact.py b/jarvis/cogs/autoreact.py index 1291c48..10aa5b9 100644 --- a/jarvis/cogs/autoreact.py +++ b/jarvis/cogs/autoreact.py @@ -29,7 +29,7 @@ class AutoReactCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _autoreact_create(self, ctx: SlashContext, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a text channel", hidden=True) @@ -63,7 +63,7 @@ class AutoReactCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _autoreact_delete(self, ctx, channel: TextChannel): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id).delete() if exists: @@ -92,7 +92,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _autoreact_add(self, ctx, channel: TextChannel, emote: str): await ctx.defer() custom_emoji = self.custom_emote.match(emote) @@ -154,7 +154,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _autoreact_remove(self, ctx, channel: TextChannel, emote: str): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id) if not exists: @@ -187,7 +187,7 @@ class AutoReactCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _autoreact_list(self, ctx, channel: TextChannel): exists = Autoreact.get(guild=ctx.guild.id, channel=channel.id) if not exists: diff --git a/jarvis/cogs/rolegiver.py b/jarvis/cogs/rolegiver.py index 2ddc932..a9b77de 100644 --- a/jarvis/cogs/rolegiver.py +++ b/jarvis/cogs/rolegiver.py @@ -26,7 +26,7 @@ class RolegiverCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _rolegiver_add(self, ctx: SlashContext, role: Role): setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") if setting and role.id in setting.value: @@ -83,7 +83,7 @@ class RolegiverCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _rolegiver_remove(self, ctx: SlashContext, role: Role): setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") if not setting or (setting and not setting.value): diff --git a/jarvis/cogs/settings.py b/jarvis/cogs/settings.py index 530c15c..814b101 100644 --- a/jarvis/cogs/settings.py +++ b/jarvis/cogs/settings.py @@ -30,7 +30,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _mute(self, ctx, role: Role): await ctx.defer() self.update_settings("mute", role.id, ctx.guild.id) @@ -49,7 +49,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _modlog(self, ctx, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a TextChannel", hidden=True) @@ -72,7 +72,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _userlog(self, ctx, channel: TextChannel): if not isinstance(channel, TextChannel): await ctx.send("Channel must be a TextChannel", hidden=True) @@ -95,7 +95,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _massmention(self, ctx, amount: int): await ctx.defer() self.update_settings("massmention", amount, ctx.guild.id) @@ -114,7 +114,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _verified(self, ctx, role: Role): await ctx.defer() self.update_settings("verified", role.id, ctx.guild.id) @@ -133,7 +133,7 @@ class SettingsCog(commands.Cog): ) ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _unverified(self, ctx, role: Role): await ctx.defer() self.update_settings("unverified", role.id, ctx.guild.id) diff --git a/jarvis/cogs/starboard.py b/jarvis/cogs/starboard.py index e7f2604..eba9678 100644 --- a/jarvis/cogs/starboard.py +++ b/jarvis/cogs/starboard.py @@ -25,7 +25,7 @@ class StarboardCog(commands.Cog): name="list", description="Lists all Starboards", ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _list(self, ctx): starboards = Starboard.get_many(guild=ctx.guild.id) if starboards != []: @@ -49,7 +49,7 @@ class StarboardCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _create(self, ctx, channel: TextChannel): if channel not in ctx.guild.channels: await ctx.send( @@ -89,7 +89,7 @@ class StarboardCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _delete(self, ctx, channel: TextChannel): deleted = Starboard.get( channel=channel.id, guild=ctx.guild.id @@ -130,7 +130,7 @@ class StarboardCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _star_add( self, ctx: SlashContext, @@ -241,7 +241,7 @@ class StarboardCog(commands.Cog): ), ], ) - @admin_or_permissions(manage_server=True) + @admin_or_permissions(manage_guild=True) async def _star_delete( self, ctx: SlashContext, From 2a7bf32aab2a175fb960e10a5d41ea39b7802983 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:26:07 -0600 Subject: [PATCH 6/7] Add on_message_edit event listener --- jarvis/events/message.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/jarvis/events/message.py b/jarvis/events/message.py index df89fff..28a62cd 100644 --- a/jarvis/events/message.py +++ b/jarvis/events/message.py @@ -18,6 +18,7 @@ class MessageEventHandler(object): def __init__(self, bot): self.bot = bot self.bot.add_listener(self.on_message) + self.bot.add_listener(self.on_message_edit) async def autopurge(self, message: Message): autopurge = Autopurge.get( @@ -222,11 +223,8 @@ class MessageEventHandler(object): await self.checks(message) await self.bot.process_commands(message) - async def on_message_edit(self, message: Message): - if ( - not isinstance(message.channel, DMChannel) - and not message.author.bot - ): - await self.massmention(message) - await self.roleping(message) - await self.checks(message) + async def on_message_edit(self, before: Message, after: Message): + if not isinstance(after.channel, DMChannel) and not after.author.bot: + await self.massmention(after) + await self.roleping(after) + await self.checks(after) From 421328662dd9f586d21f4dc3abd0e68a910eb118 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Mon, 26 Jul 2021 19:26:41 -0600 Subject: [PATCH 7/7] Bump version to 1.8.0 --- jarvis/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jarvis/__init__.py b/jarvis/__init__.py index 4c91d02..35b18cf 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -25,7 +25,7 @@ jarvis = commands.Bot( ) slash = SlashCommand(jarvis, sync_commands=True, sync_on_cog_reload=True) jarvis_self = Process() -__version__ = "1.7.0" +__version__ = "1.8.0" db = DBManager(get_config().mongo).mongo