aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar SebastiaanZ <[email protected]>2019-06-27 22:09:34 +0200
committerGravatar SebastiaanZ <[email protected]>2019-06-27 22:09:34 +0200
commit725656f471715fe96c92fac3b0155213f17029c1 (patch)
treeaf100655ac12684bf4337b750d59447eeb1f30bb
parentTruncating long names that misalign logs + adding 3 chars to account for watc... (diff)
Removing the old talentpool/bigbrother files + changing the extension loader
-rw-r--r--bot/__main__.py2
-rw-r--r--bot/cogs/bigbrother.py258
-rw-r--r--bot/cogs/nominations.py120
3 files changed, 1 insertions, 379 deletions
diff --git a/bot/__main__.py b/bot/__main__.py
index 8afec2718..44d4d9c02 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -38,7 +38,6 @@ bot.load_extension("bot.cogs.modlog")
# Commands, etc
bot.load_extension("bot.cogs.antispam")
-bot.load_extension("bot.cogs.bigbrother")
bot.load_extension("bot.cogs.bot")
bot.load_extension("bot.cogs.clean")
bot.load_extension("bot.cogs.cogs")
@@ -69,6 +68,7 @@ bot.load_extension("bot.cogs.sync")
bot.load_extension("bot.cogs.tags")
bot.load_extension("bot.cogs.token_remover")
bot.load_extension("bot.cogs.utils")
+bot.load_extension("bot.cogs.watchchannels")
bot.load_extension("bot.cogs.wolfram")
bot.run(BotConfig.token)
diff --git a/bot/cogs/bigbrother.py b/bot/cogs/bigbrother.py
deleted file mode 100644
index df7a0b576..000000000
--- a/bot/cogs/bigbrother.py
+++ /dev/null
@@ -1,258 +0,0 @@
-import asyncio
-import logging
-import re
-from collections import defaultdict, deque
-from typing import List, Union
-
-from discord import Color, Embed, Guild, Member, Message, User
-from discord.ext.commands import Bot, Context, group
-
-from bot.constants import (
- BigBrother as BigBrotherConfig, Channels, Emojis, Guild as GuildConfig, Roles
-)
-from bot.decorators import with_role
-from bot.pagination import LinePaginator
-from bot.utils import messages
-from bot.utils.moderation import post_infraction
-
-log = logging.getLogger(__name__)
-
-URL_RE = re.compile(r"(https?://[^\s]+)")
-
-
-class BigBrother:
- """User monitoring to assist with moderation."""
-
- def __init__(self, bot: Bot):
- self.bot = bot
- self.watched_users = set() # { user_id }
- self.channel_queues = defaultdict(lambda: defaultdict(deque)) # { user_id: { channel_id: queue(messages) }
- self.last_log = [None, None, 0] # [user_id, channel_id, message_count]
- self.consuming = False
-
- def update_cache(self, api_response: List[dict]):
- """
- Updates the internal cache of watched users from the given `api_response`.
- This function will only add (or update) existing keys, it will not delete
- keys that were not present in the API response.
- A user is only added if the bot can find a channel
- with the given `channel_id` in its channel cache.
- """
-
- for entry in api_response:
- user_id = entry['user']
- self.watched_users.add(user_id)
-
- async def on_ready(self):
- """Retrieves watched users from the API."""
-
- self.channel = self.bot.get_channel(Channels.big_brother_logs)
- if self.channel is None:
- log.error("Cannot find Big Brother channel. Cannot watch users.")
- else:
- data = await self.bot.api_client.get(
- 'bot/infractions',
- params={
- 'active': 'true',
- 'type': 'watch'
- }
- )
- self.update_cache(data)
-
- async def on_member_ban(self, guild: Guild, user: Union[User, Member]):
- if guild.id == GuildConfig.id and user.id in self.watched_users:
- [active_watch] = await self.bot.api_client.get(
- 'bot/infractions',
- params={
- 'active': 'true',
- 'type': 'watch',
- 'user__id': str(user.id)
- }
- )
- await self.bot.api_client.put(
- 'bot/infractions/' + str(active_watch['id']),
- json={'active': False}
- )
- self.watched_users.remove(user.id)
- del self.channel_queues[user.id]
- await self.channel.send(
- f"{Emojis.bb_message}:hammer: {user} got banned, so "
- f"`BigBrother` will no longer relay their messages."
- )
-
- async def on_message(self, msg: Message):
- """Queues up messages sent by watched users."""
-
- if msg.author.id in self.watched_users:
- if not self.consuming:
- self.bot.loop.create_task(self.consume_messages())
-
- log.trace(f"Received message: {msg.content} ({len(msg.attachments)} attachments)")
- self.channel_queues[msg.author.id][msg.channel.id].append(msg)
-
- async def consume_messages(self):
- """Consumes the message queues to log watched users' messages."""
-
- if not self.consuming:
- self.consuming = True
- log.trace("Sleeping before consuming...")
- await asyncio.sleep(BigBrotherConfig.log_delay)
-
- log.trace("Begin consuming messages.")
- channel_queues = self.channel_queues.copy()
- self.channel_queues.clear()
- for _, queues in channel_queues.items():
- for queue in queues.values():
- while queue:
- msg = queue.popleft()
- log.trace(f"Consuming message: {msg.clean_content} ({len(msg.attachments)} attachments)")
-
- self.last_log[2] += 1 # Increment message count.
- await self.send_header(msg)
- await self.log_message(msg)
-
- if self.channel_queues:
- log.trace("Queue not empty; continue consumption.")
- self.bot.loop.create_task(self.consume_messages())
- else:
- log.trace("Done consuming messages.")
- self.consuming = False
-
- async def send_header(self, message: Message):
- """
- Sends a log message header to the given channel.
-
- A header is only sent if the user or channel are different than the previous, or if the configured message
- limit for a single header has been exceeded.
-
- :param message: the first message in the queue
- """
-
- last_user, last_channel, msg_count = self.last_log
- limit = BigBrotherConfig.header_message_limit
-
- # Send header if user/channel are different or if message limit exceeded.
- if message.author.id != last_user or message.channel.id != last_channel or msg_count > limit:
- self.last_log = [message.author.id, message.channel.id, 0]
-
- embed = Embed(description=f"{message.author.mention} in [#{message.channel.name}]({message.jump_url})")
- embed.set_author(name=message.author.nick or message.author.name, icon_url=message.author.avatar_url)
- await self.channel.send(embed=embed)
-
- async def log_message(self, message: Message):
- """
- Logs a watched user's message in the given channel.
-
- Attachments are also sent. All non-image or non-video URLs are put in inline code blocks to prevent preview
- embeds from being automatically generated.
-
- :param message: the message to log
- """
-
- content = message.clean_content
- if content:
- # Put all non-media URLs in inline code blocks.
- media_urls = {embed.url for embed in message.embeds if embed.type in ("image", "video")}
- for url in URL_RE.findall(content):
- if url not in media_urls:
- content = content.replace(url, f"`{url}`")
-
- await self.channel.send(content)
-
- await messages.send_attachments(message, self.channel)
-
- @group(name='bigbrother', aliases=('bb',), invoke_without_command=True)
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def bigbrother_group(self, ctx: Context):
- """Monitor users, NSA-style."""
-
- await ctx.invoke(self.bot.get_command("help"), "bigbrother")
-
- @bigbrother_group.command(name='watched', aliases=('all',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def watched_command(self, ctx: Context, from_cache: bool = True):
- """
- Shows all users that are currently monitored and in which channel.
- By default, the users are returned from the cache.
- If this is not desired, `from_cache` can be given as a falsy value, e.g. e.g. 'no'.
- """
-
- if from_cache:
- lines = tuple(f"• <@{user_id}>" for user_id in self.watched_users)
- await LinePaginator.paginate(
- lines or ("There's nothing here yet.",),
- ctx,
- Embed(title="Watched users (cached)", color=Color.blue()),
- empty=False
- )
-
- else:
- active_watches = await self.bot.api_client.get(
- 'bot/infractions',
- params={
- 'active': 'true',
- 'type': 'watch'
- }
- )
- self.update_cache(active_watches)
- lines = tuple(
- f"• <@{entry['user']}>: {entry['reason'] or '*no reason provided*'}"
- for entry in active_watches
- )
-
- await LinePaginator.paginate(
- lines or ("There's nothing here yet.",),
- ctx,
- Embed(title="Watched users", color=Color.blue()),
- empty=False
- )
-
- @bigbrother_group.command(name='watch', aliases=('w',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def watch_command(self, ctx: Context, user: User, *, reason: str):
- """
- Relay messages sent by the given `user` to the `#big-brother-logs` channel
-
- A `reason` for watching is required, which is added for the user to be watched as a
- note (aka: shadow warning)
- """
-
- if user.id in self.watched_users:
- return await ctx.send(":x: That user is already watched.")
-
- await post_infraction(
- ctx, user, type='watch', reason=reason, hidden=True
- )
- self.watched_users.add(user.id)
- await ctx.send(f":ok_hand: will now relay messages sent by {user}")
-
- @bigbrother_group.command(name='unwatch', aliases=('uw',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def unwatch_command(self, ctx: Context, user: User):
- """Stop relaying messages by the given `user`."""
-
- active_watches = await self.bot.api_client.get(
- 'bot/infractions',
- params={
- 'active': 'true',
- 'type': 'watch',
- 'user__id': str(user.id)
- }
- )
- if active_watches:
- [infraction] = active_watches
- await self.bot.api_client.patch(
- 'bot/infractions/' + str(infraction['id']),
- json={'active': False}
- )
- await ctx.send(f":ok_hand: will no longer relay messages sent by {user}")
- self.watched_users.remove(user.id)
- if user.id in self.channel_queues:
- del self.channel_queues[user.id]
- else:
- await ctx.send(":x: that user is currently not being watched")
-
-
-def setup(bot: Bot):
- bot.add_cog(BigBrother(bot))
- log.info("Cog loaded: BigBrother")
diff --git a/bot/cogs/nominations.py b/bot/cogs/nominations.py
deleted file mode 100644
index 93ee0d885..000000000
--- a/bot/cogs/nominations.py
+++ /dev/null
@@ -1,120 +0,0 @@
-import logging
-
-from discord import Color, Embed, User
-from discord.ext.commands import Context, group
-
-from bot.cogs.bigbrother import BigBrother, Roles
-from bot.constants import Channels
-from bot.decorators import with_role
-from bot.pagination import LinePaginator
-
-
-log = logging.getLogger(__name__)
-
-
-class Nominations(BigBrother):
- """Monitor potential helpers, NSA-style."""
-
- async def on_ready(self):
- """Retrieve nominees from the API."""
-
- self.channel = self.bot.get_channel(Channels.talent_pool)
- if self.channel is None:
- log.error("Cannot find talent pool channel. Cannot watch nominees.")
- else:
- nominations = await self.bot.api_client.get(
- 'bot/nominations',
- params={'active': 'true'}
- )
- self.update_cache(nominations)
-
- async def on_member_ban(self, *_):
- pass
-
- @group(name='nominations', aliases=('n',), invoke_without_command=True)
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def bigbrother_group(self, ctx: Context):
- """Nominate helpers, NSA-style."""
-
- await ctx.invoke(self.bot.get_command("help"), "nominations")
-
- @bigbrother_group.command(name='nominated', aliases=('nominees', 'all'))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def watched_command(self, ctx: Context, from_cache: bool = True):
- if from_cache:
- lines = tuple(f"• <@{user_id}>" for user_id in self.watched_users)
-
- else:
- active_nominations = await self.bot.api_client.get(
- 'bot/nominations',
- params={'active': 'true'}
- )
- self.update_cache(active_nominations)
- lines = tuple(
- f"• <@{entry['user']}>: {entry['reason'] or '*no reason provided*'}"
- for entry in active_nominations
- )
-
- await LinePaginator.paginate(
- lines or ("There's nothing here yet.",),
- ctx,
- Embed(
- title="Nominated users" + " (cached)" * from_cache,
- color=Color.blue()
- ),
- empty=False
- )
-
- @bigbrother_group.command(name='nominate', aliases=('n',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def watch_command(self, ctx: Context, user: User, *, reason: str):
- """Talent pool the given `user`."""
-
- active_nominations = await self.bot.api_client.get(
- 'bot/nominations/' + str(user.id),
- )
- if active_nominations:
- active_nominations = await self.bot.api_client.put(
- 'bot/nominations/' + str(user.id),
- json={'active': True}
- )
- await ctx.send(":ok_hand: user's watch was updated")
-
- else:
- active_nominations = await self.bot.api_client.post(
- 'bot/nominations/' + str(user.id),
- json={
- 'active': True,
- 'author': ctx.author.id,
- 'reason': reason,
- }
- )
- self.watched_users.add(user.id)
- await ctx.send(":ok_hand: user added to talent pool")
-
- @bigbrother_group.command(name='unnominate', aliases=('un',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
- async def unwatch_command(self, ctx: Context, user: User):
- """Stop talent pooling the given `user`."""
-
- nomination = await self.bot.api_client.get(
- 'bot/nominations/' + str(user.id)
- )
-
- if not nomination['active']:
- await ctx.send(":x: the nomination is already inactive")
-
- else:
- await self.bot.api_client.put(
- 'bot/nominations/' + str(user.id),
- json={'active': False}
- )
- self.watched_users.remove(user.id)
- if user.id in self.channel_queues:
- del self.channel_queues[user.id]
- await ctx.send(f":ok_hand: {user} is no longer part of the talent pool")
-
-
-def setup(bot):
- bot.add_cog(Nominations(bot))
- log.info("Cog loaded: Nominations")