Skip to content

Implement videos page#622

Open
SiddharthJiyani wants to merge 4 commits intoAOSSIE-Org:mainfrom
SiddharthJiyani:feat/videos-page-implementation
Open

Implement videos page#622
SiddharthJiyani wants to merge 4 commits intoAOSSIE-Org:mainfrom
SiddharthJiyani:feat/videos-page-implementation

Conversation

@SiddharthJiyani
Copy link
Contributor

@SiddharthJiyani SiddharthJiyani commented Nov 8, 2025

Feat: Implement Videos Page with Dynamic Thumbnails

Overview

Adds full video management functionality with an optimized approach that eliminates unnecessary thumbnail storage and provides automatic database cleanup.

Key Changes

Backend

  • Video database schema and CRUD operations
  • Video scanning from folders with metadata extraction
  • Auto-cleanup of deleted videos from database
  • Upload endpoint for video files

Frontend

  • Videos page with grid layout and sorting options
  • Plyr video player with controls and settings
  • Video card component with play overlay

Technical Details

  • Uses OpenCV for video metadata extraction (duration, dimensions, fps)
  • Plyr.js for enhanced video playback experience
  • Automatic file existence validation on every fetch
  • Clean codebase with removed deprecated functions

Testing

  • Verified video scanning from folders
  • Confirmed auto-cleanup of deleted videos
  • Tested video playback with Plyr controls
  • Validated UI responsiveness and interactions

Demo

video_page_implementation_.1.mp4

Summary by CodeRabbit

  • New Features

    • Full video management: browse, scan folders, cleanup, and upload via a new Videos page and API.
    • Responsive video gallery with sorting (Newest/Oldest, A–Z), thumbnail cards, and modal playback using a modern player.
    • Background scanning and metadata extraction for videos; thumbnail support and upload capability.
  • Removed

    • Legacy Netflix-style custom player replaced by the new Plyr-based player.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 8, 2025

⚠️ No issue was linked in the PR description.
Please make sure to link an issue (e.g., 'Fixes #issue_number')

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Walkthrough

Adds end-to-end video support: new backend DB/table, utils, and API routes; frontend API clients, UI components and player (Plyr), Videos page, and build config for Plyr. Integrates video processing into folder workflows and initializes the videos table at startup.

Changes

