Commit Graph

256 Commits

Author SHA1 Message Date
4c606faa0e fix: sync config to settings instead of calling non-existent reload method
- Remove settings.reload() call which doesn't exist in Pydantic BaseSettings
- Manually sync anime_directory and NFO settings from config.json to settings object
- Mirrors the sync logic used in fastapi_app.py lifespan
- Fixes AttributeError: 'Settings' object has no attribute 'reload'
2026-01-23 14:41:06 +01:00
50e0b21669 refactor: centralize initialization logic in dedicated service
- Create initialization_service.py with shared initialization functions
- Extract setup logic from lifespan and setup endpoint into reusable functions
- Setup endpoint now calls perform_initial_setup() directly
- Lifespan startup calls the same shared functions
- Eliminates code duplication between setup and lifespan
- Ensures consistent initialization behavior regardless of entry point
2026-01-23 14:37:07 +01:00
8e8487b7b7 fix: mark initial scan as completed after setup endpoint sync
- Add mark_initial_scan_completed() call to /api/auth/setup endpoint
- Ensures initial_scan_completed flag is set to True after first sync
- Prevents duplicate folder scans on subsequent application startups
- Include error handling to prevent setup failure if marking fails
2026-01-21 20:24:16 +01:00
125892abe5 feat: implement NFO ID storage and media scan tracking
Task 3 (NFO data):
- Add parse_nfo_ids() method to NFOService
- Extract TMDB/TVDB IDs from NFO files during scan
- Update database with extracted IDs
- Add comprehensive unit and integration tests

Task 4 (Media scan):
- Track initial media scan with SystemSettings flag
- Run background loading only on first startup
- Skip media scan on subsequent runs
2026-01-21 19:36:54 +01:00
9f1158b9af Implement initial NFO scan tracking for one-time setup
- Add NFO scanning to startup process (fastapi_app.py)
- Check initial_nfo_scan_completed flag before running NFO scan
- Run NFO scan only on first startup if TMDB API key is configured
- Mark NFO scan as completed after first successful run
- Skip NFO scan on subsequent startups

This ensures NFO metadata processing only occurs during initial setup,
not on every application restart, improving startup performance.
2026-01-21 19:25:30 +01:00
bf3cfa00d5 Implement initial scan tracking for one-time setup
- Add SystemSettings model to track setup completion status
- Create SystemSettingsService for managing setup flags
- Modify fastapi_app startup to check and set initial_scan_completed flag
- Anime folder scanning now only runs on first startup
- Update DATABASE.md with new system_settings table documentation
- Add unit test for SystemSettingsService functionality

This ensures expensive one-time operations like scanning the entire anime
directory only occur during initial setup, not on every application restart.
2026-01-21 19:22:50 +01:00
6215477eef Optimize episode loading to prevent full directory rescans
- Added _find_series_directory() to locate series without full rescan
- Added _scan_series_episodes() to scan only target series directory
- Modified _load_episodes() to use targeted scanning instead of anime_service.rescan()
- Added 15 comprehensive unit tests for optimization
- Performance improvement: <1s vs 30-60s for large libraries
- All tests passing (15 new tests + 14 existing background loader tests)
2026-01-19 20:55:48 +01:00
bfbae88ade Skip NFO creation if exists and update DB 2026-01-19 20:45:05 +01:00
6d40ddbfe5 Fix async generator exception handling and add comprehensive tests 2026-01-19 20:34:06 +01:00
7d95c180a9 Fix async context manager usage in BackgroundLoaderService
- Changed 'async for' to 'async with' for get_db_session()
- get_db_session() is @asynccontextmanager, requires async with not async for
- Created 5 comprehensive unit tests verifying the fix
- All tests pass, background loading now works correctly
2026-01-19 19:50:25 +01:00
09a5eccea7 Fix generator exception handling in database dependencies
- Add proper exception handling in get_database_session and get_optional_database_session
- Prevents 'generator didn't stop after athrow()' error when HTTPException is raised
- Add mock for BackgroundLoaderService in anime endpoint tests
- Update test expectations to match 202 Accepted response for async add_series endpoint
2026-01-19 19:38:53 +01:00
0bbdd46fc7 Fix async loading bugs and add test results
Critical Fixes:
- Fix async context manager usage in fastapi_app.py (async for -> async with)
- Add broadcast() method to WebSocketService
- Initialize BackgroundLoaderService properly in lifespan function

