aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Sebastiaan Zeeff <[email protected]>2020-04-12 09:33:18 +0200
committerGravatar Sebastiaan Zeeff <[email protected]>2020-04-12 09:33:18 +0200
commitd87097c99942b7b12016287e1a6bdb5924664436 (patch)
treecbfc60ccd48c7c4110898f984b0b7145b658e757
parenttimer -> timing for statsd (diff)
parentMerge branch 'help-dormant-feedback' of https://github.com/Numerlor/bot into ... (diff)
Merge branch 'Numerlor-help-dormant-feedback' into `master`
After resolving the merge conflicts created by the recent stats addition, I'm merging this into master. No functional changes were made during conflict resolution (hopefully) and the merge has been tested.
-rw-r--r--bot/__init__.py2
-rw-r--r--bot/cogs/help_channels.py61
2 files changed, 53 insertions, 10 deletions
diff --git a/bot/__init__.py b/bot/__init__.py
index c9dbc3f40..2dd4af225 100644
--- a/bot/__init__.py
+++ b/bot/__init__.py
@@ -33,7 +33,7 @@ log_format = logging.Formatter(format_string)
log_file = Path("logs", "bot.log")
log_file.parent.mkdir(exist_ok=True)
-file_handler = handlers.RotatingFileHandler(log_file, maxBytes=5242880, backupCount=7)
+file_handler = handlers.RotatingFileHandler(log_file, maxBytes=5242880, backupCount=7, encoding="utf8")
file_handler.setFormatter(log_format)
root_log = logging.getLogger()
diff --git a/bot/cogs/help_channels.py b/bot/cogs/help_channels.py
index 12bc4e279..4dd70d7bf 100644
--- a/bot/cogs/help_channels.py
+++ b/bot/cogs/help_channels.py
@@ -5,6 +5,7 @@ import logging
import random
import typing as t
from collections import deque
+from contextlib import suppress
from datetime import datetime
from pathlib import Path
@@ -13,7 +14,7 @@ from discord.ext import commands
from bot import constants
from bot.bot import Bot
-from bot.decorators import with_role
+from bot.utils.checks import with_role_check
from bot.utils.scheduling import Scheduler
log = logging.getLogger(__name__)
@@ -108,6 +109,9 @@ class HelpChannels(Scheduler, commands.Cog):
super().__init__()
self.bot = bot
+ self.help_channel_claimants: (
+ t.Dict[discord.TextChannel, t.Union[discord.Member, discord.User]]
+ ) = {}
# Categories
self.available_category: discord.CategoryChannel = None
@@ -190,15 +194,39 @@ class HelpChannels(Scheduler, commands.Cog):
log.trace("Populating the name queue with names.")
return deque(available_names)
+ async def dormant_check(self, ctx: commands.Context) -> bool:
+ """Return True if the user is the help channel claimant or passes the role check."""
+ if self.help_channel_claimants.get(ctx.channel) == ctx.author:
+ log.trace(f"{ctx.author} is the help channel claimant, passing the check for dormant.")
+ return True
+
+ log.trace(f"{ctx.author} is not the help channel claimant, checking roles.")
+ return with_role_check(ctx, *constants.HelpChannels.cmd_whitelist)
+
@commands.command(name="dormant", aliases=["close"], enabled=False)
- @with_role(*constants.HelpChannels.cmd_whitelist)
async def dormant_command(self, ctx: commands.Context) -> None:
- """Make the current in-use help channel dormant."""
- log.trace("dormant command invoked; checking if the channel is in-use.")
+ """
+ Make the current in-use help channel dormant.
+ Make the channel dormant if the user passes the `dormant_check`,
+ delete the message that invoked this,
+ and reset the send permissions cooldown for the user who started the session.
+ """
+ log.trace("dormant command invoked; checking if the channel is in-use.")
if ctx.channel.category == self.in_use_category:
- self.cancel_task(ctx.channel.id)
- await self.move_to_dormant(ctx.channel, "command")
+ if await self.dormant_check(ctx):
+ with suppress(KeyError):
+ del self.help_channel_claimants[ctx.channel]
+
+ with suppress(discord.errors.NotFound):
+ log.trace("Deleting dormant invokation message.")
+ await ctx.message.delete()
+
+ with suppress(discord.errors.HTTPException, discord.errors.NotFound):
+ await self.reset_claimant_send_permission(ctx.channel)
+
+ await self.move_to_dormant(ctx.channel, "command")
+ self.cancel_task(ctx.channel.id)
else:
log.debug(f"{ctx.author} invoked command 'dormant' outside an in-use help channel")
@@ -382,14 +410,13 @@ class HelpChannels(Scheduler, commands.Cog):
self.bot.stats.gauge("help.total.available", total_available)
self.bot.stats.gauge("help.total.dormant", total_dormant)
- @staticmethod
- def is_dormant_message(message: t.Optional[discord.Message]) -> bool:
+ def is_dormant_message(self, message: t.Optional[discord.Message]) -> bool:
"""Return True if the contents of the `message` match `DORMANT_MSG`."""
if not message or not message.embeds:
return False
embed = message.embeds[0]
- return embed.description.strip() == DORMANT_MSG.strip()
+ return message.author == self.bot.user and embed.description.strip() == DORMANT_MSG.strip()
async def move_idle_channel(self, channel: discord.TextChannel, has_task: bool = True) -> None:
"""
@@ -571,6 +598,8 @@ class HelpChannels(Scheduler, commands.Cog):
await self.move_to_in_use(channel)
await self.revoke_send_permissions(message.author)
+ # Add user with channel for dormant check.
+ self.help_channel_claimants[channel] = message.author
self.bot.stats.incr("help.claimed")
@@ -631,6 +660,20 @@ class HelpChannels(Scheduler, commands.Cog):
log.trace(f"Ensuring channels in `Help: Available` are synchronized after permissions reset.")
await self.ensure_permissions_synchronization(self.available_category)
+ async def reset_claimant_send_permission(self, channel: discord.TextChannel) -> None:
+ """Reset send permissions in the Available category for the help `channel` claimant."""
+ log.trace(f"Attempting to find claimant for #{channel.name} ({channel.id}).")
+ try:
+ member = self.help_channel_claimants[channel]
+ except KeyError:
+ log.trace(f"Channel #{channel.name} ({channel.id}) not in claimant cache, permissions unchanged.")
+ return
+
+ log.trace(f"Resetting send permissions for {member} ({member.id}).")
+ await self.update_category_permissions(self.available_category, member, overwrite=None)
+ # Ignore missing task when claim cooldown has passed but the channel still isn't dormant.
+ self.cancel_task(member.id, ignore_missing=True)
+
async def revoke_send_permissions(self, member: discord.Member) -> None:
"""
Disallow `member` to send messages in the Available category for a certain time.