"""Image serving with quality-based thumbnail selection.""" from fastapi import HTTPException, status from fastapi.responses import StreamingResponse from app.database.models.image import Image def get_thumbnail_path(image: Image, quality: str) -> str: """ Get thumbnail path for specified quality level. Args: image: Image model instance quality: Quality level ('low', 'medium', 'high', 'original') Returns: Storage path to thumbnail Raises: ValueError: If quality level is invalid """ if quality == "original": return image.storage_path # Get thumbnail paths from metadata thumbnails = image.image_metadata.get("thumbnails", {}) # Map quality to thumbnail size if quality == "low": thumbnail_path = thumbnails.get("low") elif quality == "medium": thumbnail_path = thumbnails.get("medium") elif quality == "high": thumbnail_path = thumbnails.get("high") else: raise ValueError(f"Invalid quality level: {quality}") # Fall back to original if thumbnail doesn't exist if not thumbnail_path: return image.storage_path return thumbnail_path async def serve_image_with_quality( image: Image, quality: str = "medium", filename: str | None = None ) -> StreamingResponse: """ Serve image with specified quality level. Args: image: Image model instance quality: Quality level ('low', 'medium', 'high', 'original') filename: Optional custom filename for download Returns: StreamingResponse with image data Raises: HTTPException: If image cannot be served """ from app.images.download import download_single_image try: # Get appropriate thumbnail path storage_path = get_thumbnail_path(image, quality) # Use original filename if not specified if filename is None: filename = image.filename # Serve the image return await download_single_image(storage_path, filename) except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) from e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to serve image: {str(e)}", ) from e def determine_quality_from_speed(speed_mbps: float) -> str: """ Determine appropriate quality level based on connection speed. Args: speed_mbps: Connection speed in Mbps Returns: Quality level string """ if speed_mbps < 1.0: return "low" elif speed_mbps < 5.0: return "medium" else: return "high"