Testing:
- Execute manual testing (Tests 1, 5, 8, 9)
- Create comprehensive test results document
- Verify API endpoints return 202 Accepted
- Confirm database persistence works
- Validate startup incomplete series check

Test Results:
- Response time: 61ms (target: < 500ms) 
- 4 series found with missing data on startup
- Database fields properly persisted
- All critical bugs fixed

Files:
- check_db.py: Database inspection utility
- docs/MANUAL_TESTING_RESULTS.md: Comprehensive test results
- src/server/fastapi_app.py: Fixed async context manager, initialized BackgroundLoaderService
- src/server/services/websocket_service.py: Added broadcast() method
2026-01-19 08:49:28 +01:00
0b4fb10d65 Add frontend UI for async series loading
- Add SERIES_LOADING_UPDATE WebSocket event
- Update series cards to display loading indicators
- Add real-time status updates via WebSocket
- Include progress tracking (episodes, NFO, logo, images)
- Add CSS styling for loading states
- Implement updateSeriesLoadingStatus function
2026-01-19 07:20:29 +01:00
f18c31a035 Implement async series data loading with background processing
- Add loading status fields to AnimeSeries model
- Create BackgroundLoaderService for async task processing
- Update POST /api/anime/add to return 202 Accepted immediately
- Add GET /api/anime/{key}/loading-status endpoint
- Integrate background loader with startup/shutdown lifecycle
- Create database migration script for loading status fields
- Add unit tests for BackgroundLoaderService (10 tests, all passing)
- Update AnimeSeriesService.create() to accept loading status fields

Architecture follows clean separation with no code duplication:
- BackgroundLoader orchestrates, doesn't reimplement
- Reuses existing AnimeService, NFOService, WebSocket patterns
- Database-backed status survives restarts
2026-01-19 07:14:55 +01:00
2495b07fc4 Fix: Load series from DB on startup and save missing episodes when adding series 2026-01-18 16:08:30 +01:00
ea9e959a7b Fix double SeriesApp initialization on startup
- Moved sync_series_from_data_files() before DownloadService init
- Ensures series are in DB before main SeriesApp creation
- Eliminates redundant SeriesApp instantiation during startup
- Updated README to clarify initialization sequence
2026-01-18 15:49:58 +01:00
491daa2e50 Fix NFO folder naming to include year
- Add Serie.ensure_folder_with_year() method to ensure folder names include year
- Update all NFO API endpoints to call ensure_folder_with_year() before operations
- Folder format is now 'Name (Year)' when year is available
- Add comprehensive tests for ensure_folder_with_year() method
- All 5 tests passing
2026-01-18 12:28:38 +01:00
c92e2d340e Fix JSON parsing in NFO JavaScript modules
- Add response.json() calls in nfo-manager.js for all API calls
- Add response.json() calls in nfo-config.js for all API calls
- Fix createNFO, refreshNFO, viewNFO, getSeriesWithoutNFO functions
- Fix load and testTMDBConnection functions
- All API responses must be parsed before accessing properties
2026-01-18 12:18:42 +01:00
e502dcb8bd Fix NFO 503 error on server reload with config fallback
- Add dynamic config loading in get_nfo_service() dependency
- Handle settings reset during uvicorn reload in development
- Add comprehensive tests for settings priority and fallback behavior
- All 4 unit tests passing (settings priority, config fallback, error cases)
- Update documentation with reload scenario fix
2026-01-18 12:16:05 +01:00
9877f9400c Fix NFO service 503 error
- Load TMDB API key and NFO settings from config.json
- Sync NFO config to settings during app startup
- NFO endpoints now work correctly (no more 503)
2026-01-18 11:59:57 +01:00
db1e7fa54b Fix NFO database query errors
- Fixed async context manager issue in anime.py (use get_sync_session)
- Fixed async methods in anime_service.py to use async with
- Fixed folder_name attribute error (should be folder)
- All three methods now properly handle database sessions
2026-01-18 11:56:22 +01:00
4e29c4ed80 Enhanced setup and settings pages with full configuration
- Extended SetupRequest model to include all configuration fields
- Updated setup API endpoint to handle comprehensive configuration
- Created new setup.html with organized configuration sections
- Enhanced config modal in index.html with all settings
- Updated JavaScript modules to use unified config API
- Added backup configuration section
- Documented new features in features.md and instructions.md
2026-01-17 18:01:15 +01:00
d676cb7dca Fix NFO API endpoint mismatch in frontend
- Update nfo-manager.js to use correct API routes:
  * POST /api/nfo/{id}/create (was /api/nfo/series/{id})
  * PUT /api/nfo/{id}/update (was /api/nfo/series/{id})
  * GET /api/nfo/{id}/content (was /api/nfo/series/{id})
