Rebase onto upstream (a4d95fd)
#12
@@ -0,0 +1,47 @@
|
||||
"""Media handling utilities for Telegram channel."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import mimetypes
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import magic
|
||||
HAS_MAGIC = True
|
||||
except ImportError:
|
||||
HAS_MAGIC = False
|
||||
|
||||
|
||||
def detect_mime(path: str, content: bytes | None = None) -> str:
|
||||
"""
|
||||
Detect MIME type of media file.
|
||||
|
||||
Priority:
|
||||
1. python-magic sniff (if available and content provided)
|
||||
2. Extension-based lookup
|
||||
3. Fallback to application/octet-stream
|
||||
|
||||
Args:
|
||||
path: File path (used for extension detection)
|
||||
content: Optional file content bytes for magic sniffing
|
||||
|
||||
Returns:
|
||||
MIME type string (e.g., "image/jpeg")
|
||||
"""
|
||||
# Try magic detection first if we have content
|
||||
if HAS_MAGIC and content:
|
||||
try:
|
||||
mime = magic.from_buffer(content, mime=True)
|
||||
# Avoid generic types if we can be more specific from extension
|
||||
if mime and mime != "application/octet-stream":
|
||||
return mime
|
||||
except Exception:
|
||||
pass # Fall through to extension-based detection
|
||||
|
||||
# Extension-based detection
|
||||
mime_type, _ = mimetypes.guess_type(path)
|
||||
if mime_type:
|
||||
return mime_type
|
||||
|
||||
# Fallback
|
||||
return "application/octet-stream"
|
||||
@@ -0,0 +1,42 @@
|
||||
"""Tests for Telegram media handling."""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def test_detect_mime_from_jpeg():
|
||||
"""Test MIME detection for JPEG images."""
|
||||
from nanobot.channels.telegram_media import detect_mime
|
||||
|
||||
# Create minimal JPEG bytes (FF D8 FF = JPEG magic bytes)
|
||||
jpeg_bytes = b'\xff\xd8\xff\xe0\x00\x10JFIF'
|
||||
|
||||
mime = detect_mime("test.jpg", jpeg_bytes)
|
||||
assert mime == "image/jpeg"
|
||||
|
||||
|
||||
def test_detect_mime_from_png():
|
||||
"""Test MIME detection for PNG images."""
|
||||
from nanobot.channels.telegram_media import detect_mime
|
||||
|
||||
# PNG magic bytes
|
||||
png_bytes = b'\x89PNG\r\n\x1a\n'
|
||||
|
||||
mime = detect_mime("test.png", png_bytes)
|
||||
assert mime == "image/png"
|
||||
|
||||
|
||||
def test_detect_mime_from_extension_fallback():
|
||||
"""Test MIME detection falls back to extension when no content provided."""
|
||||
from nanobot.channels.telegram_media import detect_mime
|
||||
|
||||
mime = detect_mime("video.mp4", None)
|
||||
assert mime == "video/mp4"
|
||||
|
||||
|
||||
def test_detect_mime_unknown():
|
||||
"""Test MIME detection returns generic type for unknown files."""
|
||||
from nanobot.channels.telegram_media import detect_mime
|
||||
|
||||
mime = detect_mime("unknown.xyz", None)
|
||||
assert mime == "application/octet-stream"
|
||||
Reference in New Issue
Block a user