fix(api,frontend): render files by name without fetching, previewable share links
This commit is contained in:
1 parent
ef739838a5
commit
e833de245a
13 files changed
+348
-45
No files matched your search
@@ -29,6 +29,42 @@ _KIND_EXTENSIONS = {
|
||||
"voice": ".ogg",
|
||||
}
|
||||
|
||||
_EXTENSION_MIMES = {
|
||||
".flac": "audio/flac",
|
||||
".gif": "image/gif",
|
||||
".heic": "image/heic",
|
||||
".jpeg": "image/jpeg",
|
||||
".jpg": "image/jpeg",
|
||||
".m4a": "audio/mp4",
|
||||
".mov": "video/quicktime",
|
||||
".mp3": "audio/mpeg",
|
||||
".mp4": "video/mp4",
|
||||
".ogg": "audio/ogg",
|
||||
".pdf": "application/pdf",
|
||||
".png": "image/png",
|
||||
".svg": "image/svg+xml",
|
||||
".txt": "text/plain",
|
||||
".wav": "audio/wav",
|
||||
".webm": "video/webm",
|
||||
".webp": "image/webp",
|
||||
}
|
||||
|
||||
_KIND_MIMES = {
|
||||
"animation": "video/mp4",
|
||||
"gif": "video/mp4",
|
||||
"photo": "image/jpeg",
|
||||
"video": "video/mp4",
|
||||
"video_note": "video/mp4",
|
||||
"voice": "audio/ogg",
|
||||
}
|
||||
|
||||
_GENERIC_MIMES = {
|
||||
"application/octet-stream",
|
||||
"application/binary",
|
||||
"binary/octet-stream",
|
||||
"",
|
||||
}
|
||||
|
||||
_INLINE_MIME_PREFIXES = ("image/", "video/", "audio/", "text/")
|
||||
_INLINE_MIMES = {"application/pdf", "application/json"}
|
||||
|
||||
@@ -57,6 +93,45 @@ _PREVIEW_AGENTS = (
|
||||
"python-requests",
|
||||
)
|
||||
|
||||
_TRANSLIT = {
|
||||
"а": "a",
|
||||
"б": "b",
|
||||
"в": "v",
|
||||
"г": "g",
|
||||
"д": "d",
|
||||
"е": "e",
|
||||
"ё": "e",
|
||||
"ж": "zh",
|
||||
"з": "z",
|
||||
"и": "i",
|
||||
"й": "y",
|
||||
"к": "k",
|
||||
"л": "l",
|
||||
"м": "m",
|
||||
"н": "n",
|
||||
"о": "o",
|
||||
"п": "p",
|
||||
"р": "r",
|
||||
"с": "s",
|
||||
"т": "t",
|
||||
"у": "u",
|
||||
"ф": "f",
|
||||
"х": "h",
|
||||
"ц": "c",
|
||||
"ч": "ch",
|
||||
"ш": "sh",
|
||||
"щ": "sch",
|
||||
"ъ": "",
|
||||
"ы": "y",
|
||||
"ь": "",
|
||||
"э": "e",
|
||||
"ю": "yu",
|
||||
"я": "ya",
|
||||
}
|
||||
|
||||
_URL_UNSAFE = re.compile(r"[^A-Za-z0-9._-]+")
|
||||
_URL_REPEATS = re.compile(r"_{2,}")
|
||||
|
||||
_UNSAFE_CHARS = re.compile(r'[\\/:*?"<>|\x00-\x1f]+')
|
||||
_SPACES = re.compile(r"\s+")
|
||||
_NAME_LIMIT = 120
|
||||
@@ -86,6 +161,16 @@ def sanitize_name(name: str) -> str:
|
||||
return cleaned or "file"
|
||||
|
||||
|
||||
def url_slug(file_name: str) -> str:
|
||||
lowered = "".join(
|
||||
_TRANSLIT.get(ch, _TRANSLIT.get(ch.lower(), ch)) for ch in file_name
|
||||
)
|
||||
slug = _URL_REPEATS.sub("_", _URL_UNSAFE.sub("_", lowered)).strip("_.")
|
||||
if not slug:
|
||||
return "file"
|
||||
return slug[:_NAME_LIMIT]
|
||||
|
||||
|
||||
def media_file_name(
|
||||
kind: str | None, mime: str | None, message_id: int, original: str | None = None
|
||||
) -> str:
|
||||
@@ -99,6 +184,18 @@ def story_file_name(peer_id: int, story_id: int, media_kind: str | None) -> str:
|
||||
return f"story_{peer_id}_{story_id}{extension_for(media_kind or 'photo', None)}"
|
||||
|
||||
|
||||
def resolve_mime(
|
||||
kind: str | None, mime: str | None, file_name: str | None = None
|
||||
) -> str:
|
||||
if mime and mime.lower() not in _GENERIC_MIMES:
|
||||
return mime
|
||||
if file_name and "." in file_name:
|
||||
by_extension = _EXTENSION_MIMES.get(f".{file_name.rsplit('.', 1)[1].lower()}")
|
||||
if by_extension:
|
||||
return by_extension
|
||||
return _KIND_MIMES.get(kind or "", mime or "application/octet-stream")
|
||||
|
||||
|
||||
def is_inline_mime(mime: str | None) -> bool:
|
||||
if not mime:
|
||||
return False
|
||||
|
||||
Reference in new issue
Block a user