- Add request body to createNFO with default options
- Fix response handling to check actual API fields
- Remove non-existent getStatistics function
- Fix getSeriesWithoutNFO response structure
- Update instructions.md with fix documentation
2026-01-16 20:48:46 +01:00
120b26b9f7 feat: Add NFO configuration settings (Task 7)
- Added NFOConfig model with TMDB API key, auto-create, media downloads, image size settings
- Created NFO settings section in UI with form fields and validation
- Implemented nfo-config.js module for loading, saving, and testing TMDB connection
- Added TMDB API key validation endpoint (POST /api/config/tmdb/validate)
- Integrated NFO config into AppConfig and ConfigUpdate models
- Added 5 unit tests for NFO config model validation
- Added API test for TMDB validation endpoint
- All 16 config model tests passing, all 10 config API tests passing
- Documented in docs/task7_status.md (100% complete)
2026-01-16 19:33:23 +01:00
ecfa8d3c10 feat: Add NFO UI features (Task 6)
- Extended AnimeSummary model with NFO fields (has_nfo, nfo_created_at, nfo_updated_at, tmdb_id, tvdb_id)
- Updated list_anime endpoint to fetch and return NFO data from database
- Added NFO status badges to series cards (green=exists, gray=missing)
- Created nfo-manager.js module with createNFO, refreshNFO, viewNFO operations
- Added NFO action buttons to series cards (Create/View/Refresh)
- Integrated WebSocket handlers for real-time NFO events (creating, completed, failed)
- Added CSS styles for NFO badges and action buttons
- All 34 NFO API tests passing, all 32 anime endpoint tests passing
- Documented in docs/task6_status.md (90% complete, NFO status page deferred)
2026-01-16 19:18:50 +01:00
d642234814 Complete Task 8: Database Support for NFO Status
- Added 5 NFO tracking fields to AnimeSeries model
- Fields: has_nfo, nfo_created_at, nfo_updated_at, tmdb_id, tvdb_id
- Added 3 service methods to AnimeService for NFO operations
- Methods: update_nfo_status, get_series_without_nfo, get_nfo_statistics
- SQLAlchemy auto-migration (no manual migration needed)
- Backward compatible with existing data
- 15 new tests added (19/19 passing)
- Tests: database models, service methods, integration queries
2026-01-16 18:50:04 +01:00
56b4975d10 Complete Task 5: NFO Management API Endpoints
- Added comprehensive API documentation for NFO endpoints
- Section 6 in API.md with all 8 endpoints documented
- Updated task5_status.md to reflect 100% completion
- Marked Task 5 complete in instructions.md
- All 17 tests passing (1 skipped by design)
- Endpoints: check, create, update, content, media status, download, batch, missing
2026-01-16 18:41:48 +01:00
94f4cc69c4 feat: Task 5 - Add NFO Management API Endpoints (85% complete)
- Create NFO API models (11 Pydantic models)
- Implement 8 REST API endpoints for NFO management
- Register NFO router in FastAPI app
- Create 18 comprehensive API tests
- Add detailed status documentation

