from __future__ import annotations from app.core.ids import new_id from app.models.entities import PreviewArtifact from app.repositories.file_repository import FileRepository from app.repositories.preview_artifact_repository import PreviewArtifactRepository class PreviewService: def __init__(self, session) -> None: self.session = session self.file_repository = FileRepository(session) self.preview_artifact_repository = PreviewArtifactRepository(session) async def get_preview_artifacts_for_file(self, file_id: str) -> list[PreviewArtifact]: file_entry = await self.file_repository.get_by_id(file_id) if file_entry is None or file_entry.current_version_id is None: return [] return await self.preview_artifact_repository.list_by_file_version(file_entry.current_version_id) async def generate_preview_artifacts_for_file(self, file_id: str) -> int: file_entry = await self.file_repository.get_by_id(file_id) if file_entry is None or file_entry.current_version_id is None: raise ValueError("File is unavailable.") blob = await self.file_repository.get_primary_blob_for_file(file_id) if blob is None: raise ValueError("Primary blob does not exist.") artifact_types = self._select_artifact_types(file_entry.mime_type) created = 0 for artifact_type in artifact_types: existing = await self.preview_artifact_repository.get_by_version_and_type( file_entry.current_version_id, artifact_type, ) if existing is not None: if existing.status != "ready": existing.status = "ready" existing.blob_id = blob.id await self.preview_artifact_repository.save(existing) continue artifact = PreviewArtifact( id=new_id("prv"), file_version_id=file_entry.current_version_id, artifact_type=artifact_type, blob_id=blob.id, status="ready", ) await self.preview_artifact_repository.create(artifact) created += 1 await self.session.commit() return created @staticmethod def _select_artifact_types(mime_type: str | None) -> list[str]: if mime_type is None: return [] if mime_type.startswith("image/"): return ["inline_preview", "thumbnail"] if mime_type == "application/pdf": return ["inline_preview", "poster"] if mime_type.startswith("video/"): return ["poster"] return []