diff options
| author | 2018-07-21 02:46:12 +0200 | |
|---|---|---|
| committer | 2018-07-21 02:46:12 +0200 | |
| commit | 50548104768b500b12ef5773d3654565b3eb84d1 (patch) | |
| tree | 949ebf431b44d44358e5f5e4505c94be2a386132 | |
| parent | Adding all help channels to code block detection channel list, and setting de... (diff) | |
initial commit for the cleaning cog. Not completely done, need to merge in master so I can work with new changes from modlog merge.
| -rw-r--r-- | bot/__main__.py | 1 | ||||
| -rw-r--r-- | bot/cogs/clean.py | 152 | ||||
| -rw-r--r-- | bot/constants.py | 9 | ||||
| -rw-r--r-- | config-default.yml | 2 |
4 files changed, 164 insertions, 0 deletions
diff --git a/bot/__main__.py b/bot/__main__.py index 9014bce14..70336cb59 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -53,6 +53,7 @@ bot.load_extension("bot.cogs.events") # Commands, etc bot.load_extension("bot.cogs.bigbrother") bot.load_extension("bot.cogs.bot") +bot.load_extension("bot.cogs.clean") bot.load_extension("bot.cogs.cogs") # Local setups usually don't have the clickup key set, diff --git a/bot/cogs/clean.py b/bot/cogs/clean.py new file mode 100644 index 000000000..8848befab --- /dev/null +++ b/bot/cogs/clean.py @@ -0,0 +1,152 @@ +import json +import logging +import random + +from discord import Embed, Message, User, Colour +from discord.ext.commands import Bot, Context, group + +from bot.constants import Roles, Clean, URLs, Keys, NEGATIVE_REPLIES +from bot.decorators import with_role + +log = logging.getLogger(__name__) + + +class Clean: + + def __init__(self, bot: Bot): + self.bot = bot + self.headers = {"X-API-KEY": Keys.site_api} + self.cleaning = False + + async def _upload_log(self, log_data): + """ + Uploads the log data to the database via + an API endpoint for uploading logs. + + Returns a URL that can be used to view the log. + """ + + response = await self.bot.http_session.post( + URLs.site_clean_api, + headers=self.headers, + json={"log_data": log_data} + ) + + data = await response.json() + log_id = data["log_id"] + + return f"{URLs.site_clean_logs}/{log_id}" + + async def _clean_messages(self, amount, channel, bots_only: bool=False, user: User=None): + """ + A helper function that does the actual message cleaning. + + :param bots_only: Set this to True if you only want to delete bot messages. + :param user: Specify a user and it will only delete messages by this user. + :return: Returns an embed + """ + + # Is this an acceptable amount of messages to clean? + if amount > Clean.message_limit: + embed = Embed( + color=Colour.red(), + title=random.choice(NEGATIVE_REPLIES), + description=f"You cannot clean more than {Clean.message_limit} messages." + ) + return embed + + # Are we already performing a clean? + if self.cleaning: + embed = Embed( + color=Colour.red(), + title=random.choice(NEGATIVE_REPLIES), + description="Multiple simultaneous cleaning processes is not allowed." + ) + return embed + + # Skip the first message, as that will be the invocation + history = channel.history(limit=amount) + await history.next() + + message_log = [] + + async for message in history: + + delete_condition = ( + bots_only and message.author.bot # Delete bot messages + or user and message.author == user # Delete user messages + or not bots_only and not user # Delete all messages + ) + + if delete_condition: + await message.delete() + content = message.content or message.embeds[0].description + author = f"{message.author.name}#{message.author.discriminator}" + message_log.append({ + "content": content, + "author": author, + "timestamp": message.created_at.strftime("%D %H:%M") + }) + + if message_log: + # Reverse the list to restore chronological order + message_log = list(reversed(message_log)) + upload_log = await self._upload_log(message_log) + else: + upload_log = "Naw, nothing there!" + + embed = Embed( + description=upload_log + ) + + return embed + + @group(invoke_without_command=True, name="clean", hidden=True) + @with_role(Roles.moderator, Roles.admin, Roles.owner) + async def clean_group(self, ctx: Context): + """ + Commands for cleaning messages in channels + """ + + await ctx.invoke(self.bot.get_command("help"), "clean") + + @clean_group.command(aliases=["user"]) + @with_role(Roles.moderator, Roles.admin, Roles.owner) + async def clean_user(self, ctx: Context, user: User, amount: int = 10): + """ + Delete messages posted by the provided user, + and stop cleaning after traversing `amount` messages. + """ + + embed = await self._clean_messages(amount, ctx.channel, user=user) + + await ctx.send(embed=embed) + + @clean_group.command(aliases=["all"]) + @with_role(Roles.moderator, Roles.admin, Roles.owner) + async def clean_all(self, ctx: Context, amount: int = 10): + """ + Delete all messages, regardless of posted, + and stop cleaning after traversing `amount` messages. + """ + + embed = await self._clean_messages(amount, ctx.channel) + + await ctx.send(embed=embed) + + @clean_group.command(aliases=["bots"]) + @with_role(Roles.moderator, Roles.admin, Roles.owner) + async def clean_bots(self, ctx: Context, amount: int = 10): + """ + Delete all messages posted by a bot, + and stop cleaning after traversing `amount` messages. + """ + + embed = await self._clean_messages(amount, ctx.channel, bots_only=True) + + await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(Clean(bot)) + log.info("Cog loaded: Clean") diff --git a/bot/constants.py b/bot/constants.py index 7248cd36a..6a8eb6fe2 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -176,6 +176,13 @@ class Emojis(metaclass=YAMLGetter): white_chevron: str +class Clean(metaclass=YAMLGetter): + section = "bot" + subsection = "clean" + + message_limit: int + + class Channels(metaclass=YAMLGetter): section = "guild" subsection = "channels" @@ -259,6 +266,8 @@ class URLs(metaclass=YAMLGetter): omdb: str site: str site_facts_api: str + site_clean_api: str + site_clean_logs: str site_hiphopify_api: str site_idioms_api: str site_names_api: str diff --git a/config-default.yml b/config-default.yml index bd77e695e..ca15040e8 100644 --- a/config-default.yml +++ b/config-default.yml @@ -80,6 +80,8 @@ urls: omdb: 'http://omdbapi.com' site: 'pythondiscord.com' site_bigbrother_api: 'https://api.pythondiscord.com/bot/bigbrother' + site_clean_api: 'https://api.pythondiscord.com/bot/clean' + site_clean_logs: 'https://pythondiscord.com/bot/clean_logs' site_docs_api: 'https://api.pythondiscord.com/bot/docs' site_facts_api: 'https://api.pythondiscord.com/bot/snake_facts' site_hiphopify_api: 'https://api.pythondiscord.com/bot/hiphopify' |