Endpoints:
- GET /api/nfo/{id}/check - Check NFO/media status
- POST /api/nfo/{id}/create - Create NFO & media
- PUT /api/nfo/{id}/update - Update NFO
- GET /api/nfo/{id}/content - Get NFO content
- GET /api/nfo/{id}/media/status - Media status
- POST /api/nfo/{id}/media/download - Download media
- POST /api/nfo/batch/create - Batch operations
- GET /api/nfo/missing - List missing NFOs

Remaining: Refactor to use series_app dependency pattern
2026-01-15 20:06:37 +01:00
40ffb99c97 Add year support to anime folder names
- Add year property to Serie entity with name_with_year
- Add year column to AnimeSeries database model
- Add get_year() method to AniworldLoader provider
- Extract year from folder names before fetching from API
- Update SerieScanner to populate year during rescan
- Update add_series endpoint to fetch and store year
- Optimize: check folder name for year before API call
2026-01-11 19:47:47 +01:00
281b982abe Fix: Scanner availability for series addition
- Change 'scanner' to 'serie_scanner' attribute name
- Update tests to match SeriesApp attribute naming
- Scanner now properly detected and called on add
- All add_series tests passing (9/9)
2026-01-11 17:48:37 +01:00
5c0a019e72 Refactor: Defer folder creation to download time
- Remove folder creation from add_series endpoint
- Add folder creation to download() method in SeriesApp
- Maintain database persistence and targeted scanning
- Update tests to use tmp_path fixtures
- All add_series and download tests passing (13/13)
2026-01-11 17:15:59 +01:00
4f2d652a69 Change logging level from DEBUG to INFO
- Update fastapi_app.py to use INFO level instead of DEBUG
- Update development.py config to default to INFO instead of DEBUG
- Update uvicorn log_level from debug to info
- Prevents debug messages from appearing in logs
2026-01-07 19:41:39 +01:00
f39a08d985 Fix event handler TypeError and increase log level to INFO 2026-01-07 19:18:01 +01:00
ab7d78261e Replace asyncio.to_thread with ThreadPoolExecutor.run_in_executor
- Add ThreadPoolExecutor with 3 max workers to SeriesApp
- Replace all asyncio.to_thread calls with loop.run_in_executor
- Add shutdown() method to properly cleanup executor
- Integrate SeriesApp.shutdown() into FastAPI shutdown sequence
- Ensures proper resource cleanup on Ctrl+C (SIGINT/SIGTERM)
2026-01-03 21:04:52 +01:00
b1726968e5 Refactor: Replace CallbackManager with Events pattern
- Replace callback system with events library in SerieScanner
- Update SeriesApp to subscribe to loader and scanner events
- Refactor ScanService to use Events instead of CallbackManager
- Remove CallbackManager imports and callback classes
- Add safe event calling with error handling in SerieScanner
- Update AniworldLoader to use Events for download progress
- Remove progress_callback parameter from download methods
- Update all affected tests for Events pattern
- Fix test_series_app.py for new event subscription model
- Comment out obsolete callback tests in test_scan_service.py

