Commit Graph

35 Commits

Author SHA1 Message Date
75f743e6cc fix: fetch series name from provider when scanning
Avoid 'Series name cannot be empty' error when a Serie is loaded
from a serie_file with an empty name by fetching the title from the
provider after year-fetching in the scan() method.

fix #?
2026-06-02 20:57:27 +02:00
6dfb24de7e backup 2026-06-01 20:07:58 +02:00
00b26c8cbc fix: validate generated keys before creating Serie objects
- Add is_valid_key check in SerieScanner._read_data_from_file() to prevent
  passing invalid keys to Serie constructor (caused ValueError)
- Improve error message for key generation failures
- Add warning log before removing duplicate source folders in rename service
2026-05-30 11:42:19 +02:00
cf001563b3 refactor: add folder rename configuration and service
Add configurable folder rename patterns via settings with anime_folder_rename_regex and custom_pattern options. Integrate into SerieScanner and SeriesApp for consistent episode organization.
2026-05-29 19:24:09 +02:00
4e6afa31b5 Remove legacy key file support after DB migration
- SerieScanner: Remove key file fallback, keep data file fallback
- SystemSettings: Add legacy_key_cleanup_completed flag
- initialization_service: Add cleanup task to remove key files from folders with DB entries
- Tests updated to reflect key file removal from legacy path

Key files caused duplicate key errors on folder rename. DB is now sole source of truth.
2026-05-28 22:01:37 +02:00
14b8ef7f06 Add Step 4 fallback: generate key from folder name
- SerieScanner: generate key from folder when no key/data files exist
- Handle edge cases: non-Latin characters, special symbols in folder names
- anime_service: expose loading_status and loading_error fields
- Update tests to match new fallback behavior
2026-05-28 18:48:43 +02:00
33f63ca304 feat(SerieScanner): add folder ignore patterns for non-anime content
- Add NFO_FOLDER_IGNORE_PATTERNS setting to skip TV shows like
  The Last of Us, Loki, Chernobyl, Star Trek Discovery
- Update SerieScanner.__find_mp4_files() to skip ignored folders
- Update SerieList.load_series() to skip ignored folders
- Add should_ignore_folder() method for pattern matching
- Add folder_ignore_patterns property for pattern parsing
- Add comprehensive tests for ignore pattern functionality
- Update NFO_GUIDE.md with ignore patterns documentation
- Update CONFIGURATION.md with new setting

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 18:11:45 +02:00
fe9284b80e feat(SerieScanner): add warning event for duplicate series keys
- Add on_warning event system with subscribe/unsubscribe methods
- Change duplicate key handling from error to warning
- Fire on_warning event when duplicate series detected
- Include metadata: key, duplicate_folder, existing_folder
2026-05-28 18:05:07 +02:00
d358a07290 fix async handling in SerieScanner and add image_downloader cleanup
- SerieScanner.scan() now detects running event loop and uses create_task()
  when already in async context, avoids RuntimeError
- NFOService.close() now also closes image_downloader to prevent resource leaks
- Add integration tests for TMDBClient lifecycle management

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-27 20:47:29 +02:00
b9c55f9e7a fix: remove double-call on AsyncSession in SerieScanner
get_async_session_factory() returns session directly, not factory.
Calling result again with () caused 'AsyncSession' object is not callable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-27 20:19:34 +02:00
102d83e947 feat(scanner): replace file writes with DB persistence for series
- SerieScanner.scan() now calls _persist_serie_to_db() instead of serie.save_to_file()
- Added _sync_episodes_to_db() helper to handle episode CRUD during sync
- EpisodeService gains delete_by_series() for targeted episode deletion
- SerieList gains add_to_db() async method for DB-based series addition
- test_serie_scanner_db_writes.py covers create/update/preserve/sync scenarios
- DATABASE.md updated with Series Persistence Flow section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 18:12:01 +02:00
841368bf85 feat(SerieScanner): DB lookup primary, deprecate key file fallback
DB now source of truth for folder -> Serie resolution.

Changes:
- AnimeSeriesService.get_by_folder(): new async lookup by folder name
- SerieScanner.__read_data_from_file(): query DB first, then provider callback, then legacy key file (temporary, removed v3.0.0)
- Serie: reconstruct from DB record with episode dict
- Key file: warn on use, scheduled removal v3.0.0

