diff --git a/instructions.md b/instructions.md index f91ce74..607428a 100644 --- a/instructions.md +++ b/instructions.md @@ -159,353 +159,13 @@ For each task completed: ### Phase 1: Core Models and Data Layer -#### Task 1.1: Update Serie Class to Enforce Key as Primary Identifier - -**File:** [`src/core/entities/series.py`](src/core/entities/series.py) - -**Objective:** Ensure `Serie` class uses `key` as the primary identifier and add validation. - -**Steps:** - -1. Open [`src/core/entities/series.py`](src/core/entities/series.py) -2. Add validation in `__init__` to ensure `key` is never empty -3. Add a docstring clarifying that `key` is the unique identifier -4. Add validation to prevent `key` from being set to empty string -5. Ensure `folder` is documented as "filesystem folder name (metadata only)" - -**Success Criteria:** - -- [x] `key` property has validation preventing empty values -- [x] Docstrings clearly state `key` is the unique identifier -- [x] `folder` is documented as metadata only -- [x] All existing tests for `Serie` still pass - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/test_anime_models.py -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- Added comprehensive validation in `__init__` to ensure `key` is never empty or whitespace -- Added validation in `key` setter to prevent setting empty values -- Key values are automatically stripped of whitespace -- Added detailed docstrings explaining `key` as the unique identifier -- Documented `folder` as "filesystem folder name (metadata only, not used for lookups)" -- Created comprehensive test suite in `tests/unit/test_serie_class.py` with 16 tests covering: - - Key validation (empty, whitespace, valid values) - - Key setter validation - - Whitespace stripping behavior - - String representation - - Serialization/deserialization (to_dict/from_dict) - - File save/load functionality - - Documentation completeness -- All 56 Serie-related tests pass successfully - ---- - -#### Task 1.2: Update SerieList to Use Key for Lookups - -**File:** [`src/core/entities/SerieList.py`](src/core/entities/SerieList.py) - -**Objective:** Change `SerieList` internal storage to use `key` instead of `folder` as the dictionary key. - -**Steps:** - -1. Open [`src/core/entities/SerieList.py`](src/core/entities/SerieList.py) -2. Change `self.folderDict` to `self.keyDict` (rename for clarity) -3. Update `add()` method to use `serie.key` as dictionary key -4. Update `contains()` method to check by `key` instead of `folder` -5. Update `load_series()` to store series by `key` -6. Update all internal methods that access the dictionary -7. Add helper method `get_by_key(key: str) -> Optional[Serie]` -8. Add helper method `get_by_folder(folder: str) -> Optional[Serie]` for backward compatibility - -**Success Criteria:** - -- [x] Internal dictionary keyed by `serie.key` -- [x] `add()`, `contains()`, `GetList()` work correctly -- [x] Helper methods `get_by_key()` and `get_by_folder()` implemented -- [x] All existing tests pass -- [x] No breaking changes to public API - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/ -k "SerieList" -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- Renamed `self.folderDict` to `self.keyDict` for clarity -- Updated internal storage to use `serie.key` as dictionary key -- Modified `add()` method to store series by key: `self.keyDict[serie.key] = serie` -- Optimized `contains()` method to use direct dictionary lookup: `return key in self.keyDict` -- Updated `_load_data()` to store loaded series by key with enhanced logging -- All methods (`GetMissingEpisode()`, `GetList()`, etc.) now iterate over `self.keyDict.values()` -- Added `get_by_key(key: str) -> Optional[Serie]` as primary lookup method -- Added `get_by_folder(folder: str) -> Optional[Serie]` for backward compatibility -- Created comprehensive test suite in `tests/unit/test_serie_list.py` with 12 tests covering: - - Key-based storage initialization - - Add, contains, and retrieval operations - - Duplicate prevention by key - - Helper method functionality (get_by_key, get_by_folder) - - Public API compatibility - - File loading and persistence -- All 12 new tests pass successfully -- All 16 SeriesApp tests pass, confirming no breaking changes -- Enhanced docstrings to clarify `key` as identifier and `folder` as metadata - ---- - -#### Task 1.3: Update SerieScanner to Use Key Consistently - -**File:** [`src/core/SerieScanner.py`](src/core/SerieScanner.py) - -**Objective:** Ensure `SerieScanner` identifies and stores series by `key`. - -**Steps:** - -1. Open [`src/core/SerieScanner.py`](src/core/SerieScanner.py) -2. Update `scan()` method to use `serie.key` for all operations -3. Update `self.folderDict` to use `key` as dictionary key (or rename to `self.keyDict`) -4. Ensure all error logging and progress callbacks reference `key` not `folder` -5. Update `__read_data_from_file()` to validate `key` exists before proceeding -6. Add debug logging showing both `key` and `folder` for clarity - -**Success Criteria:** - -- [x] Scanner stores series by `key` -- [x] Progress callbacks use `key` for identification -- [x] Error messages reference `key` and `folder` appropriately -- [x] All scanner tests pass - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/ -k "SerieScanner" -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- Renamed `self.folderDict` to `self.keyDict` for clarity and consistency -- Updated internal dictionary storage to use `serie.key` as the dictionary key -- Modified `scan()` method to store series by key: `self.keyDict[serie.key] = serie` -- Enhanced logging in duplicate detection to show both key and folder for clarity -- Added debug logging when storing series showing both identifiers -- Updated error contexts in exception handlers to include both `key` and `folder` in metadata -- Updated completion statistics to use `len(self.keyDict)` for series count -- Updated `reinit()` method docstring to reflect key-based storage -- Enhanced `__read_data_from_file()` docstring to clarify that `folder_name` is only used to locate data files -- All error messages now properly reference both `key` (identifier) and `folder` (metadata) -- All 554 unit tests pass successfully, confirming no regressions -- Code follows PEP 8 style guidelines (max 79 characters per line) - ---- - -#### Task 1.4: Update Provider Classes to Use Key - -**Files:** - -- [`src/core/providers/aniworld_provider.py`](src/core/providers/aniworld_provider.py) -- [`src/core/providers/enhanced_provider.py`](src/core/providers/enhanced_provider.py) - -**Objective:** Update provider download methods to use `key` for identification while keeping `serieFolder` for filesystem operations. - -**Steps:** - -1. Open [`src/core/providers/aniworld_provider.py`](src/core/providers/aniworld_provider.py) -2. Update `download()` method signature: - - Add `key: str` parameter as first identifier parameter - - Keep `serie_folder: str` parameter for filesystem operations - - Update docstring to clarify: `key` is the series identifier, `serie_folder` is for file paths -3. Update all logging and error messages to reference `key` instead of folder -4. Repeat for [`src/core/providers/enhanced_provider.py`](src/core/providers/enhanced_provider.py) -5. Update the `Download()` method similarly -6. Ensure all error handling and recovery logic uses `key` for identification - -**Success Criteria:** - -- [x] Both provider classes accept `key` as primary identifier -- [x] `serie_folder` only used for file path construction -- [x] Logging references `key` for identification -- [x] All error messages use `key` -- [x] All provider tests pass - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/ -k "provider" -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- Enhanced `download()` method docstring in `aniworld_provider.py` with comprehensive parameter documentation -- Clarified that `serie_folder` is "filesystem folder name (metadata only, used for file path construction)" -- Clarified that `key` is "series unique identifier from provider (used for identification and API calls)" -- Enhanced `Download()` method docstring in `enhanced_provider.py` with comprehensive parameter documentation -- Included Args, Returns, and Raises sections in docstrings following PEP 257 -- Verified existing logging already uses `key` for identification (line 227 in aniworld_provider.py) -- Verified existing error messages already use `key` for identification (lines 456, 466 in enhanced_provider.py) -- Fixed PEP 8 line length issue by splitting long logging statement -- All 34 provider-related tests pass successfully with no regressions -- Both classes already had `key` parameter in correct position with proper usage -- No functional changes required, only documentation improvements - ---- - -#### Task 1.5: Update Provider Factory to Use Key - -**File:** `src/core/providers/provider_factory.py` - -**Objective:** Ensure provider factory uses `key` for provider selection and series identification. - -**Steps:** - -1. Open `src/core/providers/provider_factory.py` -2. Review `get_provider()` method and ensure it can work with `key` -3. Update any caching or provider lookup logic to use `key` -4. Ensure provider instances receive `key` for operations -5. Update docstrings - -**Success Criteria:** - -- [x] Provider factory works with `key` identifiers -- [x] No breaking changes to provider interface -- [x] All provider factory tests pass - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/ -k "provider_factory" -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- Added comprehensive module-level docstring explaining the distinction between provider keys and series keys -- Enhanced `Loaders` class docstring with detailed documentation of its purpose and attributes -- Added comprehensive docstring to `GetLoader()` method explaining: - - Provider key vs series key distinction - - Parameter usage and return value - - Raises clause documenting KeyError exception - - Note clarifying the two-level key usage (provider key in factory, series key in providers) -- Added type hint `Dict[str, Loader]` to `self.dict` attribute for better type safety -- Added return type hint `-> None` to `__init__` method -- Verified provider factory already correctly uses `key` for provider identification -- Verified provider instances (via Loader interface) use `key` for series identification -- No functional changes required - existing implementation was already correct -- Documentation now clearly distinguishes between: - - Provider keys: Site identifiers like "aniworld.to" (used by factory) - - Series keys: Unique anime identifiers like "attack-on-titan" (used by providers) -- All 34 provider-related tests pass successfully -- All 16 SeriesApp tests pass, confirming no breaking changes in Loaders integration -- Code follows PEP 8 and PEP 257 standards +✅ **All Phase 1 tasks completed and committed to git** --- ### Phase 2: Core Application Layer -#### Task 2.1: Update SeriesApp to Use Key for All Operations - -**File:** [`src/core/SeriesApp.py`](src/core/SeriesApp.py) - -**Objective:** Standardize `SeriesApp` to use `key` instead of `folder` for series identification. - -**Steps:** - -1. Open [`src/core/SeriesApp.py`](src/core/SeriesApp.py) -2. Update `download()` method signature: - - Keep `serie_folder` parameter for filesystem operations - - Add docstring clarifying `serie_folder` is for file paths only - - Ensure `key` is the primary lookup identifier -3. Update all internal lookups to use `key` -4. Update event emissions to include both `key` and `folder` -5. Add helper method `_get_serie_by_key(key: str) -> Optional[Serie]` -6. Ensure all method docstrings clarify identifier usage - -**Success Criteria:** - -- [x] All methods use `key` for series identification -- [x] `serie_folder` only used for filesystem operations -- [x] Events include both `key` and `folder` -- [x] Docstrings are clear about parameter usage -- [x] All SeriesApp tests pass - -**Test Command:** - -```bash -conda run -n AniWorld python -m pytest tests/unit/test_series_app.py -v -``` - -**Status:** ✅ COMPLETED - -**Implementation Details:** - -- **Import Added**: Imported `Serie` class from `src.core.entities.series` for type hints -- **DownloadStatusEventArgs Updated**: - - Added `key: Optional[str] = None` parameter to constructor - - Updated docstring to clarify `serie_folder` is "metadata only, used for file paths" - - Updated docstring to clarify `key` is "Serie unique identifier (provider key, primary identifier)" - - All event emissions now include both `key` and `folder` for complete context -- **ScanStatusEventArgs Updated**: - - Added `key: Optional[str] = None` parameter to constructor - - Updated docstring to clarify `folder` is "metadata only" - - Updated docstring to clarify `key` is "Serie unique identifier if applicable (provider key, primary identifier)" -- **download() Method Enhanced**: - - Updated docstring with comprehensive parameter documentation - - Added explicit note: "The 'key' parameter is the primary identifier for series lookups. The 'serie_folder' parameter is only used for filesystem operations." - - All logging statements now include both `key` (for identification) and `folder` (for context) - - All event emissions include both `key` and `folder`: - - Download started event - - Download progress events - - Download completed event - - Download failed event - - Download error event -- **Helper Method Added**: - - Implemented `_get_serie_by_key(key: str) -> Optional[Serie]` method - - Uses `self.list.get_by_key(key)` for lookups (key-based, not folder-based) - - Comprehensive docstring explaining this is the primary lookup method - - Properly typed with `Optional[Serie]` return type -- **Logging Improvements**: - - All download-related logs now show both key and folder: `"Starting download: %s (key: %s) S%02dE%02d"` - - Provides better context for debugging and monitoring - - Follows PEP 8 line length guidelines (max 79 characters) -- **Code Quality**: - - All docstrings follow PEP 257 standards - - Type hints used throughout - - Lazy logging with % formatting instead of f-strings - - Proper line length (max 79 characters per PEP 8) - - Two blank lines between class definitions -- **Test Updates**: - - Updated `tests/unit/test_download_progress_websocket.py` - - Fixed `MockDownloadArgs` class to include `key` and `item_id` fields - - All mock download event emissions now include `key` parameter - - Ensures backward compatibility and proper event structure -- **Test Results**: - - All 16 SeriesApp tests pass successfully - - All 562 unit tests pass with no regressions - - Test coverage maintained at high level - - No breaking changes to existing functionality - -**Benefits of This Change**: - -1. **Consistency**: Series identification is now consistent throughout the core application layer -2. **Clarity**: Clear separation between identifier (`key`) and metadata (`folder`) -3. **Debugging**: Logs and events show both identifiers for better troubleshooting -4. **Type Safety**: Proper type hints with `Optional[Serie]` return types -5. **Maintainability**: Single source of truth for series lookups via `_get_serie_by_key()` -6. **Backward Compatibility**: All existing functionality preserved, tests pass +✅ **Task 2.1 completed and committed to git** ---