feat: add audio file support and expand allowed upload types with new MIME mappings

Extend ALLOWED_UPLOAD_TYPES dict with audio formats (wav, flac, ogg, aac, wma, m4a), video formats (avi, mkv, flv, wmv, 3gp), document formats (doc, docx, xls, xlsx, ppt, pptx, odt, rtf), code formats (ts, java, cpp, c, h, rb, go, rs, sql, php, swift, kt), config formats (cfg, ini, log), archive formats (tar, gz, rar, 7z), and additional web formats (html, json, xml, yaml, yml, toml, sh, bat, svg). Add corresponding MIME_TO_EXT reverse mappings. Implement audio element rendering in ContentRenderer.js with audioExtRe regex and createAudioElement method. Add gallery-audio CSS class for audio player styling in attachments.css and media.css. Update _attachment_display.html and _media_gallery.html templates to render audio controls for is_audio attachments.
This commit is contained in:
2026-06-15 15:08:10 +00:00
parent e1874f9b6a
commit 6b08761af5
6 changed files with 126 additions and 0 deletions
+97
View File
@@ -50,6 +50,54 @@ ALLOWED_UPLOAD_TYPES = {
".js": "text/javascript",
".css": "text/css",
".md": "text/markdown",
".wav": "audio/wav",
".flac": "audio/flac",
".ogg": "audio/ogg",
".aac": "audio/aac",
".wma": "audio/x-ms-wma",
".m4a": "audio/mp4",
".avi": "video/x-msvideo",
".mkv": "video/x-matroska",
".flv": "video/x-flv",
".wmv": "video/x-ms-wmv",
".3gp": "video/3gpp",
".csv": "text/csv",
".doc": "application/msword",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls": "application/vnd.ms-excel",
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".ppt": "application/vnd.ms-powerpoint",
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".odt": "application/vnd.oasis.opendocument.text",
".rtf": "application/rtf",
".html": "text/html",
".json": "application/json",
".xml": "application/xml",
".yaml": "text/yaml",
".yml": "text/yaml",
".toml": "text/x-toml",
".sh": "text/x-sh",
".bat": "text/x-bat",
".ts": "text/typescript",
".java": "text/x-java",
".cpp": "text/x-c++",
".c": "text/x-c",
".h": "text/x-c-header",
".rb": "text/x-ruby",
".go": "text/x-go",
".rs": "text/x-rust",
".sql": "text/x-sql",
".php": "text/x-php",
".swift": "text/x-swift",
".kt": "text/x-kotlin",
".cfg": "text/x-config",
".ini": "text/x-config",
".log": "text/plain",
".svg": "image/svg+xml",
".tar": "application/x-tar",
".gz": "application/gzip",
".rar": "application/vnd.rar",
".7z": "application/x-7z-compressed",
}
MIME_TO_EXT = {
@@ -69,6 +117,51 @@ MIME_TO_EXT = {
"audio/mpeg": ".mp3",
"text/plain": ".txt",
"text/markdown": ".md",
"audio/wav": ".wav",
"audio/flac": ".flac",
"audio/ogg": ".ogg",
"audio/aac": ".aac",
"audio/x-ms-wma": ".wma",
"audio/mp4": ".m4a",
"video/x-msvideo": ".avi",
"video/x-matroska": ".mkv",
"video/x-flv": ".flv",
"video/x-ms-wmv": ".wmv",
"video/3gpp": ".3gp",
"text/csv": ".csv",
"application/msword": ".doc",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
"application/vnd.ms-excel": ".xls",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
"application/vnd.ms-powerpoint": ".ppt",
"application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
"application/vnd.oasis.opendocument.text": ".odt",
"application/rtf": ".rtf",
"text/html": ".html",
"application/json": ".json",
"application/xml": ".xml",
"text/yaml": ".yaml",
"text/x-toml": ".toml",
"text/x-sh": ".sh",
"text/x-bat": ".bat",
"text/typescript": ".ts",
"text/x-java": ".java",
"text/x-c++": ".cpp",
"text/x-c": ".c",
"text/x-c-header": ".h",
"text/x-ruby": ".rb",
"text/x-go": ".go",
"text/x-rust": ".rs",
"text/x-sql": ".sql",
"text/x-php": ".php",
"text/x-swift": ".swift",
"text/x-kotlin": ".kt",
"text/x-config": ".cfg",
"image/svg+xml": ".svg",
"application/x-tar": ".tar",
"application/gzip": ".gz",
"application/vnd.rar": ".rar",
"application/x-7z-compressed": ".7z",
}
FILE_ICONS = {
@@ -205,6 +298,8 @@ def store_attachment(file_bytes, original_filename, user_uid):
if ext not in (".gif",):
thumbnail = _generate_thumbnail(file_bytes, file_dir / f"{uid}_thumb.jpg")
is_audio = mime.startswith("audio/")
get_table("attachments").insert(
{
"uid": uid,
@@ -237,6 +332,7 @@ def store_attachment(file_bytes, original_filename, user_uid):
"has_thumbnail": thumbnail is not None,
"is_image": is_image,
"is_video": mime.startswith("video/"),
"is_audio": is_audio,
}
@@ -521,6 +617,7 @@ def _row_to_attachment(row):
"has_thumbnail": bool(row.get("has_thumbnail")),
"is_image": row.get("mime_type", "").startswith("image/"),
"is_video": row.get("mime_type", "").startswith("video/"),
"is_audio": row.get("mime_type", "").startswith("audio/"),
"target_type": row.get("target_type", ""),
"target_uid": row.get("target_uid", ""),
"created_at": row.get("created_at", ""),