Cohort / File(s) Summary
Backend config
backend/app/config/settings.py
Added VIDEOS_PATH and THUMBNAIL_VIDEOS_PATH constants for video storage.
Backend DB
backend/app/database/videos.py
New SQLite-backed videos module: connection helper, table creation, insert/update (ON CONFLICT ON path), get-all (removes missing files), get-by-path, delete-by-id, and TypedDict/type aliases.
Backend utils
backend/app/utils/videos.py
New utilities: ensure directories, OpenCV metadata extraction with fallbacks, validate extensions, collect files from folders (recursive option), register files into DB, and batch folder processing.
Backend routes
backend/app/routes/videos.py
New FastAPI router exposing GET /, POST /scan, POST /cleanup; uses DB and utils, returns typed responses and standardized error payloads.
Backend schemas
backend/app/schemas/videos.py
New Pydantic models: VideoMetadata, VideoData, GetAllVideosResponse, ErrorResponse.
Folder integration
backend/app/routes/folders.py
Invoke video_util_process_folder_videos alongside image processing in folder add and sync sequences.
App init
backend/main.py
Call db_create_videos_table() at startup and include videos router at /videos.
Frontend deps & build
frontend/package.json, frontend/vite.config.ts
Added plyr dependency and added it to Vite optimizeDeps.include.
Frontend API
frontend/src/api/apiEndpoints.ts, frontend/src/api/api-functions/videos.ts, frontend/src/api/api-functions/index.ts
New videosEndpoints and API helpers: fetchAllVideos, uploadVideos, scanVideos; exported from API index.
Frontend types
frontend/src/types/Media.ts
Added VideoMetadata and Video interfaces; adjusted Image.folder_id typing.
Frontend UI components
frontend/src/components/Media/VideoCard.tsx
New VideoCard component rendering video/thumbnail preview, badge, title, and play overlay.
Frontend player
frontend/src/components/VideoPlayer/PlyrPlayer.tsx, frontend/src/components/VideoPlayer/NetflixStylePlayer.tsx
Added PlyrPlayer (lazy-import, init/cleanup); removed legacy NetflixStylePlayer.
Frontend pages & routes
frontend/src/pages/VideosPage/Videos.tsx, frontend/src/routes/AppRoutes.tsx
New Videos page (fetch/scan/refresh/sort, grid of VideoCard, modal PlyrPlayer); route updated to use Videos component.
Frontend minor UI
frontend/src/components/ui/button.tsx
Added cursor styles for enabled/disabled button states.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Frontend as Videos Page
    participant API as /videos
    participant Utils as Video Utils
    participant DB as Videos DB
    participant FS as File System

    User->>Frontend: Open Videos page
    Frontend->>API: GET /videos/
    API->>DB: db_get_all_videos()
    DB-->>API: videos list
    API-->>Frontend: GetAllVideosResponse

    alt no videos or user requests scan
        Frontend->>API: POST /videos/scan
        API->>DB: db_get_all_folder_details()
        API->>Utils: video_util_process_folder_videos(folder_data)
        Utils->>FS: scan folders & read files
        loop per file
            Utils->>Utils: extract metadata (OpenCV)
            Utils->>DB: db_insert_video(record)
        end
        API->>DB: db_get_all_videos()
        API-->>Frontend: updated GetAllVideosResponse
    end

    User->>Frontend: Click VideoCard
    Frontend->>Frontend: show modal & init PlyrPlayer(src)
    User->>Frontend: control playback (Plyr)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files warranting extra attention:
    • backend/app/database/videos.py — schema correctness, ON CONFLICT behavior, cleanup of missing files.
    • backend/app/utils/videos.py — OpenCV usage, path normalization, exception swallowing and return semantics.
    • backend/app/routes/videos.py — API error handling and response contracts.
    • frontend/src/pages/VideosPage/Videos.tsx & frontend/src/components/VideoPlayer/PlyrPlayer.tsx — player lifecycle, lazy import, and modal integration.

Possibly related PRs

Suggested labels

enhancement, backend, frontend, UI

Suggested reviewers

  • rahulharpal1603

Poem

🐇
I hop through folders, tails a-flutter,
Thumbnails gleam and players stutter.
Plyr wakes up with buttery glide,
Videos arrive — a joyful ride.
Hop, click, and play — the updates flutter!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Implement videos page' clearly describes the main change—adding a complete videos page to the application with backend and frontend components.
Linked Issues check ✅ Passed The PR comprehensively implements all objectives from issue #611: backend endpoints for fetching/uploading/managing videos, video scanning with metadata extraction, API integration on frontend, grid layout with sorting, and Plyr.js playback integration.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the Videos page. Minor updates (button cursor styling, removing deprecated NetflixStylePlayer) are reasonable supporting changes for the main feature.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (11)
frontend/src/components/ui/button.tsx (1)

8-8: Good UX improvement with cursor-pointer, but disabled:cursor-not-allowed is redundant.

The cursor-pointer addition improves button UX by indicating clickability. However, disabled:cursor-not-allowed has no effect because disabled:pointer-events-none is already set—when pointer events are disabled, the browser won't display custom cursor styles.

If you want to keep the class string cleaner, you can remove the redundant class:

-  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
backend/app/schemas/videos.py (1)

5-13: Consider adding field validators for VideoMetadata.

The VideoMetadata model lacks validation constraints. Consider adding validators to ensure data integrity (e.g., positive values for width, height, duration, and file_size).

Example validation:

