Some checks failed
CI / skip-ci-check (pull_request) Successful in 10s
CI / python-lint (pull_request) Has been cancelled
CI / test-backend (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / secret-scanning (pull_request) Has been cancelled
CI / dependency-scan (pull_request) Has been cancelled
CI / sast-scan (pull_request) Has been cancelled
CI / workflow-summary (pull_request) Has been cancelled
CI / lint-and-type-check (pull_request) Has been cancelled
- Add `browseDirectory` API endpoint to list directory contents. - Create `FolderBrowser` component for user interface to navigate directories. - Update `Scan` page to integrate folder browsing feature. - Define `DirectoryItem` and `BrowseDirectoryResponse` schemas for API responses.
111 lines
3.0 KiB
Python
111 lines
3.0 KiB
Python
"""Photo schemas."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class PhotoImportRequest(BaseModel):
|
|
"""Request to import photos from a folder or upload files."""
|
|
|
|
folder_path: Optional[str] = Field(
|
|
None, description="Path to folder to scan for photos"
|
|
)
|
|
recursive: bool = Field(
|
|
True, description="Whether to scan subdirectories recursively"
|
|
)
|
|
|
|
|
|
class PhotoResponse(BaseModel):
|
|
"""Photo response schema."""
|
|
|
|
id: int
|
|
path: str
|
|
filename: str
|
|
checksum: Optional[str] = None
|
|
date_added: datetime
|
|
date_taken: Optional[datetime] = None
|
|
width: Optional[int] = None
|
|
height: Optional[int] = None
|
|
mime_type: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class PhotoImportResponse(BaseModel):
|
|
"""Response after initiating photo import."""
|
|
|
|
job_id: str
|
|
message: str
|
|
folder_path: Optional[str] = None
|
|
estimated_photos: Optional[int] = None
|
|
|
|
|
|
class BulkAddFavoritesRequest(BaseModel):
|
|
"""Request to add multiple photos to favorites."""
|
|
|
|
photo_ids: List[int] = Field(..., description="List of photo IDs to add to favorites")
|
|
|
|
|
|
class BulkAddFavoritesResponse(BaseModel):
|
|
"""Response for bulk add favorites operation."""
|
|
|
|
message: str
|
|
added_count: int
|
|
already_favorite_count: int
|
|
total_requested: int
|
|
|
|
|
|
class BulkRemoveFavoritesRequest(BaseModel):
|
|
"""Request to remove multiple photos from favorites."""
|
|
|
|
photo_ids: List[int] = Field(..., description="List of photo IDs to remove from favorites")
|
|
|
|
|
|
class BulkRemoveFavoritesResponse(BaseModel):
|
|
"""Response for bulk remove favorites operation."""
|
|
|
|
message: str
|
|
removed_count: int
|
|
not_favorite_count: int
|
|
total_requested: int
|
|
|
|
|
|
class BulkDeletePhotosRequest(BaseModel):
|
|
"""Request to delete multiple photos permanently."""
|
|
|
|
photo_ids: List[int] = Field(..., description="List of photo IDs to delete")
|
|
|
|
|
|
class BulkDeletePhotosResponse(BaseModel):
|
|
"""Response for bulk delete photos operation."""
|
|
|
|
message: str
|
|
deleted_count: int
|
|
missing_photo_ids: List[int] = Field(
|
|
default_factory=list,
|
|
description="Photo IDs that were requested but not found",
|
|
)
|
|
|
|
|
|
class DirectoryItem(BaseModel):
|
|
"""Directory item (file or folder) in a directory listing."""
|
|
|
|
name: str = Field(..., description="Name of the item")
|
|
path: str = Field(..., description="Full absolute path to the item")
|
|
is_directory: bool = Field(..., description="Whether this is a directory")
|
|
is_file: bool = Field(..., description="Whether this is a file")
|
|
|
|
|
|
class BrowseDirectoryResponse(BaseModel):
|
|
"""Response for directory browsing."""
|
|
|
|
current_path: str = Field(..., description="Current directory path")
|
|
parent_path: Optional[str] = Field(None, description="Parent directory path (None if at root)")
|
|
items: List[DirectoryItem] = Field(..., description="List of items in the directory")
|
|
|