diff options
author | 2022-12-20 17:22:57 +0800 | |
---|---|---|
committer | 2022-12-20 17:22:57 +0800 | |
commit | 2aaf161b8d8e4d89a57fca43df2fc50788a5f109 (patch) | |
tree | 36e24d55caf00f03f1e39e581da3c343903707d3 | |
parent | Add markdown mention escape for file error str (diff) |
Add discord file name normalization
-rw-r--r-- | bot/exts/utils/snekbox/_io.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/bot/exts/utils/snekbox/_io.py b/bot/exts/utils/snekbox/_io.py index 3ec5ff00a..88f10e4a2 100644 --- a/bot/exts/utils/snekbox/_io.py +++ b/bot/exts/utils/snekbox/_io.py @@ -6,6 +6,7 @@ from dataclasses import dataclass from io import BytesIO from pathlib import Path +import regex from discord import File # Note discord bot upload limit is 8 MiB per file, @@ -16,6 +17,14 @@ FILE_SIZE_LIMIT = 8 * 1024 * 1024 FILE_COUNT_LIMIT = 10 +# ANSI escape sequences +RE_ANSI = regex.compile(r"\x1b[^m]*m") +# Characters with a leading backslash +RE_BACKSLASH = regex.compile(r"\\.") +# Discord disallowed file name characters +RE_DISCORD_FILE_NAME_DISALLOWED = regex.compile(r"[^a-zA-Z0-9._-]+") + + def sizeof_fmt(num: int | float, suffix: str = "B") -> str: """Return a human-readable file size.""" num = float(num) @@ -28,6 +37,18 @@ def sizeof_fmt(num: int | float, suffix: str = "B") -> str: return f"{num_str} Yi{suffix}" +def normalize_discord_file_name(name: str) -> str: + """Return a normalized valid discord file name.""" + # Discord file names only allow A-Z, a-z, 0-9, underscores, dashes, and dots + # https://discord.com/developers/docs/reference#uploading-files + # Server will remove any other characters, but we'll get a 400 error for \ escaped chars + name = RE_ANSI.sub("_", name) + name = RE_BACKSLASH.sub("_", name) + # Replace any disallowed character with an underscore + name = RE_DISCORD_FILE_NAME_DISALLOWED.sub("_", name) + return name + + @dataclass class FileAttachment: """File Attachment from Snekbox eval.""" @@ -68,4 +89,5 @@ class FileAttachment: def to_file(self) -> File: """Convert to a discord.File.""" name = Path(self.path).name + name = normalize_discord_file_name(name) return File(BytesIO(self.content), filename=name) |