feat: add loading page with real-time initialization progress
- Create loading.html template with WebSocket-based progress updates - Update initialization_service to emit progress events via ProgressService - Modify setup endpoint to run initialization in background and redirect to loading page - Add /loading route in page_controller - Show real-time progress for series sync, NFO scan, and media scan steps - Display completion message with button to continue to app - Handle errors with visual feedback
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
"""Centralized initialization service for application startup and setup."""
|
||||
from typing import Optional
|
||||
|
||||
import structlog
|
||||
|
||||
from src.config.settings import settings
|
||||
@@ -7,7 +9,7 @@ from src.server.services.anime_service import sync_series_from_data_files
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
async def perform_initial_setup():
|
||||
async def perform_initial_setup(progress_service=None):
|
||||
"""Perform initial setup including series sync and scan completion marking.
|
||||
|
||||
This function is called both during application lifespan startup
|
||||
@@ -18,12 +20,27 @@ async def perform_initial_setup():
|
||||
4. NFO scan is performed if configured
|
||||
5. Media scan is performed
|
||||
|
||||
Args:
|
||||
progress_service: Optional ProgressService instance for emitting updates
|
||||
|
||||
Returns:
|
||||
bool: True if initialization was performed, False if skipped
|
||||
"""
|
||||
from src.server.database.connection import get_db_session
|
||||
from src.server.database.system_settings_service import SystemSettingsService
|
||||
|
||||
# Send initial progress update
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="started",
|
||||
title="Syncing Series Database",
|
||||
message="Checking initialization status...",
|
||||
percent=0,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
|
||||
# Check if initial setup has been completed
|
||||
try:
|
||||
async with get_db_session() as db:
|
||||
@@ -35,6 +52,16 @@ async def perform_initial_setup():
|
||||
logger.info(
|
||||
"Initial scan already completed, skipping data file sync"
|
||||
)
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Syncing Series Database",
|
||||
message="Already completed",
|
||||
percent=100,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
return False
|
||||
else:
|
||||
logger.info(
|
||||
@@ -58,11 +85,32 @@ async def perform_initial_setup():
|
||||
logger.info(
|
||||
"Initialization skipped - anime directory not configured"
|
||||
)
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Syncing Series Database",
|
||||
message="No anime directory configured",
|
||||
percent=100,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
return False
|
||||
|
||||
# Only sync from data files on first run
|
||||
if not is_initial_scan_done:
|
||||
logger.info("Performing initial anime folder scan...")
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="in_progress",
|
||||
title="Syncing Series Database",
|
||||
message="Scanning anime folders...",
|
||||
percent=25,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
|
||||
sync_count = await sync_series_from_data_files(
|
||||
settings.anime_directory
|
||||
)
|
||||
@@ -70,6 +118,17 @@ async def perform_initial_setup():
|
||||
"Data file sync complete. Added %d series.", sync_count
|
||||
)
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="in_progress",
|
||||
title="Syncing Series Database",
|
||||
message=f"Synced {sync_count} series from data files",
|
||||
percent=75,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
|
||||
# Mark initial scan as completed
|
||||
try:
|
||||
async with get_db_session() as db:
|
||||
@@ -94,6 +153,17 @@ async def perform_initial_setup():
|
||||
await anime_service._load_series_from_db()
|
||||
logger.info("Series loaded from database into memory")
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="series_sync",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Syncing Series Database",
|
||||
message="Series loaded into memory",
|
||||
percent=100,
|
||||
metadata={"step_id": "series_sync"}
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
except (OSError, RuntimeError, ValueError) as e:
|
||||
@@ -101,11 +171,26 @@ async def perform_initial_setup():
|
||||
return False
|
||||
|
||||
|
||||
async def perform_nfo_scan_if_needed():
|
||||
"""Perform initial NFO scan if not yet completed and configured."""
|
||||
async def perform_nfo_scan_if_needed(progress_service=None):
|
||||
"""Perform initial NFO scan if not yet completed and configured.
|
||||
|
||||
Args:
|
||||
progress_service: Optional ProgressService instance for emitting updates
|
||||
"""
|
||||
from src.server.database.connection import get_db_session
|
||||
from src.server.database.system_settings_service import SystemSettingsService
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="started",
|
||||
title="Processing NFO Metadata",
|
||||
message="Checking NFO scan status...",
|
||||
percent=0,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
|
||||
# Check if initial NFO scan has been completed
|
||||
try:
|
||||
async with get_db_session() as db:
|
||||
@@ -126,16 +211,51 @@ async def perform_nfo_scan_if_needed():
|
||||
):
|
||||
if not is_nfo_scan_done:
|
||||
logger.info("Performing initial NFO scan...")
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="in_progress",
|
||||
title="Processing NFO Metadata",
|
||||
message="Scanning series for NFO files...",
|
||||
percent=25,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
|
||||
try:
|
||||
from src.core.services.series_manager_service import (
|
||||
SeriesManagerService,
|
||||
)
|
||||
|
||||
manager = SeriesManagerService.from_settings()
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="in_progress",
|
||||
title="Processing NFO Metadata",
|
||||
message="Processing NFO files with TMDB data...",
|
||||
percent=50,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
|
||||
await manager.scan_and_process_nfo()
|
||||
await manager.close()
|
||||
logger.info("Initial NFO scan completed")
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Processing NFO Metadata",
|
||||
message="NFO scan completed successfully",
|
||||
percent=100,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
|
||||
# Mark NFO scan as completed
|
||||
try:
|
||||
async with get_db_session() as db:
|
||||
@@ -155,15 +275,49 @@ async def perform_nfo_scan_if_needed():
|
||||
e,
|
||||
exc_info=True
|
||||
)
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="failed",
|
||||
title="Processing NFO Metadata",
|
||||
message=f"NFO scan failed: {str(e)}",
|
||||
percent=0,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"Skipping NFO scan - already completed on previous run"
|
||||
)
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Processing NFO Metadata",
|
||||
message="Already completed",
|
||||
percent=100,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
else:
|
||||
if not settings.tmdb_api_key:
|
||||
logger.info(
|
||||
"NFO scan skipped - TMDB API key not configured"
|
||||
)
|
||||
message = "Skipped - TMDB API key not configured"
|
||||
else:
|
||||
message = "Skipped - NFO features disabled"
|
||||
|
||||
if progress_service:
|
||||
progress_service.emit_progress(
|
||||
progress_id="nfo_scan",
|
||||
progress_type="system",
|
||||
status="completed",
|
||||
title="Processing NFO Metadata",
|
||||
message=message,
|
||||
percent=100,
|
||||
metadata={"step_id": "nfo_scan"}
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"NFO scan skipped - auto_create and update_on_scan "
|
||||
|
||||
Reference in New Issue
Block a user