aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar SebastiaanZ <[email protected]>2019-06-28 19:20:06 +0200
committerGravatar SebastiaanZ <[email protected]>2019-06-28 19:20:06 +0200
commitc5d4505cc4f21d87d6177cb8208d4c64d85e1052 (patch)
tree961f4577aaf87da8a9ce966b0c6b89890393d86c
parentUpdating constants to include talent-pool (diff)
force child to set parameters via __init__; return value annotations; correcting spelling mistakes; + small fixes
-rw-r--r--bot/cogs/watchchannels/bigbrother.py21
-rw-r--r--bot/cogs/watchchannels/talentpool.py27
-rw-r--r--bot/cogs/watchchannels/watchchannel.py47
3 files changed, 46 insertions, 49 deletions
diff --git a/bot/cogs/watchchannels/bigbrother.py b/bot/cogs/watchchannels/bigbrother.py
index 55805cf87..6e894de1e 100644
--- a/bot/cogs/watchchannels/bigbrother.py
+++ b/bot/cogs/watchchannels/bigbrother.py
@@ -16,16 +16,15 @@ log = logging.getLogger(__name__)
class BigBrother(WatchChannel):
"""User monitoring to assist with moderation"""
- def __init__(self, bot):
- super().__init__(bot)
- self.log = log # to ensure logs created in the super() get the name of this file
-
- self.destination = Channels.big_brother_logs
- self.webhook_id = Webhooks.big_brother
- self.api_endpoint = 'bot/infractions'
- self.api_default_params = {
- 'active': 'true', 'type': 'watch', 'ordering': '-inserted_at'
- }
+ def __init__(self, bot) -> None:
+ super().__init__(
+ bot,
+ destination=Channels.big_brother_logs,
+ webhook_id=Webhooks.big_brother,
+ api_endpoint='bot/infractions',
+ api_default_params={'active': 'true', 'type': 'watch', 'ordering': '-inserted_at'},
+ logger=log
+ )
@group(name='bigbrother', aliases=('bb',), invoke_without_command=True)
@with_role(Roles.owner, Roles.admin, Roles.moderator)
@@ -77,7 +76,7 @@ class BigBrother(WatchChannel):
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**",
+ description=f":white_check_mark: **Messages sent by {user} will now be relayed to BigBrother**",
color=Color.green()
)
return await ctx.send(embed=e)
diff --git a/bot/cogs/watchchannels/talentpool.py b/bot/cogs/watchchannels/talentpool.py
index 773547bab..6773ddc89 100644
--- a/bot/cogs/watchchannels/talentpool.py
+++ b/bot/cogs/watchchannels/talentpool.py
@@ -18,14 +18,15 @@ STAFF_ROLES = Roles.owner, Roles.admin, Roles.moderator, Roles.helpers # <- I
class TalentPool(WatchChannel):
"""A TalentPool for helper nominees"""
- def __init__(self, bot):
- super().__init__(bot)
- self.log = log # to ensure logs created in the super() get the name of this file
-
- self.destination = Channels.big_brother_logs
- self.webhook_id = Webhooks.talent_pool
- self.api_endpoint = 'bot/nominations'
- self.api_default_params = {'active': 'true', 'ordering': '-inserted_at'}
+ def __init__(self, bot) -> None:
+ super().__init__(
+ bot,
+ destination=Channels.talent_pool,
+ webhook_id=Webhooks.talent_pool,
+ api_endpoint='bot/nominations',
+ api_default_params={'active': 'true', 'ordering': '-inserted_at'},
+ logger=log,
+ )
@group(name='talentpool', aliases=('tp', 'talent', 'nomination', 'n'), invoke_without_command=True)
@with_role(Roles.owner, Roles.admin, Roles.moderator)
@@ -83,7 +84,7 @@ class TalentPool(WatchChannel):
)
return await ctx.send(embed=e)
- # Manual request with `raise_for_status` as False becausse we want the actual response
+ # Manual request with `raise_for_status` as False because we want the actual response
session = self.bot.api_client.session
url = self.bot.api_client._url_for(self.api_endpoint)
kwargs = {
@@ -103,12 +104,12 @@ class TalentPool(WatchChannel):
color=Color.red()
)
return await ctx.send(embed=e)
- elif resp.status >= 400:
- resp.raise_for_status()
+
+ 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**",
+ description=f":white_check_mark: **Messages sent by {user} will now be relayed to TalentPool**",
color=Color.green()
)
return await ctx.send(embed=e)
@@ -223,7 +224,7 @@ class TalentPool(WatchChannel):
)
await ctx.send(embed=e)
- def _nomination_to_string(self, nomination_object):
+ def _nomination_to_string(self, nomination_object: dict) -> str:
"""Creates a string representation of a nomination"""
guild = self.bot.get_guild(Guild.id)
diff --git a/bot/cogs/watchchannels/watchchannel.py b/bot/cogs/watchchannels/watchchannel.py
index 5f9d8d1dd..566f7d52a 100644
--- a/bot/cogs/watchchannels/watchchannel.py
+++ b/bot/cogs/watchchannels/watchchannel.py
@@ -44,7 +44,7 @@ class WatchChannel(ABC):
"""
@abstractmethod
- def __init__(self, bot: Bot) -> None:
+ def __init__(self, bot: Bot, destination, webhook_id, api_endpoint, api_default_params, logger) -> None:
"""
abstractmethod for __init__ which should still be called with super().
@@ -54,11 +54,11 @@ class WatchChannel(ABC):
"""
self.bot = bot
- # These attributes need to be overwritten in the child class
- self.destination = None # Channels.big_brother_logs
- self.webhook_id = None # Webhooks.big_brother
- self.api_endpoint = None # 'bot/infractions'
- self.api_default_params = None # {'active': 'true', 'type': 'watch'}
+ self.destination = destination # E.g., Channels.big_brother_logs
+ self.webhook_id = webhook_id # E.g., Webhooks.big_brother
+ self.api_endpoint = api_endpoint # E.g., 'bot/infractions'
+ 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
@@ -99,6 +99,10 @@ class WatchChannel(ABC):
else:
self.log.error(f"Failed to start the {self.__class__.__name__} WatchChannel")
+ # Let's try again in a minute.
+ await asyncio.sleep(60)
+ self._start = self.bot.loop.create_task(self.start_watchchannel())
+
async def initialize_channel(self) -> bool:
"""
Checks if channel and webhook are set; if not, tries to initialize them.
@@ -160,7 +164,7 @@ class WatchChannel(ABC):
return True
- async def on_message(self, msg: Message):
+ async def on_message(self, msg: Message) -> None:
"""Queues up messages sent by watched users."""
if msg.author.id in self.watched_users:
if not self.consuming_messages:
@@ -169,11 +173,11 @@ class WatchChannel(ABC):
self.log.trace(f"Received message: {msg.content} ({len(msg.attachments)} attachments)")
self.message_queue[msg.author.id][msg.channel.id].append(msg)
- async def consume_messages(self, delay_consumption: bool = True):
+ async def consume_messages(self, delay_consumption: bool = True) -> None:
"""Consumes the message queues to log watched users' messages."""
if delay_consumption:
self.log.trace(f"Sleeping {BigBrotherConfig.log_delay} seconds before consuming message queue")
- await asyncio.sleep(1)
+ await asyncio.sleep(BigBrotherConfig.log_delay)
self.log.trace(f"{self.__class__.__name__} started consuming the message queue")
@@ -203,7 +207,7 @@ class WatchChannel(ABC):
async def webhook_send(
self, content: Optional[str] = None, username: Optional[str] = None,
avatar_url: Optional[str] = None, embed: Optional[Embed] = None,
- ):
+ ) -> None:
"""Sends a message to the webhook with the specified kwargs."""
try:
await self.webhook.send(content=content, username=username, avatar_url=avatar_url, embed=embed)
@@ -226,6 +230,7 @@ class WatchChannel(ABC):
cleaned_content = msg.clean_content
if cleaned_content:
+ # Put all non-media URLs in a codeblock to prevent embeds
media_urls = {embed.url for embed in msg.embeds if embed.type in ("image", "video")}
for url in URL_RE.findall(cleaned_content):
if url not in media_urls:
@@ -257,8 +262,8 @@ class WatchChannel(ABC):
self.message_history[2] += 1
- async def send_header(self, msg):
- """Sends an header embed to the WatchChannel"""
+ async def send_header(self, msg) -> None:
+ """Sends a header embed to the WatchChannel"""
user_id = msg.author.id
guild = self.bot.get_guild(GuildConfig.id)
@@ -266,11 +271,7 @@ class WatchChannel(ABC):
actor = actor.display_name if actor else self.watched_users[user_id]['actor']
inserted_at = self.watched_users[user_id]['inserted_at']
- date_time = datetime.datetime.strptime(
- inserted_at,
- "%Y-%m-%dT%H:%M:%S.%fZ"
- ).replace(tzinfo=None)
- time_delta = time_since(date_time, precision="minutes", max_units=1)
+ time_delta = self._get_time_delta(inserted_at)
reason = self.watched_users[user_id]['reason']
@@ -287,22 +288,21 @@ class WatchChannel(ABC):
avatar_url=msg.author.avatar_url
)
- async def list_watched_users(self, ctx: Context, update_cache: bool = False) -> None:
+ async def list_watched_users(self, ctx: Context, update_cache: bool = True) -> None:
"""
Gives an overview of the watched user list for this channel.
The optional kwarg `update_cache` specifies whether the cache should
be refreshed by polling the API.
"""
-
if update_cache:
if not await self.fetch_user_cache():
e = Embed(
- description=f":x: **Failed to update {self.__class__.__name__} user cache**",
+ description=f":x: **Failed to update {self.__class__.__name__} user cache, serving from cache**",
color=Color.red()
)
await ctx.send(embed=e)
- return
+ update_cache = False
lines = []
for user_id, user_data in self.watched_users.items():
@@ -323,7 +323,6 @@ class WatchChannel(ABC):
@staticmethod
def _get_time_delta(time_string: str) -> str:
"""Returns the time in human-readable time delta format"""
-
date_time = datetime.datetime.strptime(
time_string,
"%Y-%m-%dT%H:%M:%S.%fZ"
@@ -342,14 +341,12 @@ class WatchChannel(ABC):
def _remove_user(self, user_id: int) -> None:
"""Removes user from the WatchChannel"""
-
self.watched_users.pop(user_id, None)
self.message_queue.pop(user_id, None)
self.consumption_queue.pop(user_id, None)
- def cog_unload(self):
+ def cog_unload(self) -> None:
"""Takes care of unloading the cog and cancelling the consumption task."""
-
self.log.trace(f"Unloading {self.__class__._name__} cog")
if not self._consume_task.done():
self._consume_task.cancel()