from pydantic import BaseModel, Field

class VideoMetadata(BaseModel):
    name: str
    date_created: Optional[str] = None
    width: int = Field(gt=0)
    height: int = Field(gt=0)
    duration: float = Field(gt=0)
    file_location: str
    file_size: int = Field(ge=0)
    item_type: str
backend/app/config/settings.py (1)

27-29: Consider using absolute paths for video storage.

The relative paths ./videos and ./videos/thumbnails depend on the current working directory. While this is consistent with the existing IMAGES_PATH pattern, consider using pathlib.Path with absolute paths or environment variables for more robust path handling across different execution contexts.

frontend/src/types/Media.ts (1)

40-48: Consider nullable thumbnailPath for backend consistency.

The thumbnailPath field is typed as string (line 43), but the backend VideoData.thumbnailPath is Optional[str]. Consider using thumbnailPath: string | null to handle cases where thumbnails might not be available.

 export interface Video {
   id: string;
   path: string;
-  thumbnailPath: string;
+  thumbnailPath: string | null;
   folder_id?: string;
   metadata?: VideoMetadata;
   title?: string;
   tags?: string[];
 }
backend/app/routes/folders.py (2)

71-73: Consider checking video processing return value.

While video_util_process_folder_videos returns a boolean indicating success/failure, the return value is not checked. If video processing fails, the function continues silently. Consider logging the result or adding explicit error handling for better observability.

 # Process images and videos in all folders
 image_util_process_folder_images(folder_data)
-video_util_process_folder_videos(folder_data)
+video_success = video_util_process_folder_videos(folder_data)
+if not video_success:
+    logger.warning(f"Video processing encountered errors for folder {folder_path}")

119-121: Consider checking video processing return value.

Similar to the add folder sequence, the return value of video_util_process_folder_videos is not checked here. Consider adding result validation for consistency and better error visibility.

 # Process images and videos in all folders
 image_util_process_folder_images(folder_data)
-video_util_process_folder_videos(folder_data)
+video_success = video_util_process_folder_videos(folder_data)
+if not video_success:
+    logger.warning(f"Video processing encountered errors during sync for folder {folder_path}")
 image_util_process_untagged_images()
frontend/src/components/VideoPlayer/PlyrPlayer.tsx (1)

102-102: Consider supporting multiple video formats.

The video source is hardcoded to type="video/mp4", which may not support other formats like WebM or OGV.

If you need to support multiple formats, consider:

-        <source src={src} type="video/mp4" />
+        <source src={src} />

Or detect the format from the file extension and set the appropriate MIME type.

backend/app/routes/videos.py (1)

24-33: Consider extracting duplicate VideoData mapping logic.

The same VideoData construction pattern appears in all four endpoints. Extracting this into a helper function would improve maintainability.

Example:

def _map_videos_to_response(videos: List[dict]) -> List[VideoData]:
    """Helper to map database video dicts to VideoData schema."""
    return [
        VideoData(
            id=v["id"],
            path=v["path"],
            folder_id=v.get("folder_id"),
            thumbnailPath=v["thumbnailPath"],
            metadata=image_util_parse_metadata(v.get("metadata")),
        )
        for v in videos
    ]

# Then use in endpoints:
data = _map_videos_to_response(videos)

Also applies to: 57-66, 100-109, 133-142

backend/app/utils/videos.py (3)

55-81: Consider refactoring the import and directory check.

Two minor inefficiencies:

  1. Import inside function (line 59): The local import of db_get_video_by_path suggests a circular dependency issue. Consider restructuring imports or using TYPE_CHECKING to resolve this more cleanly.

  2. Redundant directory check (line 61): video_util_ensure_dirs() is called for every file registration. While harmless (due to exist_ok=True), it's unnecessary overhead. Consider calling it once during application startup or at the beginning of batch operations like video_util_process_folder_videos.

