Spaces:
Running
Running
SilverElixir commited on
Commit ·
4980a0b
1
Parent(s): b7295f0
Fix platform-dependent mimetypes guess (x-msvideo on Linux): canonicalize to supported mimes
Browse files- lumen_media.py +9 -2
- test_bot_state.py +5 -1
lumen_media.py
CHANGED
|
@@ -51,12 +51,19 @@ def _is_gemini_supported_mime(mime: str) -> bool:
|
|
| 51 |
return False
|
| 52 |
|
| 53 |
def _sanitize_mime_type(file_path: str | None, mime: str | None, default_fallback: str = "application/octet-stream") -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
m = (mime or "").strip().lower()
|
| 55 |
if not m or m in ("application/octet-stream", "binary/oct-stream", "application/x-binary", "octet/stream"):
|
| 56 |
if file_path:
|
| 57 |
guessed, _ = mimetypes.guess_type(file_path)
|
| 58 |
if guessed:
|
| 59 |
-
return guessed.lower()
|
| 60 |
if file_path:
|
| 61 |
ext = Path(file_path).suffix.lower()
|
| 62 |
ext_map = {
|
|
@@ -93,7 +100,7 @@ def _sanitize_mime_type(file_path: str | None, mime: str | None, default_fallbac
|
|
| 93 |
return "audio/ogg"
|
| 94 |
if m == "video/quicktime":
|
| 95 |
return "video/quicktime"
|
| 96 |
-
return m
|
| 97 |
|
| 98 |
def _media_file_id_and_mime(source: Any) -> tuple[str, str, str]:
|
| 99 |
file_id, mime, filename = "", "", ""
|
|
|
|
| 51 |
return False
|
| 52 |
|
| 53 |
def _sanitize_mime_type(file_path: str | None, mime: str | None, default_fallback: str = "application/octet-stream") -> str:
|
| 54 |
+
# mimetypes.guess_type зависит от платформы (/etc/mime.types на Linux,
|
| 55 |
+
# реестр Windows): один и тот же .avi даёт video/x-msvideo там и None тут.
|
| 56 |
+
# Каноникализируем известные нестандартные варианты в поддерживаемые mime.
|
| 57 |
+
canonical = {
|
| 58 |
+
"video/x-msvideo": "video/avi",
|
| 59 |
+
"video/x-m4v": "video/mp4",
|
| 60 |
+
}
|
| 61 |
m = (mime or "").strip().lower()
|
| 62 |
if not m or m in ("application/octet-stream", "binary/oct-stream", "application/x-binary", "octet/stream"):
|
| 63 |
if file_path:
|
| 64 |
guessed, _ = mimetypes.guess_type(file_path)
|
| 65 |
if guessed:
|
| 66 |
+
return canonical.get(guessed.lower(), guessed.lower())
|
| 67 |
if file_path:
|
| 68 |
ext = Path(file_path).suffix.lower()
|
| 69 |
ext_map = {
|
|
|
|
| 100 |
return "audio/ogg"
|
| 101 |
if m == "video/quicktime":
|
| 102 |
return "video/quicktime"
|
| 103 |
+
return canonical.get(m, m)
|
| 104 |
|
| 105 |
def _media_file_id_and_mime(source: Any) -> tuple[str, str, str]:
|
| 106 |
file_id, mime, filename = "", "", ""
|
test_bot_state.py
CHANGED
|
@@ -74,9 +74,13 @@ def test_sanitize_mime_type_audio_ogg_passthrough():
|
|
| 74 |
|
| 75 |
def test_sanitize_mime_type_maps_containers_to_supported_mimes():
|
| 76 |
# .m4v/.avi раньше давали video/x-m4v/x-msvideo, которые
|
| 77 |
-
# _is_gemini_supported_mime тут же отвергал.
|
|
|
|
|
|
|
| 78 |
assert bot._sanitize_mime_type("x.m4v", "application/octet-stream") == "video/mp4"
|
| 79 |
assert bot._sanitize_mime_type("x.avi", "application/octet-stream") == "video/avi"
|
|
|
|
|
|
|
| 80 |
|
| 81 |
|
| 82 |
def test_mime_suffix_maps_audio_video_subtypes_honestly():
|
|
|
|
| 74 |
|
| 75 |
def test_sanitize_mime_type_maps_containers_to_supported_mimes():
|
| 76 |
# .m4v/.avi раньше давали video/x-m4v/x-msvideo, которые
|
| 77 |
+
# _is_gemini_supported_mime тут же отвергал. На Linux mimetypes
|
| 78 |
+
# угадывает x-msvideo сам (на Windows — нет), поэтому нормализация
|
| 79 |
+
# проверяется и детерминированно, без оглядки на платформу.
|
| 80 |
assert bot._sanitize_mime_type("x.m4v", "application/octet-stream") == "video/mp4"
|
| 81 |
assert bot._sanitize_mime_type("x.avi", "application/octet-stream") == "video/avi"
|
| 82 |
+
assert bot._sanitize_mime_type(None, "video/x-msvideo") == "video/avi"
|
| 83 |
+
assert bot._sanitize_mime_type(None, "video/x-m4v") == "video/mp4"
|
| 84 |
|
| 85 |
|
| 86 |
def test_mime_suffix_maps_audio_video_subtypes_honestly():
|