FEAT: Integrated Document Engine with WebP optimization, Thumbnail generation and Hybrid (NAS/SSD) storage logic

This commit is contained in:
2026-02-07 22:16:03 +00:00
parent e370ca3021
commit 4e14d57bf6
20 changed files with 657 additions and 607 deletions

View File

@@ -0,0 +1,82 @@
import os
import shutil
import time
from PIL import Image
from uuid import uuid4
from fastapi import UploadFile, BackgroundTasks
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.document import Document
class DocumentService:
@staticmethod
def _clean_temp(path: str):
"""30 perc után törli az ideiglenes fájlt (opcionális, ha maradunk a puffer mellett)"""
time.sleep(1800)
if os.path.exists(path):
os.remove(path)
@staticmethod
async def process_upload(
file: UploadFile,
parent_type: str,
parent_id: str,
db: AsyncSession,
background_tasks: BackgroundTasks
):
file_uuid = str(uuid4())
# 1. Könyvtárstruktúra meghatározása
temp_dir = "/app/temp/uploads"
nas_vault_dir = f"/mnt/nas/app_data/organizations/{parent_id}/vault"
ssd_thumb_dir = f"/app/static/previews/organizations/{parent_id}"
for d in [temp_dir, nas_vault_dir, ssd_thumb_dir]:
os.makedirs(d, exist_ok=True)
# 2. Mentés a TEMP-be
temp_path = os.path.join(temp_dir, f"{file_uuid}_{file.filename}")
content = await file.read()
with open(temp_path, "wb") as f:
f.write(content)
# 3. Képfeldolgozás (Pillow)
img = Image.open(temp_path)
# A) Thumbnail generálás (300px WebP az SSD-re)
thumb_filename = f"{file_uuid}_thumb.webp"
thumb_path = os.path.join(ssd_thumb_dir, thumb_filename)
thumb_img = img.copy()
thumb_img.thumbnail((300, 300))
thumb_img.save(thumb_path, "WEBP", quality=80)
# B) Nagy kép optimalizálás (Max 1600px WebP a NAS-ra)
vault_filename = f"{file_uuid}.webp"
vault_path = os.path.join(nas_vault_dir, vault_filename)
if img.width > 1600:
ratio = 1600 / float(img.width)
new_height = int(float(img.height) * float(ratio))
img = img.resize((1600, new_height), Image.Resampling.LANCZOS)
img.save(vault_path, "WEBP", quality=85)
# 4. Adatbázis rögzítés
new_doc = Document(
id=uuid4(),
parent_type=parent_type,
parent_id=parent_id,
original_name=file.filename,
file_hash=file_uuid,
file_size=os.path.getsize(vault_path),
has_thumbnail=True,
thumbnail_path=f"/static/previews/organizations/{parent_id}/{thumb_filename}"
)
db.add(new_doc)
await db.commit()
# 5. Puffer törlés ütemezése (30 perc)
# background_tasks.add_task(DocumentService._clean_temp, temp_path)
# MVP-ben töröljük azonnal, ha már a NAS-on van a biztonságos másolat
os.remove(temp_path)
return new_doc