feat(userbot,api,frontend): file links, media downloads, story hold-pause, drop scheduled dupes
This commit is contained in:
1 parent
683b9a31a3
commit
3e08698b62
38 files changed
+2889
-134
No files matched your search
@@ -6,6 +6,7 @@ from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from utils.cache import DAY_HEADERS, IMMUTABLE_HEADERS
|
||||
from utils.files import content_disposition, media_file_name
|
||||
from utils.read.media import (
|
||||
get_media,
|
||||
get_media_version,
|
||||
@@ -17,6 +18,15 @@ from utils.storage import ContentAddressedStorage
|
||||
|
||||
router = APIRouter(prefix="/api/media", tags=["media"], route_class=DishkaRoute)
|
||||
|
||||
Download = Annotated[bool, Query()]
|
||||
|
||||
|
||||
def _attachment(headers: dict[str, str], file_name: str) -> dict[str, str]:
|
||||
return {
|
||||
**headers,
|
||||
"Content-Disposition": content_disposition(file_name, attachment=True),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{media_id}/meta")
|
||||
async def media_meta(pool: FromDishka[asyncpg.Pool], media_id: int) -> MediaView:
|
||||
@@ -41,14 +51,20 @@ async def serve_media_version(
|
||||
pool: FromDishka[asyncpg.Pool],
|
||||
storage: FromDishka[ContentAddressedStorage],
|
||||
version_id: int,
|
||||
download: Download = False,
|
||||
) -> FileResponse:
|
||||
version = await get_media_version(pool, version_id)
|
||||
if version is None:
|
||||
raise HTTPException(status_code=404, detail="media version not found")
|
||||
headers = IMMUTABLE_HEADERS
|
||||
if download:
|
||||
headers = _attachment(
|
||||
headers, media_file_name(version.kind, version.mime, version_id)
|
||||
)
|
||||
return FileResponse(
|
||||
storage.url(version.storage_key),
|
||||
media_type=version.mime or "application/octet-stream",
|
||||
headers=IMMUTABLE_HEADERS,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
|
||||
@@ -70,6 +86,7 @@ async def serve_media(
|
||||
pool: FromDishka[asyncpg.Pool],
|
||||
storage: FromDishka[ContentAddressedStorage],
|
||||
media_id: int,
|
||||
download: Download = False,
|
||||
) -> FileResponse:
|
||||
media = await get_media(pool, media_id)
|
||||
if media is None:
|
||||
@@ -79,8 +96,11 @@ async def serve_media(
|
||||
status_code=409,
|
||||
detail="media not downloaded; enqueue fetch via POST /api/media/fetch",
|
||||
)
|
||||
headers = DAY_HEADERS
|
||||
if download:
|
||||
headers = _attachment(headers, media.file_name or f"media_{media_id}")
|
||||
return FileResponse(
|
||||
storage.url(media.storage_key),
|
||||
media_type=media.mime or "application/octet-stream",
|
||||
headers=DAY_HEADERS,
|
||||
headers=headers,
|
||||
)
|
||||
Reference in new issue
Block a user