For the import issue, consider moving it to the top with TYPE_CHECKING:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from app.database.videos import db_get_video_by_path

Or restructure the module dependencies to eliminate the circular import.


90-108: Add consistent error handling for recursive mode.

The non-recursive mode catches OSError (line 106), but the recursive mode using os.walk (lines 94-99) doesn't. The os.walk function can raise OSError for permission issues or other filesystem errors when traversing subdirectories, leading to inconsistent behavior.

Apply this diff to add consistent error handling:

 def video_util_get_videos_from_folder(
     folder_path: str, recursive: bool = True
 ) -> List[str]:
     videos: List[str] = []
     if recursive:
-        for root, _, files in os.walk(folder_path):
-            for f in files:
-                p = os.path.join(root, f)
-                if video_util_is_valid_video(p):
-                    videos.append(p)
+        try:
+            for root, _, files in os.walk(folder_path):
+                for f in files:
+                    p = os.path.join(root, f)
+                    if video_util_is_valid_video(p):
+                        videos.append(p)
+        except OSError:
+            pass
     else:
         try:
             for f in os.listdir(folder_path):
                 p = os.path.join(folder_path, f)
                 if os.path.isfile(p) and video_util_is_valid_video(p):
                     videos.append(p)
         except OSError:
             pass
     return videos

114-126: Add logging for top-level exceptions.

The top-level exception handler (lines 125-126) silently returns False without logging the error. This makes it difficult to diagnose why folder processing failed, especially since the function processes multiple folders and could fail for various reasons (filesystem issues, database errors, etc.).

Apply this diff to add error logging:

 def video_util_process_folder_videos(folder_data: List[essential_tuple]) -> bool:
     try:
         video_util_ensure_dirs()
         for path, folder_id, recursive in folder_data:
             file_list = video_util_get_videos_from_folder(path, recursive)
             for fp in file_list:
                 try:
                     video_util_register_file(fp, folder_id)
                 except Exception:
                     continue
         return True
-    except Exception:
+    except Exception as e:
+        logger.error(f"Failed to process folder videos: {e}")
         return False
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe2f98d and f1232dc.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (19)
  • backend/app/config/settings.py (1 hunks)
  • backend/app/database/videos.py (1 hunks)
  • backend/app/routes/folders.py (3 hunks)
  • backend/app/routes/videos.py (1 hunks)
  • backend/app/schemas/videos.py (1 hunks)
  • backend/app/utils/videos.py (1 hunks)
  • backend/main.py (3 hunks)
  • frontend/package.json (1 hunks)
  • frontend/src/api/api-functions/index.ts (1 hunks)
  • frontend/src/api/api-functions/videos.ts (1 hunks)
  • frontend/src/api/apiEndpoints.ts (1 hunks)
  • frontend/src/components/Media/VideoCard.tsx (1 hunks)
  • frontend/src/components/VideoPlayer/NetflixStylePlayer.tsx (0 hunks)
  • frontend/src/components/VideoPlayer/PlyrPlayer.tsx (1 hunks)
  • frontend/src/components/ui/button.tsx (1 hunks)
  • frontend/src/pages/VideosPage/Videos.tsx (1 hunks)
  • frontend/src/routes/AppRoutes.tsx (1 hunks)
  • frontend/src/types/Media.ts (2 hunks)
  • frontend/vite.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/components/VideoPlayer/NetflixStylePlayer.tsx
🧰 Additional context used
🧬 Code graph analysis (10)
frontend/src/api/api-functions/videos.ts (3)
frontend/src/types/API.ts (1)
  • APIResponse (1-8)
frontend/src/api/axiosConfig.ts (1)
  • apiClient (5-12)
frontend/src/api/apiEndpoints.ts (1)
  • videosEndpoints (5-9)
frontend/src/types/Media.ts (1)
backend/app/schemas/videos.py (1)
  • VideoMetadata (5-13)
