aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar SebastiaanZ <[email protected]>2019-07-03 16:31:05 +0200
committerGravatar SebastiaanZ <[email protected]>2019-07-03 16:31:05 +0200
commitd8fc80cefa272901e27e54564298596ab7ce4514 (patch)
tree5e2bded310eb605796c0df1b832c3d98987b432e
parentApplying changes requested in the reviews. (diff)
Applied the following changes requested by reviews:
- Bot responses are now plain messages instead of embeds; - The message history in the WatchChannel cog is now stored using a new dataclass, MessageHistory; - Removed the truncation option from the modified name field in logging; - bigbrother now provides user feedback when watching fails due to failing cache update; - Changed the lay-out of the mod_log alert and set ping_everyone to True; - Changed the function signature of `post_infraction` utility function to the one-parameter-per-line style; - Moved the declaration of File within bot/utils/messages.py to before the if/else to make things DRY.
-rw-r--r--bot/__init__.py2
-rw-r--r--bot/cogs/watchchannels/bigbrother.py35
-rw-r--r--bot/cogs/watchchannels/talentpool.py64
-rw-r--r--bot/cogs/watchchannels/watchchannel.py25
-rw-r--r--bot/utils/messages.py6
-rw-r--r--bot/utils/moderation.py9
6 files changed, 50 insertions, 91 deletions
diff --git a/bot/__init__.py b/bot/__init__.py
index fecd7ceb3..b6919a489 100644
--- a/bot/__init__.py
+++ b/bot/__init__.py
@@ -55,7 +55,7 @@ else:
logging.basicConfig(
- format="%(asctime)s pd.beardfist.com Bot: | %(name)33.33s | %(levelname)8s | %(message)s",
+ format="%(asctime)s pd.beardfist.com Bot: | %(name)33s | %(levelname)8s | %(message)s",
datefmt="%b %d %H:%M:%S",
level=logging.TRACE if DEBUG_MODE else logging.INFO,
handlers=logging_handlers
diff --git a/bot/cogs/watchchannels/bigbrother.py b/bot/cogs/watchchannels/bigbrother.py
index dc5e76f55..ff26794f7 100644
--- a/bot/cogs/watchchannels/bigbrother.py
+++ b/bot/cogs/watchchannels/bigbrother.py
@@ -53,36 +53,25 @@ class BigBrother(WatchChannel):
in the header when relaying messages of this user to the watchchannel.
"""
if user.bot:
- e = Embed(
- description=f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.")
return
if not await self.fetch_user_cache():
- log.error("Failed to update user cache; can't watch user {user}")
+
+ await ctx.send(f":x: Updating the user cache failed, can't watch user {user}")
return
if user.id in self.watched_users:
- e = Embed(
- description=":x: The specified user is already being watched.",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(":x: The specified user is already being watched.")
return
response = await post_infraction(
ctx, user, type='watch', reason=reason, hidden=True
)
+
if response is not None:
self.watched_users[user.id] = response
- e = Embed(
- description=f":white_check_mark: Messages sent by {user} will now be relayed to BigBrother.",
- color=Color.green()
- )
- await ctx.send(embed=e)
- return
+ await ctx.send(f":white_check_mark: Messages sent by {user} will now be relayed to BigBrother.")
@bigbrother_group.command(name='unwatch', aliases=('uw',))
@with_role(Roles.owner, Roles.admin, Roles.moderator)
@@ -105,16 +94,8 @@ class BigBrother(WatchChannel):
await post_infraction(ctx, user, type='watch', reason=f"Unwatched: {reason}", hidden=True, active=False)
- e = Embed(
- description=f":white_check_mark: Messages sent by {user} will no longer be relayed.",
- color=Color.green()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":white_check_mark: Messages sent by {user} will no longer be relayed.")
self._remove_user(user.id)
else:
- e = Embed(
- description=":x: The specified user is currently not being watched.",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(":x: The specified user is currently not being watched.")
diff --git a/bot/cogs/watchchannels/talentpool.py b/bot/cogs/watchchannels/talentpool.py
index 5e515fe2e..45b695e55 100644
--- a/bot/cogs/watchchannels/talentpool.py
+++ b/bot/cogs/watchchannels/talentpool.py
@@ -57,36 +57,19 @@ class TalentPool(WatchChannel):
in the header when relaying messages of this user to the watchchannel.
"""
if user.bot:
- e = Embed(
- description=f":x: **I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.")
return
if isinstance(user, Member) and any(role.id in STAFF_ROLES for role in user.roles):
- e = Embed(
- description=f":x: **Nominating staff members, eh? You cheeky bastard.**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":x: Nominating staff members, eh? Here's a cookie :cookie:")
return
if not await self.fetch_user_cache():
- log.error(f"Failed to update user cache; can't watch user {user}")
- e = Embed(
- description=f":x: **Failed to update the user cache; can't add {user}**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":x: Failed to update the user cache; can't add {user}")
return
if user.id in self.watched_users:
- e = Embed(
- description=":x: **The specified user is already in the TalentPool**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(":x: The specified user is already being watched in the TalentPool")
return
# Manual request with `raise_for_status` as False because we want the actual response
@@ -105,7 +88,7 @@ class TalentPool(WatchChannel):
if resp.status == 400 and response_data.get('user', False):
e = Embed(
- description=":x: **The specified user can't be found in the database tables**",
+ description=":x: The specified user can't be found in the database tables",
color=Color.red()
)
await ctx.send(embed=e)
@@ -114,11 +97,7 @@ class TalentPool(WatchChannel):
resp.raise_for_status()
self.watched_users[user.id] = response_data
- e = Embed(
- description=f":white_check_mark: **Messages sent by {user} will now be relayed to TalentPool**",
- color=Color.green()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":white_check_mark: Messages sent by {user} will now be relayed to TalentPool")
@nomination_group.command(name='history', aliases=('info', 'search'))
@with_role(Roles.owner, Roles.admin, Roles.moderator)
@@ -132,11 +111,7 @@ class TalentPool(WatchChannel):
}
)
if not result:
- e = Embed(
- description=":warning: **This user has never been nominated**",
- color=Color.blue()
- )
- await ctx.send(embed=e)
+ await ctx.send(":warning: This user has never been nominated")
return
embed = Embed(
@@ -170,11 +145,7 @@ class TalentPool(WatchChannel):
)
if not active_nomination:
- e = Embed(
- description=":x: **The specified user does not have an active Nomination**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(":x: The specified user does not have an active Nomination")
return
[nomination] = active_nomination
@@ -182,11 +153,7 @@ class TalentPool(WatchChannel):
f"{self.api_endpoint}/{nomination['id']}",
json={'end_reason': reason}
)
- e = Embed(
- description=f":white_check_mark: **Messages sent by {user} will no longer be relayed**",
- color=Color.green()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":white_check_mark: Messages sent by {user} will no longer be relayed")
self._remove_user(user.id)
@nomination_group.group(name='edit', aliases=('e',), invoke_without_command=True)
@@ -210,11 +177,7 @@ class TalentPool(WatchChannel):
except ClientResponseError as e:
if e.status == 404:
self.log.trace(f"Nomination API 404: Can't nomination with id {nomination_id}")
- e = Embed(
- description=f":x: **Can't find a nomination with id `{nomination_id}`**",
- color=Color.red()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`")
return
else:
raise
@@ -222,16 +185,13 @@ class TalentPool(WatchChannel):
field = "reason" if nomination["active"] else "end_reason"
self.log.trace(f"Changing {field} for nomination with id {nomination_id} to {reason}")
+
await self.bot.api_client.patch(
f"{self.api_endpoint}/{nomination_id}",
json={field: reason}
)
- e = Embed(
- description=f":white_check_mark: **Updated the {field} of the nomination!**",
- color=Color.green()
- )
- await ctx.send(embed=e)
+ await ctx.send(f":white_check_mark: Updated the {field} of the nomination!")
def _nomination_to_string(self, nomination_object: dict) -> str:
"""Creates a string representation of a nomination."""
diff --git a/bot/cogs/watchchannels/watchchannel.py b/bot/cogs/watchchannels/watchchannel.py
index 8f0bc765d..16212e3b0 100644
--- a/bot/cogs/watchchannels/watchchannel.py
+++ b/bot/cogs/watchchannels/watchchannel.py
@@ -5,7 +5,8 @@ import re
import textwrap
from abc import ABC, abstractmethod
from collections import defaultdict, deque
-from typing import Optional
+from dataclasses import dataclass
+from typing import Iterator, Optional
import aiohttp
import discord
@@ -39,6 +40,16 @@ def proxy_user(user_id: str) -> Object:
return user
+@dataclass
+class MessageHistory:
+ last_author: Optional[int] = None
+ last_channel: Optional[int] = None
+ message_count: int = 0
+
+ def __iter__(self) -> Iterator:
+ return iter((self.last_author, self.last_channel, self.message_count))
+
+
class WatchChannel(ABC):
"""ABC that implements watch channel functionality to relay all messages of a user to a watch channel."""
@@ -52,7 +63,6 @@ class WatchChannel(ABC):
self.api_default_params = api_default_params # E.g., {'active': 'true', 'type': 'watch'}
self.log = logger # Logger of the child cog for a correct name in the logs
- # These attributes can be left as they are in the child class
self._consume_task = None
self.watched_users = defaultdict(dict)
self.message_queue = defaultdict(lambda: defaultdict(deque))
@@ -61,7 +71,7 @@ class WatchChannel(ABC):
self.retry_delay = 10
self.channel = None
self.webhook = None
- self.message_history = [None, None, 0]
+ self.message_history = MessageHistory()
self._start = self.bot.loop.create_task(self.start_watchchannel())
@@ -118,13 +128,14 @@ class WatchChannel(ABC):
TextChannel: {"**Failed to load**" if self.channel is None else "Loaded successfully"}
Webhook: {"**Failed to load**" if self.webhook is None else "Loaded successfully"}
- The Cog has been unloaded."""
+ The Cog has been unloaded.
+ """
)
await self.modlog.send_log_message(
title=f"Error: Failed to initialize the {self.__class__.__name__} watch channel",
text=message,
- ping_everyone=False,
+ ping_everyone=True,
icon_url=Icons.token_removed,
colour=Color.red()
)
@@ -221,7 +232,7 @@ class WatchChannel(ABC):
limit = BigBrotherConfig.header_message_limit
if msg.author.id != last_author or msg.channel.id != last_channel or count >= limit:
- self.message_history = [msg.author.id, msg.channel.id, 0]
+ self.message_history = MessageHistory(last_author=msg.author.id, last_channel=msg.channel.id)
await self.send_header(msg)
@@ -258,7 +269,7 @@ class WatchChannel(ABC):
exc_info=exc
)
- self.message_history[2] += 1
+ self.message_history.message_count += 1
async def send_header(self, msg) -> None:
"""Sends a header embed with information about the relayed messages to the watch channel"""
diff --git a/bot/utils/messages.py b/bot/utils/messages.py
index 5c9b5b4d7..94a8b36ed 100644
--- a/bot/utils/messages.py
+++ b/bot/utils/messages.py
@@ -97,11 +97,13 @@ async def send_attachments(message: Message, destination: Union[TextChannel, Web
if attachment.size <= MAX_SIZE - 512:
with BytesIO() as file:
await attachment.save(file)
+ attachment_file = File(file, filename=attachment.filename)
+
if isinstance(destination, TextChannel):
- await destination.send(file=File(file, filename=attachment.filename))
+ await destination.send(file=attachment_file)
else:
await destination.send(
- file=File(file, filename=attachment.filename),
+ file=attachment_file,
username=message.author.display_name,
avatar_url=message.author.avatar_url
)
diff --git a/bot/utils/moderation.py b/bot/utils/moderation.py
index e81186253..c1eb98dd6 100644
--- a/bot/utils/moderation.py
+++ b/bot/utils/moderation.py
@@ -14,8 +14,13 @@ HEADERS = {"X-API-KEY": Keys.site_api}
async def post_infraction(
- ctx: Context, user: Union[Member, Object, User], type: str, reason: str,
- expires_at: datetime = None, hidden: bool = False, active: bool = True
+ ctx: Context,
+ user: Union[Member, Object, User],
+ type: str,
+ reason: str,
+ expires_at: datetime = None,
+ hidden: bool = False,
+ active: bool = True,
):
payload = {