fix: serve admin media previews from telegram

This commit is contained in:
Your Name
2026-08-10 23:22:49 +05:00
parent 55f3bb51b6
commit f866a13a8a
+59 -5
View File
@@ -9,14 +9,18 @@ import re
import secrets
import time
from datetime import date, datetime, timedelta, timezone
from io import BytesIO
from pathlib import Path
from typing import Any
from urllib.parse import urlencode
from zoneinfo import ZoneInfo
import aiohttp
from aiogram import Bot
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from fastapi import FastAPI, File, Form, HTTPException, Request, UploadFile, status
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse, Response
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from loguru import logger
@@ -502,6 +506,40 @@ async def get_current_user(request: Request) -> dict | None:
return dict(row) if row else None
@app.get("/raw/media/{media_id}")
async def raw_media_preview(request: Request, media_id: int) -> Response:
if not await get_current_user(request):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
pool = await get_pool()
media = await pool.fetchrow(
"SELECT media_type, tg_file_id FROM raw_post_media WHERE id=$1",
media_id,
)
if not media or media["media_type"] != "photo" or not media["tg_file_id"]:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
local_bot_api_url = str(await fetch_setting("local_bot_api_url", settings.local_bot_api_url) or "").strip()
session = (
AiohttpSession(api=TelegramAPIServer.from_base(local_bot_api_url.rstrip("/"), is_local=True))
if local_bot_api_url
else AiohttpSession()
)
bot = Bot(token=settings.tg_bot_token, session=session)
output = BytesIO()
try:
await bot.download(str(media["tg_file_id"]), destination=output)
except Exception as exc:
logger.warning("Telegram media preview failed for media {}: {}", media_id, exc)
raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail="Media preview unavailable") from exc
finally:
await bot.session.close()
return Response(
content=output.getvalue(),
media_type="image/jpeg",
headers={"Cache-Control": "private, max-age=3600"},
)
def require_csrf(user: dict, csrf_token: str) -> None:
if not user or csrf_token != user["csrf_token"]:
raise PermissionError("bad csrf")
@@ -2680,7 +2718,11 @@ async def raw_posts(
jsonb_build_object(
'id', rpm.id,
'type', rpm.media_type,
'url', rpm.original_url,
'url', CASE
WHEN rpm.media_type='photo' AND rpm.tg_file_id IS NOT NULL
THEN '/raw/media/' || rpm.id::text
ELSE rpm.original_url
END,
'status', rpm.status,
'error', rpm.error,
'duration_sec', rpm.duration_sec
@@ -2846,7 +2888,11 @@ async def fetch_single_editor_row(pool, post_id: int):
jsonb_build_object(
'id', rpm.id,
'type', rpm.media_type,
'url', rpm.original_url,
'url', CASE
WHEN rpm.media_type='photo' AND rpm.tg_file_id IS NOT NULL
THEN '/raw/media/' || rpm.id::text
ELSE rpm.original_url
END,
'status', rpm.status,
'error', rpm.error,
'duration_sec', rpm.duration_sec
@@ -2987,7 +3033,11 @@ async def editor_feed(
jsonb_build_object(
'id', rpm.id,
'type', rpm.media_type,
'url', rpm.original_url,
'url', CASE
WHEN rpm.media_type='photo' AND rpm.tg_file_id IS NOT NULL
THEN '/raw/media/' || rpm.id::text
ELSE rpm.original_url
END,
'status', rpm.status,
'error', rpm.error,
'duration_sec', rpm.duration_sec
@@ -3327,7 +3377,11 @@ async def raw_post_detail(request: Request, post_id: int):
jsonb_build_object(
'id', rpm.id,
'type', rpm.media_type,
'url', rpm.original_url,
'url', CASE
WHEN rpm.media_type='photo' AND rpm.tg_file_id IS NOT NULL
THEN '/raw/media/' || rpm.id::text
ELSE rpm.original_url
END,
'status', rpm.status,
'error', rpm.error,
'duration_sec', rpm.duration_sec