mirror of
https://github.com/flibusta-apps/telegram_files_cache_server.git
synced 2025-12-06 14:45:36 +01:00
Add file downloading
This commit is contained in:
@@ -16,4 +16,4 @@ class CachedFile(ormar.Model):
|
||||
id: int = ormar.Integer(primary_key=True) # type: ignore
|
||||
object_id: int = ormar.Integer() # type: ignore
|
||||
object_type: str = ormar.String(max_length=8) # type: ignore
|
||||
data = ormar.JSON()
|
||||
data: dict = ormar.JSON() # type: ignore
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Optional
|
||||
from app.models import CachedFile
|
||||
from app.services.caption_getter import get_caption
|
||||
from app.services.downloader import download
|
||||
from app.services.files_uploader import upload_file
|
||||
from app.services.files_client import upload_file
|
||||
from app.services.library_client import get_books, get_book, Book
|
||||
|
||||
|
||||
|
||||
@@ -25,3 +25,19 @@ async def download(
|
||||
name = content_disposition.replace("attachment; filename=", "")
|
||||
|
||||
return response.content, name
|
||||
|
||||
|
||||
async def get_filename(book_id: int, file_type: str) -> Optional[str]:
|
||||
headers = {"Authorization": env_config.DOWNLOADER_API_KEY}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"{env_config.DOWNLOADER_URL}/filename/{book_id}/{file_type}",
|
||||
headers=headers,
|
||||
timeout=5 * 60,
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return None
|
||||
|
||||
return response.text
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
import httpx
|
||||
from pydantic import BaseModel
|
||||
@@ -29,3 +30,19 @@ async def upload_file(content: bytes, filename: str, caption: str) -> UploadedFi
|
||||
)
|
||||
|
||||
return UploadedFile.parse_obj(response.json())
|
||||
|
||||
|
||||
async def download_file(chat_id: int, message_id: int) -> Optional[bytes]:
|
||||
headers = {"Authorization": env_config.FILES_SERVER_API_KEY}
|
||||
|
||||
async with httpx.AsyncClient(timeout=60) as client:
|
||||
response = await client.get(
|
||||
f"{env_config.FILES_SERVER_URL}"
|
||||
f"/api/v1/files/download_by_message/{chat_id}/{message_id}",
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return None
|
||||
|
||||
return response.content
|
||||
@@ -1,11 +1,15 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks, status
|
||||
|
||||
from starlette.responses import Response
|
||||
|
||||
from asyncpg import exceptions
|
||||
|
||||
from app.depends import check_token
|
||||
from app.models import CachedFile as CachedFileDB
|
||||
from app.serializers import CachedFile, CreateCachedFile
|
||||
from app.services.cache_updater import CacheUpdater
|
||||
from app.services.downloader import get_filename
|
||||
from app.services.files_client import download_file as download_file_from_cache
|
||||
|
||||
|
||||
router = APIRouter(
|
||||
@@ -28,6 +32,34 @@ async def get_cached_file(object_id: int, object_type: str):
|
||||
return cached_file
|
||||
|
||||
|
||||
@router.get("/download/{object_id}/{object_type}")
|
||||
async def download_cached_file(object_id: int, object_type: str):
|
||||
cached_file = await CachedFileDB.objects.get_or_none(
|
||||
object_id=object_id, object_type=object_type
|
||||
)
|
||||
|
||||
if not cached_file:
|
||||
cached_file = await CacheUpdater.cache_file(object_id, object_type)
|
||||
|
||||
if not cached_file:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
cache_data = cached_file.data
|
||||
|
||||
data = await download_file_from_cache(
|
||||
cache_data["chat_id"], cache_data["message_id"]
|
||||
)
|
||||
|
||||
if data is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
filename = await get_filename(object_id, object_type)
|
||||
|
||||
return Response(
|
||||
data, headers={"Content-Disposition": f"attachment; filename={filename}"}
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/{object_id}/{object_type}", response_model=CachedFile)
|
||||
async def delete_cached_file(object_id: int, object_type: str):
|
||||
cached_file = await CachedFileDB.objects.get(
|
||||
|
||||
Reference in New Issue
Block a user