fix: serve admin media previews from telegram
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user