diff options
| author | 2021-03-28 09:10:35 +0300 | |
|---|---|---|
| committer | 2021-03-28 09:10:35 +0300 | |
| commit | 78b00dc8f43d7cb25ce72bc97d6236ec9944cd1f (patch) | |
| tree | 5f88d150b795e12a7ce4d1fc2698239ca5ac9a6a | |
| parent | Merge pull request #1466 from vcokltfre/discord-tags (diff) | |
Remove WatchChannel parent of TalentPool and migrate first commands
| -rw-r--r-- | bot/exts/recruitment/talentpool/_cog.py | 80 |
1 files 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", |