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