Add unit tests for DB hit/miss/callback/fallback edge cases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 17:56:37 +02:00
d5e955a731 Add year extraction from folder names for existing series
- New migration script: populate year from folder (YYYY) pattern
- SerieScanner: refactor year extraction logic
- anime_service: pass year when syncing from data files
2026-05-25 15:30:28 +02:00
e3509f5c8f feat(scanner): add DB fallback for series key resolution
When SerieScanner encounters a folder without a local key or data file,
it now optionally falls back to a database lookup by folder name. This
prevents newly-added series from being silently skipped on rescan when
their metadata only lives in the DB.

Changes:
- SerieScanner accepts an optional db_lookup callable
- SeriesApp forwards db_lookup to SerieScanner
- AnimeSeriesService adds get_by_folder_sync() helper
- dependencies.py wires a sync DB lookup into get_series_app()
- Unit tests cover fallback hit, miss, and exception paths
2026-05-14 19:28:43 +02: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
f39a08d985 Fix event handler TypeError and increase log level to INFO 2026-01-07 19:18:01 +01:00
055bbf4de6 Fix event subscription bug in SerieScanner and mark checklist complete 2026-01-07 19:01:42 +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
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
596476f9ac refactor: remove database access from core layer
- Remove db_session parameter from SeriesApp, SerieList, SerieScanner
- Move all database operations to AnimeService (service layer)
- Add add_series_to_db, contains_in_db methods to AnimeService
- Update sync_series_from_data_files to use inline DB operations
- Remove obsolete test classes for removed DB methods
- Fix pylint issues: add broad-except comments, fix line lengths
- Core layer (src/core/) now has zero database imports

722 unit tests pass
2025-12-15 15:19:03 +01:00
798461a1ea better db model 2025-12-04 19:22:42 +01:00
e0a7c6baa9 some fixes 2025-12-02 13:24:22 +01:00
46ca4c9aac Task 5: Update SerieScanner to use database storage
- Add db_session parameter to SerieScanner.__init__
- Add async scan_async() method for database-backed scanning
- Add _save_serie_to_db() helper for creating/updating series
- Add _update_serie_in_db() helper for updating existing series
- Add deprecation warning to file-based scan() method
- Maintain backward compatibility for CLI usage
- Add comprehensive unit tests (15 tests, all passing)
- Update instructions.md to mark Task 5 complete
2025-12-01 19:25:28 +01:00
aeb1ebe7a2 Task 1.4: Update provider classes to use key as primary identifier
- Enhanced download() method docstring in aniworld_provider.py
- Enhanced Download() method docstring in enhanced_provider.py
- Clarified that 'key' is the series unique identifier from provider
- Clarified that 'serie_folder'/'serieFolder' is filesystem folder name (metadata only)
- Added comprehensive Args, Returns, and Raises sections to docstrings
- Fixed PEP 8 line length issue in logging statement
- Verified existing code already uses 'key' for identification and logging
- All 34 provider-related tests pass successfully
- No functional changes required, documentation improvements only
2025-11-23 17:51:32 +01:00
920a5b0eaf feat(core): Standardize SerieScanner to use 'key' as primary identifier
Task 1.3: Update SerieScanner to Use Key Consistently

Changes:
- Renamed self.folderDict to self.keyDict for clarity and consistency
- Updated internal storage to use serie.key as dictionary key
- Modified scan() method to store series by key
- Enhanced logging to show both key (identifier) and folder (metadata)
- Added debug logging when storing series
- Updated error contexts to include both key and folder in metadata
- Updated completion statistics to use keyDict
- Enhanced docstrings to clarify identifier vs metadata usage
- Fixed import formatting to comply with PEP 8 line length

Success criteria met:
 Scanner stores series by 'key'
 Progress callbacks use 'key' for identification
 Error messages reference both 'key' and 'folder' appropriately
 All 554 unit tests pass

Related to: Series Identifier Standardization (Phase 1, Task 1.3)
2025-11-23 13:06:33 +01:00
a41c86f1da refactor: remove GlobalLogger and migrate to standard Python logging
- Remove src/infrastructure/logging/GlobalLogger.py
- Update SerieScanner.py to use standard logging.getLogger()
- Update aniworld_provider.py to remove custom noKeyFound_logger setup
- Fix test_dependencies.py to properly mock config_service
- Fix code style issues (line length, formatting)
- All 846 tests passing
2025-10-25 17:27:49 +02:00
c81a493fb1 cleanup 2025-10-23 19:00:49 +02:00
9a64ca5b01 cleanup 2025-10-23 18:10:34 +02:00
92795cf9b3 Improve docs and security defaults 2025-10-22 15:22:58 +02:00
04799633b4 cleanup 2025-10-22 13:38:46 +02:00
f64ba74d93 refactor: Apply PEP8 naming conventions - convert PascalCase methods to snake_case
This comprehensive refactoring applies PEP8 naming conventions across the codebase:

