diff --git a/backend/app/database/images.py b/backend/app/database/images.py index dadbc202..15c1d374 100644 --- a/backend/app/database/images.py +++ b/backend/app/database/images.py @@ -1,6 +1,8 @@ # Standard library imports import sqlite3 from typing import Any, List, Mapping, Tuple, TypedDict, Union, Optional +import json + from datetime import datetime # App-specific imports @@ -455,6 +457,36 @@ def db_toggle_image_favourite_status(image_id: str) -> bool: finally: conn.close() +def db_get_image_by_id(image_id: str) -> Optional[dict]: + """ + Get a single image by ID with its favorite status. + """ + conn = _connect() + cursor = conn.cursor() + try: + cursor.execute(""" + SELECT id, path, folder_id, thumbnailPath, metadata, isTagged, isFavourite + FROM images + WHERE id = ? + """, (image_id,)) + row = cursor.fetchone() + if not row: + return None + try: + metadata = json.loads(row[4]) if row[4] else {} + except json.JSONDecodeError: + metadata = {} + return { + "id": row[0], + "path": row[1], + "folder_id": row[2], + "thumbnailPath": row[3], + "metadata": metadata, + "isTagged": bool(row[5]), + "isFavourite": bool(row[6]), + } + finally: + conn.close() # ============================================================================ # MEMORIES FEATURE - Location and Time-based Queries diff --git a/backend/app/routes/images.py b/backend/app/routes/images.py index 2e40cd82..f00b0a94 100644 --- a/backend/app/routes/images.py +++ b/backend/app/routes/images.py @@ -4,9 +4,10 @@ from app.schemas.images import ErrorResponse from app.utils.images import image_util_parse_metadata from pydantic import BaseModel -from app.database.images import db_toggle_image_favourite_status +from app.database.images import db_toggle_image_favourite_status, db_get_image_by_id from app.logging.setup_logging import get_logger + # Initialize logger logger = get_logger(__name__) router = APIRouter() @@ -97,27 +98,37 @@ class ToggleFavouriteRequest(BaseModel): @router.post("/toggle-favourite") def toggle_favourite(req: ToggleFavouriteRequest): + """ + Toggle the favorite status of an image. + """ image_id = req.image_id try: success = db_toggle_image_favourite_status(image_id) if not success: raise HTTPException( - status_code=404, detail="Image not found or failed to toggle" + status_code=status.HTTP_404_NOT_FOUND, + detail="Image not found or failed to toggle" ) # Fetch updated status to return - image = next( - (img for img in db_get_all_images() if img["id"] == image_id), None - ) + image = db_get_image_by_id(image_id) + if not image: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Image not found after toggle" + ) return { "success": True, "image_id": image_id, "isFavourite": image.get("isFavourite", False), } - + except HTTPException: + raise # Re-raise HTTPExceptions to preserve status codes except Exception as e: logger.error(f"error in /toggle-favourite route: {e}") - raise HTTPException(status_code=500, detail=f"Internal server error: {e}") - + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Internal server error: {e}" + ) class ImageInfoResponse(BaseModel): id: str