From 2546e943b2b31edbfad07bfc6d978f2762a11a75 Mon Sep 17 00:00:00 2001 From: sebkuip Date: Sun, 16 Mar 2025 14:21:51 +0100 Subject: [PATCH 1/5] Fix multi-guild nickname channel names. Reduce cognitive complexity. --- bot.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index 3f13ef7ced..cffb2adfa9 100644 --- a/bot.py +++ b/bot.py @@ -1745,38 +1745,40 @@ async def log_expiry(self): logger.info(f"Deleted {expired_logs.deleted_count} expired logs.") - def format_channel_name(self, author, exclude_channel=None, force_null=False): + def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names Placed in main bot class to be extendable to plugins""" guild = self.modmail_guild if force_null: - name = new_name = "null" + return "null" else: if self.config["use_random_channel_name"]: to_hash = self.token.split(".")[-1] + str(author.id) digest = hashlib.md5(to_hash.encode("utf8"), usedforsecurity=False) - name = new_name = digest.hexdigest()[-8:] + name = digest.hexdigest()[-8:] elif self.config["use_user_id_channel_name"]: - name = new_name = str(author.id) + name = str(author.id) elif self.config["use_timestamp_channel_name"]: - name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") + name = author.created_at.isoformat(sep="-", timespec="minutes") else: if self.config["use_nickname_channel_name"]: author_member = self.guild.get_member(author.id) - name = author_member.display_name.lower() + if author_member is None: + name = author.display_name.lower() + else: + name = author_member.display_name.lower() else: name = author.name.lower() - if force_null: - name = "null" - name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" if author.discriminator != "0": name += f"-{author.discriminator}" - new_name = name + return ensure_unique_channel_name(name, guild, excluse_channel) + + def ensure_unique_channel_name(self, name, guild, exclude_channel) -> str: counter = 1 existed = set(c.name for c in guild.text_channels if c != exclude_channel) while new_name in existed: From 59e16d4d83775e257d351c77fc47a446ba1ee9ec Mon Sep 17 00:00:00 2001 From: sebkuip Date: Sun, 16 Mar 2025 14:29:14 +0100 Subject: [PATCH 2/5] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec54e0f8a..45b4138ae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.1.3 + +### Fixed +- `use_nickname_channel_name` option would produce errors when the member was not found in the guild leading to the failure of opening modmail threads. ([PR #3368](https://github.com/modmail-dev/Modmail/pull/3368)) + # v4.1.2 ### Fixed From 0ce163814240710f22c4e021c772060598d77b6e Mon Sep 17 00:00:00 2001 From: sebkuip Date: Sun, 16 Mar 2025 14:33:07 +0100 Subject: [PATCH 3/5] Fixed naming for sanitization --- bot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index cffb2adfa9..224510e96d 100644 --- a/bot.py +++ b/bot.py @@ -1752,7 +1752,7 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): guild = self.modmail_guild if force_null: - return "null" + return ensure_unique_channel_name("null", guild, excluse_channel) else: if self.config["use_random_channel_name"]: to_hash = self.token.split(".")[-1] + str(author.id) @@ -1772,11 +1772,11 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): else: name = author.name.lower() - name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + sanitized_name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" if author.discriminator != "0": - name += f"-{author.discriminator}" + sanitized_name += f"-{author.discriminator}" - return ensure_unique_channel_name(name, guild, excluse_channel) + return ensure_unique_channel_name(sanitized_name, guild, excluse_channel) def ensure_unique_channel_name(self, name, guild, exclude_channel) -> str: counter = 1 From cc8dfea7e5a49f5d93c19fc3ad0157beef0e6d5b Mon Sep 17 00:00:00 2001 From: sebkuip Date: Sun, 16 Mar 2025 14:37:46 +0100 Subject: [PATCH 4/5] Fix formatting --- bot.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index 224510e96d..b0c46d5082 100644 --- a/bot.py +++ b/bot.py @@ -1745,7 +1745,7 @@ async def log_expiry(self): logger.info(f"Deleted {expired_logs.deleted_count} expired logs.") - def format_channel_name(self, author, exclude_channel=None, force_null=False): + def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names Placed in main bot class to be extendable to plugins""" @@ -1757,7 +1757,7 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): if self.config["use_random_channel_name"]: to_hash = self.token.split(".")[-1] + str(author.id) digest = hashlib.md5(to_hash.encode("utf8"), usedforsecurity=False) - name = digest.hexdigest()[-8:] + name = digest.hexdigest()[-8:] elif self.config["use_user_id_channel_name"]: name = str(author.id) elif self.config["use_timestamp_channel_name"]: @@ -1772,12 +1772,16 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): else: name = author.name.lower() - sanitized_name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" - if author.discriminator != "0": - sanitized_name += f"-{author.discriminator}" + sanitized_name = self.sanitize_name(name) + + if author.discriminator != "0": + sanitized_name += f"-{author.discriminator}" return ensure_unique_channel_name(sanitized_name, guild, excluse_channel) + def sanitize_name(self, name: str) -> str: + return "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + def ensure_unique_channel_name(self, name, guild, exclude_channel) -> str: counter = 1 existed = set(c.name for c in guild.text_channels if c != exclude_channel) From 58841c841ac2a19a716605721f1c91816c952474 Mon Sep 17 00:00:00 2001 From: sebkuip Date: Sun, 16 Mar 2025 14:42:38 +0100 Subject: [PATCH 5/5] Fix typo --- bot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index b0c46d5082..bf6b97bd3a 100644 --- a/bot.py +++ b/bot.py @@ -1752,7 +1752,7 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): guild = self.modmail_guild if force_null: - return ensure_unique_channel_name("null", guild, excluse_channel) + return ensure_unique_channel_name("null", guild, exclude_channel) else: if self.config["use_random_channel_name"]: to_hash = self.token.split(".")[-1] + str(author.id) @@ -1777,7 +1777,7 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): if author.discriminator != "0": sanitized_name += f"-{author.discriminator}" - return ensure_unique_channel_name(sanitized_name, guild, excluse_channel) + return ensure_unique_channel_name(sanitized_name, guild, exclude_channel) def sanitize_name(self, name: str) -> str: return "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null"