## Core Changes:

### src/cli/Main.py
- Renamed __InitList__() to __init_list__()
- Renamed print_Download_Progress() to print_download_progress()
- Fixed variable naming: task3 -> download_progress_task
- Fixed parameter spacing: words :str -> words: str
- Updated all method calls to use snake_case
- Added comprehensive docstrings

### src/core/SerieScanner.py
- Renamed Scan() to scan()
- Renamed GetTotalToScan() to get_total_to_scan()
- Renamed Reinit() to reinit()
- Renamed private methods to snake_case:
  - __ReadDataFromFile() -> __read_data_from_file()
  - __GetMissingEpisodesAndSeason() -> __get_missing_episodes_and_season()
  - __GetEpisodeAndSeason() -> __get_episode_and_season()
  - __GetEpisodesAndSeasons() -> __get_episodes_and_seasons()
- Added comprehensive docstrings to all methods
- Fixed long line issues

### src/core/providers/base_provider.py
- Refactored abstract base class with proper naming:
  - Search() -> search()
  - IsLanguage() -> is_language()
  - Download() -> download()
  - GetSiteKey() -> get_site_key()
  - GetTitle() -> get_title()
- Added proper type hints (Dict, List, etc.)
- Added comprehensive docstrings explaining contracts
- Fixed newline at end of file

### src/core/providers/aniworld_provider.py
- Renamed public methods to snake_case:
  - Search() -> search()
  - IsLanguage() -> is_language()
  - Download() -> download()
  - GetSiteKey() -> get_site_key()
  - GetTitle() -> get_title()
  - ClearCache() -> clear_cache()
  - RemoveFromCache() -> remove_from_cache()
- Renamed private methods to snake_case:
  - _GetLanguageKey() -> _get_language_key()
  - _GetKeyHTML() -> _get_key_html()
  - _GetEpisodeHTML() -> _get_episode_html()
- Fixed import organization
- Improved code formatting and line lengths
- Added docstrings to all methods

### src/core/SeriesApp.py
- Updated all calls to use new snake_case method names
- Updated loader calls: loader.Search() -> loader.search()
- Updated loader calls: loader.Download() -> loader.download()
- Updated scanner calls: SerieScanner.GetTotalToScan() -> SerieScanner.get_total_to_scan()
- Updated scanner calls: SerieScanner.Reinit() -> SerieScanner.reinit()
- Updated scanner calls: SerieScanner.Scan() -> SerieScanner.scan()

### tests/unit/test_series_app.py
- Updated mock calls to use new snake_case method names:
  - get_total_to_scan() instead of GetTotalToScan()
  - reinit() instead of Reinit()
  - scan() instead of Scan()

## Verification:
- All unit tests pass 
- All integration tests pass 
- All tests pass 
- No breaking changes to functionality

## Standards Applied:
- PEP 8: Function/method names use lowercase with underscores (snake_case)
- PEP 257: Added comprehensive docstrings
- Type hints: Proper type annotations where applicable
- Code formatting: Fixed line lengths and spacing
2025-10-22 12:44:42 +02:00
a0f32b1a00 feat: Implement comprehensive progress callback system
- Created callback interfaces (ProgressCallback, ErrorCallback, CompletionCallback)
- Defined rich context objects (ProgressContext, ErrorContext, CompletionContext)
- Implemented CallbackManager for managing multiple callbacks
- Integrated callbacks into SerieScanner for scan progress reporting
- Enhanced SeriesApp with download progress tracking via callbacks
- Added error and completion notifications throughout core operations
- Maintained backward compatibility with legacy callback system
- Created 22 comprehensive unit tests with 100% pass rate
- Updated infrastructure.md with callback system documentation
- Removed completed tasks from instructions.md

The callback system provides:
- Real-time progress updates with percentage and phase tracking
- Comprehensive error reporting with recovery information
- Operation completion notifications with statistics
- Thread-safe callback execution with exception handling
- Support for multiple simultaneous callbacks per type
2025-10-17 20:05:57 +02:00
7a71715183 backup 2025-10-12 18:05:31 +02:00
85f2d2c6f7 cleanup 2 2025-10-05 22:22:04 +02:00
e477780ed6 refactoring 2025-09-29 21:18:42 +02:00