aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Sebastiaan Zeeff <[email protected]>2020-04-27 14:27:22 +0200
committerGravatar GitHub <[email protected]>2020-04-27 14:27:22 +0200
commitb55e1f919d562621580b114289c15bae67d0366c (patch)
tree4101d3cc312e7c5c7c80f1473cafdd074c00ae11
parentHelpChannels: rename dormant command to close (diff)
parentMerge pull request #904 from Akarys42/free-tag (diff)
Merge branch 'master' into feat/frontend/839/help-channel-role
-rw-r--r--bot/cogs/help_channels.py50
-rw-r--r--bot/cogs/tags.py2
-rw-r--r--bot/resources/tags/free.md5
3 files changed, 50 insertions, 7 deletions
diff --git a/bot/cogs/help_channels.py b/bot/cogs/help_channels.py
index 75f907602..ef58ca9a1 100644
--- a/bot/cogs/help_channels.py
+++ b/bot/cogs/help_channels.py
@@ -63,7 +63,8 @@ through our guide for [asking a good question]({ASKING_GUIDE_URL}).
"""
AVAILABLE_EMOJI = "✅"
-IN_USE_EMOJI = "⌛"
+IN_USE_ANSWERED_EMOJI = "⌛"
+IN_USE_UNANSWERED_EMOJI = "⏳"
NAME_SEPARATOR = "|"
CoroutineFunc = t.Callable[..., t.Coroutine]
@@ -138,7 +139,14 @@ class HelpChannels(Scheduler, commands.Cog):
self.init_task = self.bot.loop.create_task(self.init_cog())
# Stats
- self.claim_times = {}
+
+ # This dictionary maps a help channel to the time it was claimed
+ self.claim_times: t.Dict[int, datetime] = {}
+
+ # This dictionary maps a help channel to whether it has had any
+ # activity other than the original claimant. True being no other
+ # activity and False being other activity.
+ self.unanswered: t.Dict[int, bool] = {}
def cog_unload(self) -> None:
"""Cancel the init task and scheduled tasks when the cog unloads."""
@@ -275,13 +283,12 @@ class HelpChannels(Scheduler, commands.Cog):
return name
- @staticmethod
- def get_category_channels(category: discord.CategoryChannel) -> t.Iterable[discord.TextChannel]:
+ def get_category_channels(self, category: discord.CategoryChannel) -> t.Iterable[discord.TextChannel]:
"""Yield the text channels of the `category` in an unsorted manner."""
log.trace(f"Getting text channels in the category '{category}' ({category.id}).")
# This is faster than using category.channels because the latter sorts them.
- for channel in category.guild.channels:
+ for channel in self.bot.get_guild(constants.Guild.id).channels:
if channel.category_id == category.id and isinstance(channel, discord.TextChannel):
yield channel
@@ -513,6 +520,12 @@ class HelpChannels(Scheduler, commands.Cog):
in_use_time = datetime.now() - claimed
self.bot.stats.timing("help.in_use_time", in_use_time)
+ if channel.id in self.unanswered:
+ if self.unanswered[channel.id]:
+ self.bot.stats.incr("help.sessions.unanswered")
+ else:
+ self.bot.stats.incr("help.sessions.answered")
+
log.trace(f"Position of #{channel} ({channel.id}) is actually {channel.position}.")
log.trace(f"Sending dormant message for #{channel} ({channel.id}).")
@@ -528,7 +541,7 @@ class HelpChannels(Scheduler, commands.Cog):
log.info(f"Moving #{channel} ({channel.id}) to the In Use category.")
await channel.edit(
- name=f"{IN_USE_EMOJI}{NAME_SEPARATOR}{self.get_clean_channel_name(channel)}",
+ name=f"{IN_USE_UNANSWERED_EMOJI}{NAME_SEPARATOR}{self.get_clean_channel_name(channel)}",
category=self.in_use_category,
sync_permissions=True,
topic=IN_USE_TOPIC,
@@ -587,6 +600,27 @@ class HelpChannels(Scheduler, commands.Cog):
# Handle it here cause this feature isn't critical for the functionality of the system.
log.exception("Failed to send notification about lack of dormant channels!")
+ async def check_for_answer(self, message: discord.Message) -> None:
+ """Checks for whether new content in a help channel comes from non-claimants."""
+ channel = message.channel
+ log.trace(f"Checking if #{channel} ({channel.id}) has been answered.")
+
+ # Confirm the channel is an in use help channel
+ if self.is_in_category(channel, constants.Categories.help_in_use):
+ # Check if there is an entry in unanswered (does not persist across restarts)
+ if channel.id in self.unanswered:
+ claimant_id = self.help_channel_claimants[channel].id
+
+ # Check the message did not come from the claimant
+ if claimant_id != message.author.id:
+ # Mark the channel as answered
+ self.unanswered[channel.id] = False
+
+ # Change the emoji in the channel name to signify activity
+ log.trace(f"#{channel} ({channel.id}) has been answered; changing its emoji")
+ name = self.get_clean_channel_name(channel)
+ await channel.edit(name=f"{IN_USE_ANSWERED_EMOJI}{NAME_SEPARATOR}{name}")
+
@commands.Cog.listener()
async def on_message(self, message: discord.Message) -> None:
"""Move an available channel to the In Use category and replace it with a dormant one."""
@@ -594,6 +628,9 @@ class HelpChannels(Scheduler, commands.Cog):
return # Ignore messages sent by bots.
channel = message.channel
+
+ await self.check_for_answer(message)
+
if not self.is_in_category(channel, constants.Categories.help_available):
return # Ignore messages outside the Available category.
@@ -619,6 +656,7 @@ class HelpChannels(Scheduler, commands.Cog):
self.bot.stats.incr("help.claimed")
self.claim_times[channel.id] = datetime.now()
+ self.unanswered[channel.id] = True
log.trace(f"Releasing on_message lock for {message.id}.")
diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py
index 9ba33d7e0..a813ffff5 100644
--- a/bot/cogs/tags.py
+++ b/bot/cogs/tags.py
@@ -43,7 +43,7 @@ class Tags(Cog):
tag = {
"title": tag_title,
"embed": {
- "description": file.read_text()
+ "description": file.read_text(encoding="utf-8")
}
}
cache[tag_title] = tag
diff --git a/bot/resources/tags/free.md b/bot/resources/tags/free.md
new file mode 100644
index 000000000..582cca9da
--- /dev/null
+++ b/bot/resources/tags/free.md
@@ -0,0 +1,5 @@
+**We have a new help channel system!**
+
+We recently moved to a new help channel system. You can now use any channel in the **<#691405807388196926>** category to ask your question.
+
+For more information, check out [our website](https://pythondiscord.com/pages/resources/guides/help-channels/).