df
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
This commit is contained in:
@@ -15,6 +15,115 @@ from ProviderCore.base import Provider
|
||||
_MATRIX_INIT_CHECK_CACHE: Dict[str, Tuple[bool, Optional[str]]] = {}
|
||||
|
||||
|
||||
def _sniff_mime_from_header(path: Path) -> Optional[str]:
|
||||
"""Best-effort MIME sniffing from file headers.
|
||||
|
||||
Used when the file has no/unknown extension (common for exported/temp files).
|
||||
Keeps dependencies to stdlib only.
|
||||
"""
|
||||
try:
|
||||
if not path.exists() or not path.is_file():
|
||||
return None
|
||||
with open(path, "rb") as handle:
|
||||
header = handle.read(512)
|
||||
if not header:
|
||||
return None
|
||||
|
||||
# Images
|
||||
if header.startswith(b"\xFF\xD8\xFF"):
|
||||
return "image/jpeg"
|
||||
if header.startswith(b"\x89PNG\r\n\x1a\n"):
|
||||
return "image/png"
|
||||
if header.startswith(b"GIF87a") or header.startswith(b"GIF89a"):
|
||||
return "image/gif"
|
||||
if header.startswith(b"BM"):
|
||||
return "image/bmp"
|
||||
if header.startswith(b"RIFF") and len(header) >= 12 and header[8:12] == b"WEBP":
|
||||
return "image/webp"
|
||||
|
||||
# Audio
|
||||
if header.startswith(b"fLaC"):
|
||||
return "audio/flac"
|
||||
if header.startswith(b"OggS"):
|
||||
# Could be audio or video; treat as audio unless extension suggests video.
|
||||
return "audio/ogg"
|
||||
if header.startswith(b"ID3"):
|
||||
return "audio/mpeg"
|
||||
if len(header) >= 2 and header[0] == 0xFF and (header[1] & 0xE0) == 0xE0:
|
||||
return "audio/mpeg"
|
||||
if header.startswith(b"RIFF") and len(header) >= 12 and header[8:12] == b"WAVE":
|
||||
return "audio/wav"
|
||||
|
||||
# Video
|
||||
if header.startswith(b"RIFF") and len(header) >= 12 and header[8:12] == b"AVI ":
|
||||
return "video/x-msvideo"
|
||||
if header.startswith(b"\x1A\x45\xDF\xA3"):
|
||||
# EBML container: Matroska/WebM.
|
||||
return "video/x-matroska"
|
||||
if len(header) >= 12 and header[4:8] == b"ftyp":
|
||||
# ISO BMFF: mp4/mov/m4a. Default to mp4; extension can refine.
|
||||
return "video/mp4"
|
||||
# MPEG-TS / M2TS (sync byte every 188 bytes)
|
||||
try:
|
||||
if path.stat().st_size >= 188 * 2 and header[0] == 0x47:
|
||||
with open(path, "rb") as handle:
|
||||
handle.seek(188)
|
||||
b = handle.read(1)
|
||||
if b == b"\x47":
|
||||
return "video/mp2t"
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _classify_matrix_upload(path: Path, *, explicit_mime_type: Optional[str] = None) -> Tuple[str, str]:
|
||||
"""Return (mime_type, msgtype) for Matrix uploads."""
|
||||
mime_type = str(explicit_mime_type or "").strip() or None
|
||||
|
||||
if not mime_type:
|
||||
# `mimetypes.guess_type` expects a string/URL; Path can return None on some platforms.
|
||||
mime_type, _ = mimetypes.guess_type(str(path))
|
||||
|
||||
if not mime_type:
|
||||
mime_type = _sniff_mime_from_header(path)
|
||||
|
||||
# Refinements based on extension for ambiguous containers.
|
||||
ext = path.suffix.lower()
|
||||
if ext in {".m4a", ".aac"}:
|
||||
mime_type = mime_type or "audio/mp4"
|
||||
if ext in {".mkv", ".webm"}:
|
||||
mime_type = mime_type or "video/x-matroska"
|
||||
if ext in {".ogv"}:
|
||||
mime_type = mime_type or "video/ogg"
|
||||
|
||||
msgtype = "m.file"
|
||||
if mime_type:
|
||||
mt = mime_type.casefold()
|
||||
if mt.startswith("image/"):
|
||||
msgtype = "m.image"
|
||||
elif mt.startswith("audio/"):
|
||||
msgtype = "m.audio"
|
||||
elif mt.startswith("video/"):
|
||||
msgtype = "m.video"
|
||||
|
||||
# Final fallback for unknown MIME types.
|
||||
if msgtype == "m.file":
|
||||
audio_exts = {".mp3", ".flac", ".wav", ".m4a", ".aac", ".ogg", ".opus", ".wma", ".mka", ".alac"}
|
||||
video_exts = {".mp4", ".mkv", ".webm", ".mov", ".avi", ".flv", ".mpg", ".mpeg", ".ts", ".m4v", ".wmv", ".m2ts", ".mts", ".3gp", ".ogv"}
|
||||
image_exts = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"}
|
||||
if ext in audio_exts:
|
||||
msgtype = "m.audio"
|
||||
elif ext in video_exts:
|
||||
msgtype = "m.video"
|
||||
elif ext in image_exts:
|
||||
msgtype = "m.image"
|
||||
|
||||
return (mime_type or "application/octet-stream"), msgtype
|
||||
|
||||
|
||||
def _normalize_homeserver(value: str) -> str:
|
||||
text = str(value or "").strip()
|
||||
if not text:
|
||||
@@ -189,9 +298,8 @@ class Matrix(Provider):
|
||||
"Content-Type": "application/octet-stream",
|
||||
}
|
||||
|
||||
mime_type, _ = mimetypes.guess_type(path)
|
||||
if mime_type:
|
||||
headers["Content-Type"] = mime_type
|
||||
mime_type, msgtype = _classify_matrix_upload(path, explicit_mime_type=kwargs.get("mime_type"))
|
||||
headers["Content-Type"] = mime_type
|
||||
|
||||
filename = path.name
|
||||
|
||||
@@ -222,19 +330,6 @@ class Matrix(Provider):
|
||||
except Exception:
|
||||
download_url_for_store = ""
|
||||
|
||||
# Determine message type
|
||||
msgtype = "m.file"
|
||||
ext = path.suffix.lower()
|
||||
audio_exts = {".mp3", ".flac", ".wav", ".m4a", ".aac", ".ogg", ".opus", ".wma", ".mka", ".alac"}
|
||||
video_exts = {".mp4", ".mkv", ".webm", ".mov", ".avi", ".flv", ".mpg", ".mpeg", ".ts", ".m4v", ".wmv"}
|
||||
image_exts = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"}
|
||||
if ext in audio_exts:
|
||||
msgtype = "m.audio"
|
||||
elif ext in video_exts:
|
||||
msgtype = "m.video"
|
||||
elif ext in image_exts:
|
||||
msgtype = "m.image"
|
||||
|
||||
info = {"mimetype": mime_type, "size": path.stat().st_size}
|
||||
payload = {"msgtype": msgtype, "body": filename, "url": content_uri, "info": info}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user