aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar wookie184 <[email protected]>2023-03-04 15:07:49 +0000
committerGravatar wookie184 <[email protected]>2023-03-04 15:07:49 +0000
commite9aa8f1621f9fcff0ace8e6cbe37c98449641773 (patch)
tree7a9abbc31a4f81030f720ce06d8cb1dc1771b6f5
parentBump inactivity removal threshold and display in message (diff)
Split default nomination listing into groups
-rw-r--r--bot/exts/recruitment/talentpool/_api.py3
-rw-r--r--bot/exts/recruitment/talentpool/_cog.py116
-rw-r--r--bot/exts/recruitment/talentpool/_review.py19
3 files changed, 101 insertions, 37 deletions
diff --git a/bot/exts/recruitment/talentpool/_api.py b/bot/exts/recruitment/talentpool/_api.py
index 7b6c67fc3..e12111de5 100644
--- a/bot/exts/recruitment/talentpool/_api.py
+++ b/bot/exts/recruitment/talentpool/_api.py
@@ -124,6 +124,9 @@ class NominationAPI:
Returns a dictionary mapping user ID to message count.
"""
+ if not user_ids:
+ return {}
+
result = await self.site_api.post(
"bot/users/metricity_activity_data",
json=user_ids,
diff --git a/bot/exts/recruitment/talentpool/_cog.py b/bot/exts/recruitment/talentpool/_cog.py
index 7a9db7886..b92afdbcc 100644
--- a/bot/exts/recruitment/talentpool/_cog.py
+++ b/bot/exts/recruitment/talentpool/_cog.py
@@ -15,7 +15,7 @@ from bot.bot import Bot
from bot.constants import Bot as BotConfig, Channels, Emojis, Guild, MODERATION_ROLES, Roles, STAFF_ROLES
from bot.converters import MemberOrUser, UnambiguousMemberOrUser
from bot.exts.recruitment.talentpool._api import Nomination, NominationAPI
-from bot.exts.recruitment.talentpool._review import RECENT_ACTIVITY_DAYS, Reviewer
+from bot.exts.recruitment.talentpool._review import Reviewer
from bot.log import get_logger
from bot.pagination import LinePaginator
from bot.utils import time
@@ -152,6 +152,9 @@ class TalentPool(Cog, name="Talentpool"):
if messages_per_user[nomination.user_id] > 0:
continue
+ if nomination.reviewed:
+ continue
+
log.info("Removing %s from the talent pool due to inactivity", nomination.user_id)
await nomination_discussion.send(
@@ -176,56 +179,105 @@ class TalentPool(Cog, name="Talentpool"):
ctx: Context,
) -> None:
"""
- Shows the users that are currently in the talent pool, ordered by next to be reviewed.
+ Shows the users that are currently in the talent pool.
- Note that this order will change over time, so should not be relied upon.
+ The "Recent Nominations" sections shows users nominated in the past 7 days,
+ so will not be considered for autoreview.
+
+ In the "Autoreview Priority" section a :zzz: emoji will be shown next to
+ users that have not been active recently enough to be considered for autoreview.
+ Note that the order in this section will change over time so should not be relied upon.
"""
- await self.list_nominated_users(ctx, order_by_priority=True)
+ await self.show_nominations_list(ctx, grouped_view=True)
@list_group.command(name="oldest")
async def list_oldest(self, ctx: Context) -> None:
"""Shows the users that are currently in the talent pool, ordered by oldest nomination."""
- await self.list_nominated_users(ctx, oldest_first=True)
+ await self.show_nominations_list(ctx, oldest_first=True)
@list_group.command(name='newest')
async def list_newest(self, ctx: Context) -> None:
"""Shows the users that are currently in the talent pool, ordered by newest nomination."""
- await self.list_nominated_users(ctx, oldest_first=False)
+ await self.show_nominations_list(ctx, oldest_first=False)
- async def list_nominated_users(
+ async def show_nominations_list(
self,
ctx: Context,
+ *,
oldest_first: bool = False,
- order_by_priority: bool = False
+ grouped_view: bool = False,
) -> None:
"""
Lists the currently nominated users.
- The optional kwarg `oldest_first` orders the list by oldest entry.
+ If `grouped_view` is passed, nominations will be displayed in the groups
+ being reviewed, recent nominations, and others by autoreview priority.
+
+ Otherwise, nominations will be sorted by age
+ (ordered based on the value of `oldest_first`).
"""
now = datetime.now(tz=timezone.utc)
+ nominations = await self.api.get_nominations(active=True)
+ messages_per_user = await self.api.get_activity(
+ [nomination.user_id for nomination in nominations],
+ days=DAYS_UNTIL_INACTIVE
+ )
+
+ if grouped_view:
+ reviewed_nominations = []
+ recent_nominations = []
+ other_nominations = []
+ for nomination in nominations:
+ if nomination.reviewed:
+ reviewed_nominations.append(nomination)
+ elif not self.reviewer.is_nomination_old_enough(nomination, now):
+ recent_nominations.append(nomination)
+ else:
+ other_nominations.append(nomination)
+
+ other_nominations = await self.reviewer.sort_nominations_to_review(other_nominations, now)
+
+ lines = [
+ "**Being Reviewed:**",
+ *await self.list_nominations(ctx, reviewed_nominations, messages_per_user),
+ "**Recent Nominations:**",
+ *await self.list_nominations(ctx, recent_nominations, messages_per_user),
+ "**Other Nominations by Autoreview Priority:**",
+ *await self.list_nominations(ctx, other_nominations, messages_per_user, show_inactive=True)
+ ]
+ else:
+ if oldest_first:
+ nominations.reverse()
+ lines = await self.list_nominations(ctx, nominations, messages_per_user, show_reviewed=True)
+
+ if not lines:
+ lines = ["There are no active nominations"]
+
embed = Embed(
title="Talent Pool active nominations",
color=Color.blue()
)
- nominations = await self.api.get_nominations(active=True)
+ await LinePaginator.paginate(lines, ctx, embed, empty=False)
- if not nominations:
- embed.description = "There are no active nominations."
- await ctx.send(embed=embed)
- return
+ async def list_nominations(
+ self,
+ ctx: Context,
+ nominations: list[Nomination],
+ messages_per_user: dict[int, int],
+ show_reviewed: bool = False,
+ show_inactive: bool = False,
+ ) -> list[str]:
+ """
+ Formats the given nominations into a list.
- if order_by_priority:
- nominations = await self.reviewer.sort_nominations_to_review(nominations, now)
- elif oldest_first:
- nominations.reverse()
+ Pass `show_reviewed` to indicate reviewed nominations, and `show_inactive` to
+ indicate if the user doesn't have recent enough activity to be autoreviewed.
+ """
+ lines: list[str] = []
- messages_per_user = await self.api.get_activity(
- [nomination.user_id for nomination in nominations],
- days=RECENT_ACTIVITY_DAYS
- )
+ if not nominations:
+ return ["*None*"]
- lines: list[str] = []
for nomination in nominations:
line = f"• `{nomination.user_id}`"
@@ -233,23 +285,19 @@ class TalentPool(Cog, name="Talentpool"):
if member:
line += f" ({member.name}#{member.discriminator})"
else:
- line += " (not in server)"
+ line += " (not on server)"
line += f", added {time.format_relative(nomination.inserted_at)}"
- is_ready_for_review = await self.reviewer.is_nomination_ready_for_review(
- nomination,
- messages_per_user[nomination.user_id],
- now
- )
- if nomination.reviewed:
+ if show_reviewed and nomination.reviewed:
line += " *(reviewed)*"
- elif is_ready_for_review:
- line += " *(ready for review)*"
- lines.append(line)
+ is_active = self.reviewer.is_user_active_enough(messages_per_user[nomination.user_id])
+ if show_inactive and not is_active:
+ line += " :zzz:"
- await LinePaginator.paginate(lines, ctx, embed, empty=False)
+ lines.append(line)
+ return lines
@nomination_group.command(
name="forcenominate",
diff --git a/bot/exts/recruitment/talentpool/_review.py b/bot/exts/recruitment/talentpool/_review.py
index 9436f2bad..9abf3affa 100644
--- a/bot/exts/recruitment/talentpool/_review.py
+++ b/bot/exts/recruitment/talentpool/_review.py
@@ -109,6 +109,17 @@ class Reviewer:
return True
+ @staticmethod
+ def is_nomination_old_enough(nomination: Nomination, now: datetime) -> bool:
+ """Check if a nomination is old enough to autoreview."""
+ time_since_nomination = now - nomination.inserted_at
+ return time_since_nomination > MIN_NOMINATION_TIME
+
+ @staticmethod
+ def is_user_active_enough(user_message_count: int) -> bool:
+ """Check if a user's message count is enough for them to be autoreviewed."""
+ return user_message_count > 0
+
async def is_nomination_ready_for_review(
self,
nomination: Nomination,
@@ -125,16 +136,15 @@ class Reviewer:
- They are still a member of the server.
"""
guild = self.bot.get_guild(Guild.id)
- time_since_nomination = now - nomination.inserted_at
return (
# Must be an active nomination
nomination.active and
# ... that has not already been reviewed
not nomination.reviewed and
# ... and has been nominated for long enough
- time_since_nomination > MIN_NOMINATION_TIME and
+ self.is_nomination_old_enough(nomination, now) and
# ... and is for a user that has been active recently
- user_message_count > 0 and
+ self.is_user_active_enough(user_message_count) and
# ... and is currently a member of the server
await get_or_fetch_member(guild, nomination.id) is not None
)
@@ -146,6 +156,9 @@ class Reviewer:
The priority of the review is determined based on how many nominations the user has
(more nominations = higher priority), and the age of the nomination.
"""
+ if not nominations:
+ return []
+
oldest_date = min(nomination.inserted_at for nomination in nominations)
max_entries = max(len(nomination.entries) for nomination in nominations)