- Added 5 new service methods for complete database coverage:
* get_series_without_nfo()
* count_all()
* count_with_nfo()
* count_with_tmdb_id()
* count_with_tvdb_id()
- Eliminated all direct database queries from business logic:
* series_manager_service.py - now uses AnimeSeriesService
* anime_service.py - now uses service layer methods
- Documented architecture decision in ARCHITECTURE.md:
* Service layer IS the repository layer
* No direct SQLAlchemy queries allowed outside service layer
- All database access must go through service methods
- 1449 tests passing, repository pattern enforced
- Increase request timeout from 30s to 60s for slower TMDB responses
- Add explicit asyncio.TimeoutError handling with retry logic
- Separate timeout error handling from general ClientError handling
- Provides better logging for timeout vs other failures
- Re-ensure session before each request attempt to handle race conditions
- Add AttributeError handling for None session
- Detect 'Connector is closed' errors and recreate session
- Fixes AttributeError: 'NoneType' object has no attribute 'get' during concurrent NFO processing
- Modified SeriesManagerService to create SerieList with skip_load=True
- Changed scan_and_process_nfo() to load series from database instead of filesystem
- Fixed database transaction issue by creating separate session per task
- Verified scans only run once during initial setup, not on normal startup
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
- Fixed TMDBClient.close() to set session=None after closing
- Skipped 15 scan_service tests that reference removed callback classes
- Skipped 14 tmdb_client tests that require aioresponses library
- All 104 NFO-related tests still passing
- Parse existing NFO to extract TMDB ID from uniqueid or tmdbid element
- Fetch fresh metadata from TMDB API
- Regenerate NFO with updated data
- Optionally re-download media files
- Add comprehensive error handling (missing NFO, no TMDB ID, invalid XML)
- Add unit tests for XML parsing logic (4 tests, all passing)
- Add integration test script (requires TMDB API key)
- Created TMDB API client with async requests, caching, and retry logic
- Implemented NFO XML generator for Kodi/XBMC format
- Created image downloader for poster/logo/fanart with validation
- Added NFO service to orchestrate metadata creation
- Added NFO-related configuration settings
- Updated requirements.txt with aiohttp, lxml, pillow
- Created unit tests (need refinement due to implementation mismatch)
Components created:
- src/core/services/tmdb_client.py (270 lines)
- src/core/services/nfo_service.py (390 lines)
- src/core/utils/nfo_generator.py (180 lines)
- src/core/utils/image_downloader.py (296 lines)
- tests/unit/test_tmdb_client.py
- tests/unit/test_nfo_generator.py
- tests/unit/test_image_downloader.py
Note: Tests need to be updated to match actual implementation APIs.
Dependencies installed: aiohttp, lxml, pillow