frontend/src/routes/AppRoutes.tsx (1)
frontend/src/constants/routes.ts (1)
  • ROUTES (1-11)
frontend/src/pages/VideosPage/Videos.tsx (6)
frontend/src/types/API.ts (1)
  • APIResponse (1-8)
frontend/src/api/api-functions/videos.ts (2)
  • fetchAllVideos (5-10)
  • scanVideos (25-28)
frontend/src/types/Media.ts (1)
  • Video (40-48)
frontend/src/components/ui/LoadingScreen/LoadingScreen.tsx (1)
  • LoadingScreen (15-64)
frontend/src/components/Media/VideoCard.tsx (1)
  • VideoCard (13-52)
frontend/src/components/VideoPlayer/PlyrPlayer.tsx (1)
  • PlyrPlayer (10-106)
backend/app/schemas/videos.py (1)
frontend/src/types/Media.ts (1)
  • VideoMetadata (13-22)
backend/app/utils/videos.py (1)
backend/app/database/videos.py (2)
  • db_insert_video (52-75)
  • db_get_video_by_path (128-156)
backend/app/routes/videos.py (5)
backend/app/database/videos.py (1)
  • db_get_all_videos (78-125)
backend/app/schemas/videos.py (3)
  • GetAllVideosResponse (24-27)
  • ErrorResponse (30-33)
  • VideoData (16-21)
backend/app/utils/images.py (1)
  • image_util_parse_metadata (496-513)
backend/app/utils/videos.py (3)
  • video_util_register_file (55-81)
  • video_util_ensure_dirs (15-16)
  • video_util_process_folder_videos (114-126)
backend/app/database/folders.py (1)
  • db_get_all_folder_details (397-418)
frontend/src/components/Media/VideoCard.tsx (1)
frontend/src/types/Media.ts (1)
  • Video (40-48)
backend/app/routes/folders.py (2)
backend/app/utils/videos.py (1)
  • video_util_process_folder_videos (114-126)
backend/app/utils/images.py (1)
  • image_util_process_folder_images (32-84)
