aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/moderation/watchchannels/_watchchannel.py8
-rw-r--r--bot/exts/moderation/watchchannels/talentpool.py108
2 files changed, 87 insertions, 29 deletions
diff --git a/bot/exts/moderation/watchchannels/_watchchannel.py b/bot/exts/moderation/watchchannels/_watchchannel.py
index f9fc12dc3..0793a66af 100644
--- a/bot/exts/moderation/watchchannels/_watchchannel.py
+++ b/bot/exts/moderation/watchchannels/_watchchannel.py
@@ -47,7 +47,9 @@ class WatchChannel(metaclass=CogABCMeta):
webhook_id: int,
api_endpoint: str,
api_default_params: dict,
- logger: logging.Logger
+ logger: logging.Logger,
+ *,
+ disable_header: bool = False
) -> None:
self.bot = bot
@@ -66,6 +68,7 @@ class WatchChannel(metaclass=CogABCMeta):
self.channel = None
self.webhook = None
self.message_history = MessageHistory()
+ self.disable_header = disable_header
self._start = self.bot.loop.create_task(self.start_watchchannel())
@@ -267,6 +270,9 @@ class WatchChannel(metaclass=CogABCMeta):
async def send_header(self, msg: Message) -> None:
"""Sends a header embed with information about the relayed messages to the watch channel."""
+ if self.disable_header:
+ return
+
user_id = msg.author.id
guild = self.bot.get_guild(GuildConfig.id)
diff --git a/bot/exts/moderation/watchchannels/talentpool.py b/bot/exts/moderation/watchchannels/talentpool.py
index dd3349c3a..d75688fa6 100644
--- a/bot/exts/moderation/watchchannels/talentpool.py
+++ b/bot/exts/moderation/watchchannels/talentpool.py
@@ -14,6 +14,8 @@ from bot.exts.moderation.watchchannels._watchchannel import WatchChannel
from bot.pagination import LinePaginator
from bot.utils import time
+REASON_MAX_CHARS = 1000
+
log = logging.getLogger(__name__)
@@ -28,6 +30,7 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
api_endpoint='bot/nominations',
api_default_params={'active': 'true', 'ordering': '-inserted_at'},
logger=log,
+ disable_header=True,
)
@group(name='talentpool', aliases=('tp', 'talent', 'nomination', 'n'), invoke_without_command=True)
@@ -83,8 +86,8 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
await ctx.send(f":x: Failed to update the user cache; can't add {user}")
return
- if user.id in self.watched_users:
- await ctx.send(f":x: {user} is already being watched in the talent pool")
+ if len(reason) > REASON_MAX_CHARS:
+ await ctx.send(f":x: Maxiumum allowed characters for the reason is {REASON_MAX_CHARS}.")
return
# Manual request with `raise_for_status` as False because we want the actual response
@@ -101,14 +104,18 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
async with session.post(url, **kwargs) as resp:
response_data = await resp.json()
- if resp.status == 400 and response_data.get('user', False):
- await ctx.send(":x: The specified user can't be found in the database tables")
+ if resp.status == 400:
+ if response_data.get('user', False):
+ await ctx.send(":x: The specified user can't be found in the database tables")
+ elif response_data.get('actor', False):
+ await ctx.send(":x: You have already nominated this user")
+
return
else:
resp.raise_for_status()
self.watched_users[user.id] = response_data
- msg = f":white_check_mark: Messages sent by {user} will now be relayed to the talent pool channel"
+ msg = f":white_check_mark: The nomination for {user} has been added to the talent pool"
history = await self.bot.api_client.get(
self.api_endpoint,
@@ -120,9 +127,7 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
)
if history:
- total = f"({len(history)} previous nominations in total)"
- start_reason = f"Watched: {textwrap.shorten(history[0]['reason'], width=500, placeholder='...')}"
- msg += f"\n\nUser's previous watch reasons {total}:```{start_reason}```"
+ msg += f"\n\n({len(history)} previous nominations in total)"
await ctx.send(msg)
@@ -163,6 +168,10 @@ class TalentPool(WatchChannel, 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}.")
+ return
+
if await self.unwatch(user.id, reason):
await ctx.send(f":white_check_mark: Messages sent by {user} will no longer be relayed")
else:
@@ -176,33 +185,69 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
@nomination_edit_group.command(name='reason')
@has_any_role(*MODERATION_ROLES)
- async def edit_reason_command(self, ctx: Context, nomination_id: int, *, reason: str) -> None:
- """
- Edits the reason/unnominate reason for the nomination with the given `id` depending on the status.
+ async def edit_reason_command(self, ctx: Context, nomination_id: int, actor: FetchedMember, *, reason: str) -> None:
+ """Edits the reason of a specific nominator in a specific active nomination."""
+ if len(reason) > REASON_MAX_CHARS:
+ await ctx.send(f":x: Maxiumum allowed characters for the reason is {REASON_MAX_CHARS}.")
+ return
- If the nomination is active, the reason for nominating the user will be edited;
- If the nomination is no longer active, the reason for ending the nomination will be edited instead.
- """
try:
nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{nomination_id}")
except ResponseCodeError as e:
if e.response.status == 404:
- self.log.trace(f"Nomination API 404: Can't nomination with id {nomination_id}")
+ self.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:
raise
- field = "reason" if nomination["active"] else "end_reason"
+ if not nomination["active"]:
+ await ctx.send(":x: Can't edit the reason of an inactive nomination.")
+ return
+
+ if not any(entry["actor"] == actor.id for entry in nomination["entries"]):
+ await ctx.send(f":x: {actor} doesn't have an entry in this nomination.")
+ return
- self.log.trace(f"Changing {field} for nomination with id {nomination_id} to {reason}")
+ self.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}",
- json={field: reason}
+ json={"actor": actor.id, "reason": reason}
+ )
+ await self.fetch_user_cache() # Update cache
+ await ctx.send(":white_check_mark: Successfully updated nomination reason.")
+
+ @nomination_edit_group.command(name='end_reason')
+ @has_any_role(*MODERATION_ROLES)
+ async def edit_end_reason_command(self, ctx: Context, nomination_id: int, *, reason: str) -> None:
+ """Edits the unnominate reason for the nomination with the given `id`."""
+ if len(reason) > REASON_MAX_CHARS:
+ await ctx.send(f":x: Maxiumum allowed characters for the end reason is {REASON_MAX_CHARS}.")
+ return
+
+ try:
+ nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{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}")
+ await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`")
+ return
+ else:
+ raise
+
+ if nomination["active"]:
+ 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)}")
+
+ await self.bot.api_client.patch(
+ f"{self.api_endpoint}/{nomination_id}",
+ json={"end_reason": reason}
)
await self.fetch_user_cache() # Update cache.
- await ctx.send(f":white_check_mark: Updated the {field} of the nomination!")
+ await ctx.send(":white_check_mark: Updated the end reason of the nomination!")
@Cog.listener()
async def on_member_ban(self, guild: Guild, user: Union[User, Member]) -> None:
@@ -237,14 +282,21 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
def _nomination_to_string(self, nomination_object: dict) -> str:
"""Creates a string representation of a nomination."""
guild = self.bot.get_guild(Guild.id)
+ entries = []
+ for site_entry in nomination_object["entries"]:
+ actor_id = site_entry["actor"]
+ actor = guild.get_member(actor_id)
+
+ reason = site_entry["reason"] or "*None*"
+ created = time.format_infraction(site_entry["inserted_at"])
+ entries.append(
+ f"Actor: {actor.mention if actor else actor_id}\nCreated: {created}\nReason: {reason}"
+ )
- actor_id = nomination_object["actor"]
- actor = guild.get_member(actor_id)
+ entries_string = "\n\n".join(entries)
active = nomination_object["active"]
- reason = nomination_object["reason"] or "*None*"
-
start_date = time.format_infraction(nomination_object["inserted_at"])
if active:
lines = textwrap.dedent(
@@ -252,9 +304,9 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
===============
Status: **Active**
Date: {start_date}
- Actor: {actor.mention if actor else actor_id}
- Reason: {reason}
Nomination ID: `{nomination_object["id"]}`
+
+ {entries_string}
===============
"""
)
@@ -265,12 +317,12 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"):
===============
Status: Inactive
Date: {start_date}
- Actor: {actor.mention if actor else actor_id}
- Reason: {reason}
+ Nomination ID: `{nomination_object["id"]}`
+
+ {entries_string}
End date: {end_date}
Unwatch reason: {nomination_object["end_reason"]}
- Nomination ID: `{nomination_object["id"]}`
===============
"""
)