aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2018-07-21 02:46:12 +0200
committerGravatar Leon Sandøy <[email protected]>2018-07-21 02:46:12 +0200
commit50548104768b500b12ef5773d3654565b3eb84d1 (patch)
tree949ebf431b44d44358e5f5e4505c94be2a386132
parentAdding 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__.py1
-rw-r--r--bot/cogs/clean.py152
-rw-r--r--bot/constants.py9
-rw-r--r--config-default.yml2
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'