backend/main.py (1)
backend/app/database/videos.py (1)
  • db_create_videos_table (31-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: sync-labels
  • GitHub Check: Backend Tests
  • GitHub Check: Tauri Build Check (windows-latest)
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
🔇 Additional comments (18)
frontend/src/routes/AppRoutes.tsx (1)

11-11: LGTM!

The Videos component import and route registration follow the existing patterns and integrate cleanly with the route structure.

Also applies to: 19-19

frontend/vite.config.ts (1)

17-19: LGTM!

Pre-bundling plyr in optimizeDeps is the recommended approach for improving dev server startup time and handling potential ESM compatibility issues with the library.

frontend/src/api/api-functions/index.ts (1)

4-4: LGTM!

The videos module export follows the established pattern for API function organization.

frontend/src/types/Media.ts (1)

13-22: LGTM!

The VideoMetadata interface correctly mirrors the backend schema fields and types, ensuring consistent data shape across frontend and backend.

backend/app/routes/folders.py (1)

45-45: LGTM!

The import of video processing utilities integrates cleanly with the existing folder processing infrastructure.

frontend/package.json (1)

56-56: plyr 3.8.3 is current and secure.

Version 3.8.3 is the latest release with no known security vulnerabilities or CVEs. The package was released August 27, 2025, indicating active maintenance. No action needed.

backend/app/schemas/videos.py (1)

21-21: The code is correct for the project's Python version requirement.

The union syntax Mapping[str, Any] | VideoMetadata is appropriate here. The project's GitHub Actions workflows explicitly specify Python 3.12, which fully supports PEP 604 union syntax (available since Python 3.10). No changes are needed.

frontend/src/api/apiEndpoints.ts (1)

5-9: LGTM!

The new videosEndpoints object follows the established pattern and provides clear endpoint definitions for video operations.

backend/main.py (1)

22-22: LGTM!

The video module integration follows the established pattern for other entities in the application. The table creation is correctly placed in the startup sequence, and the router is properly mounted with appropriate tags.

Also applies to: 28-28, 58-58, 132-132

frontend/src/api/api-functions/videos.ts (1)

5-28: LGTM!

The API functions follow a clean pattern and leverage the existing apiClient configuration. Error handling appears to be delegated to the caller (React Query), which is a reasonable approach for this architecture.

frontend/src/pages/VideosPage/Videos.tsx (1)

68-141: LGTM!

The UI implementation is well-structured with responsive grid layout, sorting controls, and a modal player. The component provides a good user experience with loading states and empty states.

frontend/src/components/Media/VideoCard.tsx (1)

13-52: Well-structured video card component.

The component provides good UX with hover effects, play button overlay, and responsive design. The video metadata fallback chain is robust.

frontend/src/components/VideoPlayer/PlyrPlayer.tsx (1)

10-106: Excellent player implementation with proper cleanup.

The component handles Plyr initialization, configuration, and cleanup correctly. The dynamic import approach and effect dependencies are appropriate.

backend/app/database/videos.py (4)

31-49: LGTM!

The table schema is well-designed with appropriate constraints. The foreign key relationship with ON DELETE SET NULL ensures data integrity when folders are removed.


52-76: LGTM!

The upsert logic using ON CONFLICT is appropriate for handling duplicate paths, and error handling with rollback is properly implemented.


78-126: Excellent auto-cleanup implementation.

The automatic cleanup of database entries for deleted files is a smart approach that keeps the database in sync with the filesystem. The implementation is safe and well-logged.


128-171: LGTM!

Both query and delete functions are well-implemented with proper error handling and connection management.

backend/app/utils/videos.py (1)

15-16: Now let me search for broader "thumbnail" references in the codebase:

Remove THUMBNAIL_VIDEOS_PATH from settings or implement directory creation.

The constant is defined in backend/app/config/settings.py (line 29) but never used anywhere in the codebase. Since the PR optimizes by avoiding unnecessary thumbnails (line 77 sets thumbnailPath to None), either remove this unused constant from settings to prevent confusion, or add os.makedirs(THUMBNAIL_VIDEOS_PATH, exist_ok=True) to video_util_ensure_dirs() if thumbnail functionality is planned for the future.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
backend/app/routes/videos.py (4)

9-9: Consider adding tags to the router for better API documentation.

Adding tags helps organize endpoints in the automatically generated OpenAPI/Swagger documentation.

Apply this diff:

-router = APIRouter()
+router = APIRouter(tags=["videos"])

12-39: Consider pagination for scalability.

The endpoint returns all videos without pagination, which could cause performance issues and large response sizes with extensive video libraries.

Consider adding pagination parameters:

@router.get(
    "/",
    response_model=GetAllVideosResponse,
    responses={500: {"model": ErrorResponse}},
)
def get_all_videos(skip: int = 0, limit: int = 100):
    try:
        videos = db_get_all_videos()
        # Apply pagination
        paginated_videos = videos[skip:skip + limit]
        data: List[VideoData] = [
            VideoData(
                id=v["id"],
                path=v["path"],
                folder_id=v.get("folder_id"),
                thumbnailPath=v["thumbnailPath"],
                metadata=image_util_parse_metadata(v.get("metadata")),
            )
            for v in paginated_videos
        ]
        return GetAllVideosResponse(
            success=True, 
            message=f"Retrieved {len(data)} videos (showing {skip}-{skip+len(data)} of {len(videos)} total)", 
            data=data
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ErrorResponse(
                success=False, error="Internal server error", message=str(e)
            ).model_dump(),
        )

47-47: Remove async keyword or use asynchronous operations.

The function is declared as async but doesn't use any await expressions. This creates unnecessary overhead and inconsistency with get_all_videos, which is synchronous.

Apply this diff:

-async def scan_videos_from_folders():
+def scan_videos_from_folders():

80-80: Remove async keyword or use asynchronous operations.

Similar to scan_videos_from_folders, this function is declared as async but doesn't use any await expressions, creating inconsistency with get_all_videos.

Apply this diff:

-async def cleanup_deleted_videos():
+def cleanup_deleted_videos():
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1232dc and 07839fe.

📒 Files selected for processing (1)
  • backend/app/routes/videos.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/app/routes/videos.py (5)
backend/app/database/videos.py (1)
  • db_get_all_videos (78-125)
backend/app/schemas/videos.py (3)
  • GetAllVideosResponse (24-27)
  • ErrorResponse (30-33)
  • VideoData (16-21)
backend/app/utils/images.py (1)
  • image_util_parse_metadata (496-513)
backend/app/utils/videos.py (1)
  • video_util_process_folder_videos (114-126)
backend/app/database/folders.py (1)
  • db_get_all_folder_details (397-418)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Backend Tests
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)
  • GitHub Check: Tauri Build Check (windows-latest)