All core tests passing. Events provide cleaner event-driven architecture.
2025-12-30 21:04:45 +01:00
ff9dea0488 removed cancel request 2025-12-30 20:36:02 +01:00
803f35ef39 Update config.json and workspace context as of 27. Dezember 2025 2025-12-27 21:10:53 +01:00
4780f68a23 Fix: Use yt_dlp.utils.DownloadCancelled for proper download cancellation
- Import and use DownloadCancelled exception which YT-DLP properly handles
- Add InterruptedError handling throughout the call chain
- Fire 'cancelled' status event when download is cancelled
- Handle InterruptedError in DownloadService to set CANCELLED status
2025-12-27 19:38:12 +01:00
08f816a954 Fix: Add graceful download cancellation on Ctrl+C
- Add cancellation flag to AniworldLoader with request_cancel/reset_cancel/is_cancelled methods
- Update base_provider.Loader interface with cancellation abstract methods
- Integrate cancellation check in YT-DLP progress hooks
- Add request_download_cancel method to SeriesApp and AnimeService
- Update DownloadService.stop() to request cancellation before shutdown
- Clean up temp files on cancellation
2025-12-27 19:31:57 +01:00
778d16b21a Fix: Use structlog consistently in sync_series_from_data_files 2025-12-27 19:23:54 +01:00
a67a16d6bf Fix: Add missing asyncio import in fastapi_app.py 2025-12-27 19:22:08 +01:00
2e5731b5d6 refactor: split CSS and JS into modular files (SRP) 2025-12-26 13:55:02 +01:00
1b7ca7b4da feat: Enhanced anime add flow with sanitized folders and targeted scan
- Add sanitize_folder_name utility for filesystem-safe folder names
- Add sanitized_folder property to Serie entity
- Update SerieList.add() to use sanitized display names for folders
- Add scan_single_series() method for targeted episode scanning
- Enhance add_series endpoint: DB save -> folder create -> targeted scan
- Update response to include missing_episodes and total_missing
- Add comprehensive unit tests for new functionality
- Update API tests with proper mock support
2025-12-26 12:49:23 +01:00
d70d70e193 feat: implement graceful shutdown with SIGINT/SIGTERM support
- Add WebSocket shutdown() with client notification and graceful close
- Enhance download service stop() with pending state persistence
- Expand FastAPI lifespan shutdown with proper cleanup sequence
- Add SQLite WAL checkpoint before database close
- Update stop_server.sh to use SIGTERM with timeout fallback
- Configure uvicorn timeout_graceful_shutdown=30s
- Update ARCHITECTURE.md with shutdown documentation
2025-12-25 18:59:07 +01:00
1ba67357dc Add database transaction support with atomic operations
- Create transaction.py with @transactional decorator, atomic() context manager
- Add TransactionPropagation modes: REQUIRED, REQUIRES_NEW, NESTED
- Add savepoint support for nested transactions with partial rollback
- Update connection.py with TransactionManager, get_transactional_session
- Update service.py with bulk operations (bulk_mark_downloaded, bulk_delete)
- Wrap QueueRepository.save_item() and clear_all() in atomic transactions
- Add comprehensive tests (66 transaction tests, 90% coverage)
- All 1090 tests passing
2025-12-25 18:05:33 +01:00
b2728a7cf4 style: simplify status-indicator by removing background and border 2025-12-25 13:24:31 +01:00
9f4ea84b47 Improve scan status indicator reliability on page reload
- Add debug logging to checkActiveScanStatus() for better tracing
- Update status indicator before showing overlay for faster feedback
- Add warning logs when DOM elements are not found
- Ensure idle state is explicitly set when no scan is running
- Add debug logging to AnimeService.get_scan_status()
2025-12-25 13:19:10 +01:00
9e393adb00 fix: rescan-status indicator now updates and is clickable after page reload
- Added defensive check for rescan-status element before adding event listener
- Added e.stopPropagation() to prevent click event bubbling issues
- Added console logging for debugging click events
- Call checkActiveScanStatus() directly in init() method, not just on socket connect
  This ensures scan status is checked immediately on page load even if WebSocket
  connection is delayed
2025-12-24 21:35:57 +01:00
458ca1d776 Improve scan overlay UX
- Show overlay immediately when rescan is clicked (before API response)
- Add click-outside-to-close on overlay background
- Add click on rescan-status indicator to reopen overlay
- Add cursor pointer to rescan-status for clickability feedback
- All 1024 tests passing
2025-12-24 21:27:32 +01:00
b6d44ca7d8 Prevent concurrent rescans with async lock
- Add _scan_lock asyncio.Lock to AnimeService
- Check if lock is held before starting rescan
- Use async with to ensure lock is released on completion or exception
- All 1024 tests passing
2025-12-24 21:10:19 +01:00