From 78b00dc8f43d7cb25ce72bc97d6236ec9944cd1f Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:10:35 +0300 Subject: Remove WatchChannel parent of TalentPool and migrate first commands --- bot/exts/recruitment/talentpool/_cog.py | 80 +++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index b809cea17..09f2fecbd 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -1,6 +1,6 @@ import logging import textwrap -from collections import ChainMap +from collections import ChainMap, defaultdict from typing import Union from discord import Color, Embed, Member, User @@ -8,35 +8,48 @@ from discord.ext.commands import Cog, Context, group, has_any_role from bot.api import ResponseCodeError from bot.bot import Bot -from bot.constants import Channels, Guild, MODERATION_ROLES, STAFF_ROLES, Webhooks +from bot.constants import Guild, MODERATION_ROLES, STAFF_ROLES from bot.converters import FetchedMember -from bot.exts.moderation.watchchannels._watchchannel import WatchChannel from bot.exts.recruitment.talentpool._review import Reviewer from bot.pagination import LinePaginator from bot.utils import time +from bot.utils.time import get_time_delta REASON_MAX_CHARS = 1000 log = logging.getLogger(__name__) -class TalentPool(WatchChannel, Cog, name="Talentpool"): +class TalentPool(Cog, name="Talentpool"): """Relays messages of helper candidates to a watch channel to observe them.""" def __init__(self, bot: 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, - disable_header=True, - ) - + self.bot = bot self.reviewer = Reviewer(self.__class__.__name__, bot, self) self.bot.loop.create_task(self.reviewer.reschedule_reviews()) + # Stores talentpool users in cache + self.cache = defaultdict(dict) + + async def refresh_cache(self) -> bool: + """Updates TalentPool users cache.""" + try: + data = await self.bot.api_client.get( + 'bot/nominations', + params={'active': 'true', 'ordering': '-inserted_at'} + ) + except ResponseCodeError as err: + log.exception("Failed to fetch the watched users from the API", exc_info=err) + return False + + self.cache = defaultdict(dict) + + for entry in data: + user_id = entry.pop('user') + self.cache[user_id] = entry + + return True + @group(name='talentpool', aliases=('tp', 'talent', 'nomination', 'n'), invoke_without_command=True) @has_any_role(*MODERATION_ROLES) async def nomination_group(self, ctx: Context) -> None: @@ -78,26 +91,37 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): The optional kwarg `update_cache` specifies whether the cache should be refreshed by polling the API. """ - # TODO Once the watch channel is removed, this can be done in a smarter way, without splitting and overriding - # the list_watched_users function. - watched_data = await self.prepare_watched_users_data(ctx, oldest_first, update_cache) + successful_update = False + if update_cache: + if not (successful_update := await self.refresh_cache()): + await ctx.send(":warning: Unable to update cache. Data may be inaccurate.") - if update_cache and not watched_data["updated"]: - await ctx.send(f":x: Failed to update {self.__class__.__name__} user cache, serving from cache") + nominations = self.cache.items() + if oldest_first: + nominations = reversed(nominations) lines = [] - for user_id, line in watched_data["info"].items(): - if self.watched_users[user_id]['reviewed']: + + for user_id, user_data in nominations: + member = ctx.guild.get_member(user_id) + line = f"• `{user_id}`" + if member: + line += f" ({member.name}#{member.discriminator})" + inserted_at = user_data['inserted_at'] + line += f", added {get_time_delta(inserted_at)}" + if not member: # Cross off users who left the server. + line = f"~~{line}~~" + if user_data['reviewed']: line += " *(reviewed)*" elif user_id in self.reviewer: - line += " *(scheduled)*" + line += " *(scheduled)" lines.append(line) if not lines: lines = ("There's nothing here yet.",) embed = Embed( - title=watched_data["title"], + title=f"Talent Pool active nominations ({'updated' if update_cache and successful_update else 'cached'})", color=Color.blue() ) await LinePaginator.paginate(lines, ctx, embed, empty=False) @@ -130,8 +154,8 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): await ctx.send(":x: Nominating staff members, eh? Here's a cookie :cookie:") return - if not await self.fetch_user_cache(): - await ctx.send(f":x: Failed to update the user cache; can't add {user}") + if not await self.refresh_cache(): + await ctx.send(f":x: Failed to update the cache; can't add {user}") return if len(reason) > REASON_MAX_CHARS: @@ -140,7 +164,7 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): # 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) + url = self.bot.api_client._url_for('bot/nominations') kwargs = { 'json': { 'actor': ctx.author.id, @@ -162,13 +186,13 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): else: resp.raise_for_status() - self.watched_users[user.id] = response_data + self.cache[user.id] = response_data if user.id not in self.reviewer: self.reviewer.schedule_review(user.id) history = await self.bot.api_client.get( - self.api_endpoint, + 'bot/nominations', params={ "user__id": str(user.id), "active": "false", -- cgit v1.2.3 From dda3490a0a1a55bb3ccb16b82afc0dd131f335b5 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:19:51 +0300 Subject: Use more accurate command names and docstring for talent pool commands --- bot/exts/recruitment/talentpool/_cog.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 09f2fecbd..40fb90f11 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -56,25 +56,25 @@ class TalentPool(Cog, name="Talentpool"): """Highlights the activity of helper nominees by relaying their messages to the talent pool channel.""" await ctx.send_help(ctx.command) - @nomination_group.command(name='watched', aliases=('all', 'list'), root_aliases=("nominees",)) + @nomination_group.command(name='list', aliases=('all', 'watched'), root_aliases=("nominees",)) @has_any_role(*MODERATION_ROLES) - async def watched_command( + async def list_command( self, ctx: Context, oldest_first: bool = False, update_cache: bool = True ) -> None: """ - Shows the users that are currently being monitored in the talent pool. + Shows the users that are currently in the talent pool. The optional kwarg `oldest_first` can be used to order the list by oldest nomination. The optional kwarg `update_cache` can be used to update the user cache using the API before listing the users. """ - await self.list_watched_users(ctx, oldest_first=oldest_first, update_cache=update_cache) + await self.list_users(ctx, oldest_first=oldest_first, update_cache=update_cache) - async def list_watched_users( + async def list_users( self, ctx: Context, oldest_first: bool = False, @@ -130,21 +130,20 @@ class TalentPool(Cog, name="Talentpool"): @has_any_role(*MODERATION_ROLES) async def oldest_command(self, ctx: Context, update_cache: bool = True) -> None: """ - Shows talent pool monitored users ordered by oldest nomination. + Shows talent pool users ordered by oldest nomination. The optional kwarg `update_cache` can be used to update the user cache using the API before listing the users. """ - await ctx.invoke(self.watched_command, oldest_first=True, update_cache=update_cache) + await ctx.invoke(self.list_command, oldest_first=True, update_cache=update_cache) - @nomination_group.command(name='watch', aliases=('w', 'add', 'a'), root_aliases=("nominate",)) + @nomination_group.command(name='add', aliases=('w', 'a', 'watch'), root_aliases=("nominate",)) @has_any_role(*STAFF_ROLES) - async def watch_command(self, ctx: Context, user: FetchedMember, *, reason: str = '') -> None: + async def add_command(self, ctx: Context, user: FetchedMember, *, reason: str = '') -> None: """ - Relay messages sent by the given `user` to the `#talent-pool` channel. + Adds user nomination (or nomination entry) to Talent Pool. - A `reason` for adding the user to the talent pool is optional. - If given, it will be displayed in the header when relaying messages of this user to the channel. + If user already have nomination, then entry associated with existing nomination will be created. """ if user.bot: await ctx.send(f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.") @@ -235,9 +234,9 @@ class TalentPool(Cog, name="Talentpool"): max_size=1000 ) - @nomination_group.command(name='unwatch', aliases=('end', ), root_aliases=("unnominate",)) + @nomination_group.command(name='end', aliases=('unwatch',), root_aliases=("unnominate",)) @has_any_role(*MODERATION_ROLES) - async def unwatch_command(self, ctx: Context, user: FetchedMember, *, reason: str) -> None: + async def end_command(self, ctx: Context, user: FetchedMember, *, reason: str) -> None: """ Ends the active nomination of the specified user with the given reason. -- cgit v1.2.3 From f144bace9243659887cbb125ea915f809736fc97 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:22:13 +0300 Subject: Migrate nominations history command to non-watchchannel system --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 40fb90f11..ee5dc5dae 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -210,7 +210,7 @@ class TalentPool(Cog, name="Talentpool"): async def history_command(self, ctx: Context, user: FetchedMember) -> None: """Shows the specified user's nomination history.""" result = await self.bot.api_client.get( - self.api_endpoint, + 'bot/nominations', params={ 'user__id': str(user.id), 'ordering': "-active,-inserted_at" -- cgit v1.2.3 From 807a27ec112684a2a2b8cfd2b470ab8378f0da98 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:30:46 +0300 Subject: Migrate Talent Pool Reviewer class to non-watchchannel Talent Pool --- bot/exts/recruitment/talentpool/_review.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_review.py b/bot/exts/recruitment/talentpool/_review.py index fb3461238..bc2878451 100644 --- a/bot/exts/recruitment/talentpool/_review.py +++ b/bot/exts/recruitment/talentpool/_review.py @@ -47,9 +47,9 @@ class Reviewer: log.trace("Rescheduling reviews") await self.bot.wait_until_guild_available() # TODO Once the watch channel is removed, this can be done in a smarter way, e.g create a sync function. - await self._pool.fetch_user_cache() + await self._pool.refresh_cache() - for user_id, user_data in self._pool.watched_users.items(): + for user_id, user_data in self._pool.cache.items(): if not user_data["reviewed"]: self.schedule_review(user_id) @@ -57,7 +57,7 @@ class Reviewer: """Schedules a single user for review.""" log.trace(f"Scheduling review of user with ID {user_id}") - user_data = self._pool.watched_users[user_id] + user_data = self._pool.cache[user_id] inserted_at = isoparse(user_data['inserted_at']).replace(tzinfo=None) review_at = inserted_at + timedelta(days=MAX_DAYS_IN_POOL) @@ -69,7 +69,7 @@ class Reviewer: """Format a generic review of a user and post it to the nomination voting channel.""" log.trace(f"Posting the review of {user_id}") - nomination = self._pool.watched_users[user_id] + nomination = self._pool.cache[user_id] if not nomination: log.trace(f"There doesn't appear to be an active nomination for {user_id}") return @@ -79,7 +79,7 @@ class Reviewer: member = guild.get_member(user_id) if update_database: - await self.bot.api_client.patch(f"{self._pool.api_endpoint}/{nomination['id']}", json={"reviewed": True}) + await self.bot.api_client.patch(f"bot/nominations/{nomination['id']}", json={"reviewed": True}) if not member: await channel.send( @@ -228,7 +228,7 @@ class Reviewer: """ log.trace(f"Fetching the nomination history data for {member.id}'s review") history = await self.bot.api_client.get( - self._pool.api_endpoint, + "bot/nominations", params={ "user__id": str(member.id), "active": "false", @@ -286,18 +286,18 @@ class Reviewer: Returns True if the user was successfully marked as reviewed, False otherwise. """ log.trace(f"Updating user {user_id} as reviewed") - await self._pool.fetch_user_cache() - if user_id not in self._pool.watched_users: + await self._pool.refresh_cache() + if user_id not in self._pool.cache: log.trace(f"Can't find a nominated user with id {user_id}") await ctx.send(f"❌ Can't find a currently nominated user with id `{user_id}`") return False - nomination = self._pool.watched_users[user_id] + nomination = self._pool.cache[user_id] if nomination["reviewed"]: await ctx.send("❌ This nomination was already reviewed, but here's a cookie 🍪") return False - await self.bot.api_client.patch(f"{self._pool.api_endpoint}/{nomination['id']}", json={"reviewed": True}) + await self.bot.api_client.patch(f"bot/nominations/{nomination['id']}", json={"reviewed": True}) if user_id in self._review_scheduler: self._review_scheduler.cancel(user_id) -- cgit v1.2.3 From 2d4764041da02ccee64a93c02c0dd392c31e80c4 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:31:24 +0300 Subject: Migrate unnominate command to non-watchchannel --- bot/exts/recruitment/talentpool/_cog.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index ee5dc5dae..1ad40812a 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -30,13 +30,14 @@ class TalentPool(Cog, name="Talentpool"): # Stores talentpool users in cache self.cache = defaultdict(dict) + self.api_default_params = {'active': 'true', 'ordering': '-inserted_at'} async def refresh_cache(self) -> bool: """Updates TalentPool users cache.""" try: data = await self.bot.api_client.get( 'bot/nominations', - params={'active': 'true', 'ordering': '-inserted_at'} + params=self.api_default_params ) except ResponseCodeError as err: log.exception("Failed to fetch the watched users from the API", exc_info=err) @@ -243,11 +244,11 @@ class TalentPool(Cog, name="Talentpool"): Providing a `reason` is required. """ if len(reason) > REASON_MAX_CHARS: - await ctx.send(f":x: Maxiumum allowed characters for the end reason is {REASON_MAX_CHARS}.") + await ctx.send(f":x: Maximum allowed characters for the end reason is {REASON_MAX_CHARS}.") return if await self.unwatch(user.id, reason): - await ctx.send(f":white_check_mark: Messages sent by {user} will no longer be relayed") + await ctx.send(f":white_check_mark: Successfully un-nominated {user}") else: await ctx.send(":x: The specified user does not have an active nomination") @@ -349,7 +350,7 @@ class TalentPool(Cog, name="Talentpool"): async def unwatch(self, user_id: int, reason: str) -> bool: """End the active nomination of a user with the given reason and return True on success.""" active_nomination = await self.bot.api_client.get( - self.api_endpoint, + 'bot/nominations', params=ChainMap( {"user__id": str(user_id)}, self.api_default_params, @@ -364,10 +365,9 @@ class TalentPool(Cog, name="Talentpool"): nomination = active_nomination[0] await self.bot.api_client.patch( - f"{self.api_endpoint}/{nomination['id']}", + f"bot/nominations/{nomination['id']}", json={'end_reason': reason, 'active': False} ) - self._remove_user(user_id) self.reviewer.cancel(user_id) -- cgit v1.2.3 From ae3c91082f1a456d37c8ce72c65509315e4a2137 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:32:58 +0300 Subject: Add missing asterisk to nominees list --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 1ad40812a..4ef3af3d1 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -115,7 +115,7 @@ class TalentPool(Cog, name="Talentpool"): if user_data['reviewed']: line += " *(reviewed)*" elif user_id in self.reviewer: - line += " *(scheduled)" + line += " *(scheduled)*" lines.append(line) if not lines: -- cgit v1.2.3 From 4716b8eba3d25f21e277ee20cff2741cece2e0ed Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 09:52:53 +0300 Subject: Migrate nomination reasons editing commands --- bot/exts/recruitment/talentpool/_cog.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 4ef3af3d1..7824d22d7 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -267,10 +267,10 @@ class TalentPool(Cog, name="Talentpool"): return try: - nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{nomination_id}") + nomination = await self.bot.api_client.get(f"bot/nominations/{nomination_id}") except ResponseCodeError as e: if e.response.status == 404: - self.log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") + log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`") return else: @@ -284,13 +284,13 @@ class TalentPool(Cog, name="Talentpool"): await ctx.send(f":x: {actor} doesn't have an entry in this nomination.") return - self.log.trace(f"Changing reason for nomination with id {nomination_id} of actor {actor} to {repr(reason)}") + log.trace(f"Changing reason for nomination with id {nomination_id} of actor {actor} to {repr(reason)}") await self.bot.api_client.patch( - f"{self.api_endpoint}/{nomination_id}", + f"bot/nominations/{nomination_id}", json={"actor": actor.id, "reason": reason} ) - await self.fetch_user_cache() # Update cache + await self.refresh_cache() # Update cache await ctx.send(":white_check_mark: Successfully updated nomination reason.") @nomination_edit_group.command(name='end_reason') @@ -302,10 +302,10 @@ class TalentPool(Cog, name="Talentpool"): return try: - nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{nomination_id}") + nomination = await self.bot.api_client.get(f"bot/nominations/{nomination_id}") except ResponseCodeError as e: if e.response.status == 404: - self.log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") + log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`") return else: @@ -315,13 +315,13 @@ class TalentPool(Cog, name="Talentpool"): await ctx.send(":x: Can't edit the end reason of an active nomination.") return - self.log.trace(f"Changing end reason for nomination with id {nomination_id} to {repr(reason)}") + log.trace(f"Changing end reason for nomination with id {nomination_id} to {repr(reason)}") await self.bot.api_client.patch( - f"{self.api_endpoint}/{nomination_id}", + f"bot/nominations/{nomination_id}", json={"end_reason": reason} ) - await self.fetch_user_cache() # Update cache. + await self.refresh_cache() # Update cache. await ctx.send(":white_check_mark: Updated the end reason of the nomination!") @nomination_group.command(aliases=('mr',)) -- cgit v1.2.3 From e9a233f1f2fbc9b0204041dffa0f3ad6a1f7e8cf Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 28 Mar 2021 10:17:47 +0300 Subject: Remove talentpool channel constants --- bot/constants.py | 2 -- config-default.yml | 3 --- 2 files changed, 5 deletions(-) diff --git a/bot/constants.py b/bot/constants.py index 467a4a2c4..840f6fbf6 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -457,7 +457,6 @@ class Channels(metaclass=YAMLGetter): voice_chat: int big_brother_logs: int - talent_pool: int class Webhooks(metaclass=YAMLGetter): @@ -470,7 +469,6 @@ class Webhooks(metaclass=YAMLGetter): duck_pond: int incidents_archive: int reddit: int - talent_pool: int class Roles(metaclass=YAMLGetter): diff --git a/config-default.yml b/config-default.yml index 502f0f861..8fc1f6718 100644 --- a/config-default.yml +++ b/config-default.yml @@ -223,7 +223,6 @@ guild: # Watch big_brother_logs: &BB_LOGS 468507907357409333 - talent_pool: &TALENT_POOL 534321732593647616 moderation_categories: - *MODMAIL @@ -292,7 +291,6 @@ guild: incidents_archive: 720671599790915702 python_news: &PYNEWS_WEBHOOK 704381182279942324 reddit: 635408384794951680 - talent_pool: 569145364800602132 filter: @@ -323,7 +321,6 @@ filter: - *MESSAGE_LOG - *MOD_LOG - *STAFF_LOUNGE - - *TALENT_POOL - *USER_EVENT_A role_whitelist: -- cgit v1.2.3 From d1a2d9965fadc5292685d3ca78a75fd16f07af26 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Sat, 12 Jun 2021 14:08:52 -0700 Subject: Switched back to default value getting. --- bot/exts/recruitment/talentpool/_review.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_review.py b/bot/exts/recruitment/talentpool/_review.py index 585640699..4e61ecb3e 100644 --- a/bot/exts/recruitment/talentpool/_review.py +++ b/bot/exts/recruitment/talentpool/_review.py @@ -65,7 +65,7 @@ class Reviewer: """Schedules a single user for review.""" log.trace(f"Scheduling review of user with ID {user_id}") - user_data = self._pool.cache[user_id] + user_data = self._pool.cache.get(user_id) inserted_at = isoparse(user_data['inserted_at']).replace(tzinfo=None) review_at = inserted_at + timedelta(days=MAX_DAYS_IN_POOL) @@ -93,7 +93,7 @@ class Reviewer: await last_message.add_reaction(reaction) if update_database: - nomination = self._pool.cache[user_id] + nomination = self._pool.cache.get(user_id) await self.bot.api_client.patch(f"{self._pool.api_endpoint}/{nomination['id']}", json={"reviewed": True}) async def make_review(self, user_id: int) -> typing.Tuple[str, Optional[Emoji]]: @@ -104,7 +104,7 @@ class Reviewer: # not to accidentally insert the IDs of users that have no # active nominated by using the `watched_users.get(user_id)` # instead of `watched_users[user_id]`. - nomination = self._pool.cache[user_id] + nomination = self._pool.cache.get(user_id) if not nomination: log.trace(f"There doesn't appear to be an active nomination for {user_id}") return "", None @@ -393,7 +393,7 @@ class Reviewer: await ctx.send(f":x: Can't find a currently nominated user with id `{user_id}`") return False - nomination = self._pool.cache[user_id] + nomination = self._pool.cache.get(user_id) if nomination["reviewed"]: await ctx.send(":x: This nomination was already reviewed, but here's a cookie :cookie:") return False -- cgit v1.2.3 From c2d1c974bb95d75b275260e869ec67d3e92d1ae1 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 21:23:54 +0100 Subject: Change all references to watch to nominate instead --- bot/exts/recruitment/talentpool/_cog.py | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 8db2d7eac..99567d55e 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -25,7 +25,7 @@ log = logging.getLogger(__name__) class TalentPool(Cog, name="Talentpool"): - """Relays messages of helper candidates to a watch channel to observe them.""" + """Used to nominate potential helper candidates.""" # RedisCache[str, bool] # Can contain a single key, "autoreview_enabled", with the value a bool indicating if autoreview is enabled. @@ -59,7 +59,7 @@ class TalentPool(Cog, name="Talentpool"): params=self.api_default_params ) except ResponseCodeError as err: - log.exception("Failed to fetch the watched users from the API", exc_info=err) + log.exception("Failed to fetch the currently nominated users from the API", exc_info=err) return False self.cache = defaultdict(dict) @@ -120,7 +120,11 @@ class TalentPool(Cog, name="Talentpool"): else: await ctx.send("Autoreview is currently disabled") - @nomination_group.command(name='watched', aliases=('all', 'list'), root_aliases=("nominees",)) + @nomination_group.command( + name="nominess", + aliases=("nominated", "all", "list", "watched"), + root_aliases=("nominees",) + ) @has_any_role(*MODERATION_ROLES) async def list_command( self, @@ -201,19 +205,23 @@ class TalentPool(Cog, name="Talentpool"): """ await ctx.invoke(self.list_command, oldest_first=True, update_cache=update_cache) - @nomination_group.command(name='forcewatch', aliases=('fw', 'forceadd', 'fa'), root_aliases=("forcenominate",)) + @nomination_group.command( + name="forcenominate", + aliases=("fw", "forceadd", "fa", "fn", "forcewatch"), + root_aliases=("forcenominate",) + ) @has_any_role(*MODERATION_ROLES) - async def force_watch_command(self, ctx: Context, user: MemberOrUser, *, reason: str = '') -> None: + async def force_nominate_command(self, ctx: Context, user: MemberOrUser, *, reason: str = '') -> None: """ Adds the given `user` to the talent pool, from any channel. A `reason` for adding the user to the talent pool is optional. """ - await self._watch_user(ctx, user, reason) + await self._nominate_user(ctx, user, reason) - @nomination_group.command(name='watch', aliases=('w', 'add', 'a'), root_aliases=("nominate",)) + @nomination_group.command(name='nominate', aliases=("w", "add", "a", "watch"), root_aliases=("nominate",)) @has_any_role(*STAFF_ROLES) - async def watch_command(self, ctx: Context, user: MemberOrUser, *, reason: str = '') -> None: + async def nominate_command(self, ctx: Context, user: MemberOrUser, *, reason: str = '') -> None: """ Adds the given `user` to the talent pool. @@ -224,18 +232,18 @@ class TalentPool(Cog, name="Talentpool"): if any(role.id in MODERATION_ROLES for role in ctx.author.roles): await ctx.send( f":x: Nominations should be run in the <#{Channels.nominations}> channel. " - "Use `!tp forcewatch` to override this check." + "Use `!tp forcenominate` to override this check." ) else: await ctx.send(f":x: Nominations must be run in the <#{Channels.nominations}> channel") return - await self._watch_user(ctx, user, reason) + await self._nominate_user(ctx, user, reason) - async def _watch_user(self, ctx: Context, user: MemberOrUser, reason: str) -> None: + async def _nominate_user(self, ctx: Context, user: MemberOrUser, reason: str) -> None: """Adds the given user to the talent pool.""" if user.bot: - await ctx.send(f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. I only watch humans.") + await ctx.send(f":x: I'm sorry {ctx.author}, I'm afraid I can't do that. Only humans can be nominated.") return if isinstance(user, Member) and any(role.id in STAFF_ROLES for role in user.roles): @@ -325,7 +333,7 @@ class TalentPool(Cog, name="Talentpool"): @nomination_group.command(name='end', aliases=('unwatch',), root_aliases=("unnominate",)) @has_any_role(*MODERATION_ROLES) - async def unwatch_command(self, ctx: Context, user: MemberOrUser, *, reason: str) -> None: + async def end_nomination_command(self, ctx: Context, user: MemberOrUser, *, reason: str) -> None: """ Ends the active nomination of the specified user with the given reason. @@ -335,7 +343,7 @@ class TalentPool(Cog, name="Talentpool"): await ctx.send(f":x: Maximum allowed characters for the end reason is {REASON_MAX_CHARS}.") return - if await self.unwatch(user.id, reason): + if await self.end_nomination(user.id, reason): await ctx.send(f":white_check_mark: Messages sent by {user.mention} will no longer be relayed") else: await ctx.send(":x: The specified user does not have an active nomination") @@ -444,7 +452,7 @@ class TalentPool(Cog, name="Talentpool"): @Cog.listener() async def on_member_ban(self, guild: Guild, user: Union[MemberOrUser]) -> None: """Remove `user` from the talent pool after they are banned.""" - await self.unwatch(user.id, "User was banned.") + await self.end_nomination(user.id, "User was banned.") @Cog.listener() async def on_raw_reaction_add(self, payload: RawReactionActionEvent) -> None: @@ -466,7 +474,7 @@ class TalentPool(Cog, name="Talentpool"): log.info(f"Archiving nomination {message.id}") await self.reviewer.archive_vote(message, emoji == Emojis.incident_actioned) - async def unwatch(self, user_id: int, reason: str) -> bool: + async def end_nomination(self, user_id: int, reason: str) -> bool: """End the active nomination of a user with the given reason and return True on success.""" active_nomination = await self.bot.api_client.get( 'bot/nominations', @@ -536,7 +544,7 @@ class TalentPool(Cog, name="Talentpool"): {entries_string} End date: {end_date} - Unwatch reason: {nomination_object["end_reason"]} + Unnominate reason: {nomination_object["end_reason"]} =============== """ ) -- cgit v1.2.3 From 20aa8b23a386ad2d570a1d771825331b07074bb1 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 21:27:54 +0100 Subject: Remove code that is no longer hit --- bot/exts/recruitment/talentpool/_cog.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 99567d55e..78f9b189b 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -47,10 +47,6 @@ class TalentPool(Cog, name="Talentpool"): """Return whether automatic posting of nomination reviews is enabled.""" return await self.talentpool_settings.get(AUTOREVIEW_ENABLED_KEY, True) - # Stores talentpool users in cache - self.cache = defaultdict(dict) - self.api_default_params = {'active': 'true', 'ordering': '-inserted_at'} - async def refresh_cache(self) -> bool: """Updates TalentPool users cache.""" try: -- cgit v1.2.3 From ffed769fbb1f450ac966564cc0ba75c2406e18ae Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 21:39:20 +0100 Subject: Update comment to reference the new TalentPool cache name --- bot/exts/recruitment/talentpool/_review.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_review.py b/bot/exts/recruitment/talentpool/_review.py index dfdcdcffe..1cc9c900c 100644 --- a/bot/exts/recruitment/talentpool/_review.py +++ b/bot/exts/recruitment/talentpool/_review.py @@ -103,10 +103,10 @@ class Reviewer: """Format a generic review of a user and return it with the reviewed emoji.""" log.trace(f"Formatting the review of {user_id}") - # Since `watched_users` is a defaultdict, we should take care + # Since `cache` is a defaultdict, we should take care # not to accidentally insert the IDs of users that have no - # active nominated by using the `watched_users.get(user_id)` - # instead of `watched_users[user_id]`. + # active nominated by using the `cache.get(user_id)` + # instead of `cache[user_id]`. nomination = self._pool.cache.get(user_id) if not nomination: log.trace(f"There doesn't appear to be an active nomination for {user_id}") -- cgit v1.2.3 From 6a35307ada47a1c3091b23fb3a33dea78fe63c15 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 21:44:48 +0100 Subject: Update api endpoint name in talent pool review --- bot/exts/recruitment/talentpool/_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_review.py b/bot/exts/recruitment/talentpool/_review.py index 1cc9c900c..3ffbf93f3 100644 --- a/bot/exts/recruitment/talentpool/_review.py +++ b/bot/exts/recruitment/talentpool/_review.py @@ -97,7 +97,7 @@ class Reviewer: if update_database: nomination = self._pool.cache.get(user_id) - await self.bot.api_client.patch(f"{self._pool.api_endpoint}/{nomination['id']}", json={"reviewed": True}) + await self.bot.api_client.patch(f"bot/nominations/{nomination['id']}", json={"reviewed": True}) async def make_review(self, user_id: int) -> typing.Tuple[str, Optional[Emoji]]: """Format a generic review of a user and return it with the reviewed emoji.""" -- cgit v1.2.3 From 892fafcd653b35c53ba48d7af42decd50b7fdda9 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 21:58:59 +0100 Subject: Update unnominate message to remove reference to relaying messages. --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 78f9b189b..4a77de24c 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -340,7 +340,7 @@ class TalentPool(Cog, name="Talentpool"): return if await self.end_nomination(user.id, reason): - await ctx.send(f":white_check_mark: Messages sent by {user.mention} will no longer be relayed") + await ctx.send(f":white_check_mark: Successfully un-nominated {user}") else: await ctx.send(":x: The specified user does not have an active nomination") -- cgit v1.2.3 From bcb664e19c3e417c17f00562180393f601c43a5a Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 22:04:09 +0100 Subject: Add back missing default params for TalentPool cog --- bot/exts/recruitment/talentpool/_cog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 4a77de24c..38fefddd4 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -34,6 +34,7 @@ class TalentPool(Cog, name="Talentpool"): def __init__(self, bot: Bot) -> None: self.bot = bot self.reviewer = Reviewer(self.__class__.__name__, bot, self) + self.api_default_params = {'active': 'true', 'ordering': '-inserted_at'} self.bot.loop.create_task(self.schedule_autoreviews()) async def schedule_autoreviews(self) -> None: -- cgit v1.2.3 From ea6bd12f09c7978db24184cf09b91e1d643cffba Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 22:04:46 +0100 Subject: use global logger in talent pool, over a self var that has been deleted --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 38fefddd4..f932fc003 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -42,7 +42,7 @@ class TalentPool(Cog, name="Talentpool"): if await self.autoreview_enabled(): await self.reviewer.reschedule_reviews() else: - self.log.trace("Not scheduling reviews as autoreview is disabled.") + log.trace("Not scheduling reviews as autoreview is disabled.") async def autoreview_enabled(self) -> bool: """Return whether automatic posting of nomination reviews is enabled.""" -- cgit v1.2.3 From 5ca1fec1e9a2bb767863701bee1ffcad729331ec Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 22:46:26 +0100 Subject: Rename list nominated user command for clarity --- bot/exts/recruitment/talentpool/_cog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index f932fc003..6dc36058b 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -137,9 +137,9 @@ class TalentPool(Cog, name="Talentpool"): The optional kwarg `update_cache` can be used to update the user cache using the API before listing the users. """ - await self.list_users(ctx, oldest_first=oldest_first, update_cache=update_cache) + await self.list_nominated_users(ctx, oldest_first=oldest_first, update_cache=update_cache) - async def list_users( + async def list_nominated_users( self, ctx: Context, oldest_first: bool = False, -- cgit v1.2.3 From 9ef8306c2bc8ab0285da62ba2c7c42e003f015e2 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 30 Aug 2021 22:51:47 +0100 Subject: Fix spelling of a TalentPool command name --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 6dc36058b..c0b3f8348 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -118,7 +118,7 @@ class TalentPool(Cog, name="Talentpool"): await ctx.send("Autoreview is currently disabled") @nomination_group.command( - name="nominess", + name="nominees", aliases=("nominated", "all", "list", "watched"), root_aliases=("nominees",) ) -- cgit v1.2.3 From 990bc67c7d02027d1eb3fc30654585bf77bc0d17 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Wed, 1 Sep 2021 10:23:05 +0100 Subject: Add an extra alias to unnominate --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index c0b3f8348..477fff2fd 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -328,7 +328,7 @@ class TalentPool(Cog, name="Talentpool"): max_size=1000 ) - @nomination_group.command(name='end', aliases=('unwatch',), root_aliases=("unnominate",)) + @nomination_group.command(name="end", aliases=("unwatch", "unnominate"), root_aliases=("unnominate",)) @has_any_role(*MODERATION_ROLES) async def end_nomination_command(self, ctx: Context, user: MemberOrUser, *, reason: str) -> None: """ -- cgit v1.2.3 From 97017f00ecdb70359ff8cf6f4a8fe970c6aa7ad5 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Fri, 3 Sep 2021 00:50:50 -0700 Subject: `Unnominate reason` to `Unnomination reason` --- bot/exts/recruitment/talentpool/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index 477fff2fd..c2257c84b 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -541,7 +541,7 @@ class TalentPool(Cog, name="Talentpool"): {entries_string} End date: {end_date} - Unnominate reason: {nomination_object["end_reason"]} + Unnomination reason: {nomination_object["end_reason"]} =============== """ ) -- cgit v1.2.3 From a06367e1691d8ef39e2cf8f8e0d15e5922d29d01 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Fri, 3 Sep 2021 09:42:44 +0100 Subject: Pop user from talent pool cache when unnominated --- bot/exts/recruitment/talentpool/_cog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py index c2257c84b..a317c6645 100644 --- a/bot/exts/recruitment/talentpool/_cog.py +++ b/bot/exts/recruitment/talentpool/_cog.py @@ -493,6 +493,7 @@ class TalentPool(Cog, name="Talentpool"): json={'end_reason': reason, 'active': False} ) + self.cache.pop(user_id) if await self.autoreview_enabled(): self.reviewer.cancel(user_id) -- cgit v1.2.3