🔇 Additional comments (3)
backend/app/routes/videos.py (3)

80-81: LGTM! The cleanup mechanism works via implicit behavior.

The endpoint correctly leverages the automatic cleanup behavior in db_get_all_videos, which removes database entries for videos whose files no longer exist (as shown in the relevant code snippet from backend/app/database/videos.py). The docstring clearly explains the purpose.


33-39: LGTM! Error handling is consistent and appropriate.

The error handling pattern correctly uses ErrorResponse.model_dump() to convert the Pydantic model to a dictionary for the HTTPException detail field. The consistent structure across all endpoints makes the API predictable.

Also applies to: 66-72, 99-105


50-50: Review comment is incorrect—AI_Tagging and recursive scanning are unrelated features.

The hardcoded recursive=False is intentional system-wide behavior (replicated in backend/app/routes/folders.py:68 with an explicit comment). The database schema has no recursive field; it's not configurable per folder.

AI_Tagging is a separate per-folder feature flag for AI-based image tagging (queried in backend/app/database/images.py), not a control for scan recursion. It does not indicate or require recursive folder scanning.

Likely an incorrect or invalid review comment.

@rahulharpal1603
Copy link
Contributor

@SiddharthJiyani Please resolve conflicts.

@github-actions github-actions bot added backend enhancement New feature or request frontend labels Nov 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 809a5e6 and 8a8033f.

📒 Files selected for processing (3)
  • frontend/src/api/apiEndpoints.ts (1 hunks)
  • frontend/src/routes/AppRoutes.tsx (1 hunks)
  • frontend/src/types/Media.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/api/apiEndpoints.ts
  • frontend/src/routes/AppRoutes.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/types/Media.ts (1)
backend/app/schemas/videos.py (1)
  • VideoMetadata (5-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Backend Tests
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
  • GitHub Check: Tauri Build Check (windows-latest)
🔇 Additional comments (2)
frontend/src/types/Media.ts (2)

13-22: LGTM! VideoMetadata interface aligns with backend schema.

The VideoMetadata interface correctly mirrors the backend schema with appropriate TypeScript types and includes the essential duration field for video playback.


24-34: The review comment is incorrect.

The git diff shows that folder_id: string was already required in the codebase before this PR and was not modified. The line appears as unchanged context in the diff, not as a new addition or modification. The actual changes in this PR are:

  • Added VideoMetadata interface
  • Added isFavourite?: boolean to the Image interface
  • Added Video interface with optional folder_id?: string
  • Added images: Image[] property to MediaViewProps

There is no breaking change to Image.folder_id in this PR.

Likely an incorrect or invalid review comment.

@SiddharthJiyani
Copy link
Contributor Author

@SiddharthJiyani Please resolve conflicts.

Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Implement Videos Page

2 participants

Comments