Commit Graph

300 Commits

Author SHA1 Message Date
27108aacda Fix architecture issues from todolist
- Add documentation warnings for in-memory rate limiting and failed login attempts
- Consolidate duplicate health endpoints into api/health.py
- Fix CLI to use correct async rescan method names
- Update download.py and anime.py to use custom exception classes
- Add WebSocket room validation and rate limiting
2025-12-15 14:23:41 +01:00
1652f2f6af feat: rescan now saves to database instead of data files
- Update SeriesApp.rescan() to use database storage by default (use_database=True)
- Use SerieScanner.scan_async() for database mode, which saves directly to DB
- Fall back to legacy file-based scan() when use_database=False (for CLI compatibility)
- Reinitialize SerieList from database after scan when in database mode
- Update unit tests to use use_database=False for mocked tests
- Add parameter to control storage mode for backward compatibility
2025-12-13 20:37:03 +01:00
3cb644add4 fix: resolve pylint and type-checking issues
- Fix return type annotation in SetupRedirectMiddleware.dispatch() to use Response instead of RedirectResponse
- Replace broad 'except Exception' with specific exception types (FileNotFoundError, ValueError, OSError, etc.)
- Rename AppConfig.validate() to validate_config() to avoid shadowing BaseModel.validate()
- Fix ValidationResult.errors field to use List[str] with default_factory
- Add pylint disable comments for intentional broad exception catches during shutdown
- Rename lifespan parameter to _application to indicate unused variable
- Update all callers to use new validate_config() method name
2025-12-13 20:29:07 +01:00
63742bb369 fix: handle empty series name in data file sync
- Use folder name as fallback when series name is empty
- Skip series with both empty name and folder
- Add try/catch for individual series to prevent one failure
  from stopping the entire sync
2025-12-13 10:12:53 +01:00
8373da8547 style: fix import ordering in auth.py and config.py 2025-12-13 10:02:15 +01:00
38e0ba0484 feat: sync series from data files after setup/directory update
- Call sync_series_from_data_files after initial setup completes
- Call sync_series_from_data_files when anime directory is updated
- Return synced_series count in directory update response
2025-12-13 10:00:40 +01:00
5f6ac8e507 refactor: move sync_series_from_data_files to anime_service
- Moved _sync_series_to_database from fastapi_app.py to anime_service.py
- Renamed to sync_series_from_data_files for better clarity
- Updated all imports and test references
- Removed completed TODO tasks from instructions.md
2025-12-13 09:58:32 +01:00
684337fd0c Add data file to database sync functionality
- Add get_all_series_from_data_files() to SeriesApp
- Sync series from data files to DB on startup
- Add unit tests for new SeriesApp method
- Add integration tests for sync functionality
- Update documentation
2025-12-13 09:32:57 +01:00
86eaa8a680 cleanup 2025-12-13 09:09:48 +01:00
ee317b29f1 Remove migration code and alembic dependency 2025-12-13 09:02:26 +01:00
842f9c88eb migration removed 2025-12-10 21:12:34 +01:00
99f79e4c29 fix queue error 2025-12-10 20:55:09 +01:00
798461a1ea better db model 2025-12-04 19:22:42 +01:00
942f14f746 Fix incorrect import path for settings module 2025-12-02 17:54:06 +01:00
7c56c8bef2 Fix download service init when anime dir not configured 2025-12-02 17:36:41 +01:00
b0f3b643c7 Migrate download queue from JSON to SQLite database
- Created QueueRepository adapter in src/server/services/queue_repository.py
- Refactored DownloadService to use repository pattern instead of JSON
- Updated application startup to initialize download service from database
- Updated all test fixtures to use MockQueueRepository
- All 1104 tests passing
2025-12-02 16:01:25 +01:00
4347057c06 soem fixes 2025-12-02 14:04:37 +01:00
e0a7c6baa9 some fixes 2025-12-02 13:24:22 +01:00
396b243d59 chore: Add deprecation warnings and update documentation (Task 9)
Task 9: Clean up legacy code
- Added deprecation warnings to Serie.save_to_file() and load_from_file()
- Updated infrastructure.md with Data Storage section documenting:
  - SQLite database as primary storage
  - Legacy file storage as deprecated
  - Data migration process
- Added deprecation warning tests for Serie class
- Updated existing tests to handle new warnings
- All 1012 tests pass (872 unit + 55 API + 85 integration)
2025-12-01 19:55:15 +01:00
cb014cf547 feat(core): Add database support to SeriesApp (Task 7)
- Added db_session parameter to SeriesApp.__init__()
- Added db_session property and set_db_session() method
- Added init_from_db_async() for async database initialization
- Pass db_session to SerieList and SerieScanner during construction
- Added get_series_app_with_db() dependency for FastAPI endpoints
- All 815 unit tests and 55 API tests pass
2025-12-01 19:42:04 +01:00
246782292f feat(api): Update anime API endpoints to use database storage
Task 6: Update Anime API endpoints to use database
- Modified add_series endpoint to save series to database when available
- Added get_optional_database_session dependency for graceful fallback
- Falls back to file-based storage when database unavailable
- All 55 API tests and 809 unit tests pass
2025-12-01 19:34:41 +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
795f83ada5 Task 4: Update SerieList to use database storage
- Add db_session and skip_load parameters to SerieList.__init__
- Add async load_series_from_db() method for database loading
- Add async add_to_db() method for database storage
- Add async contains_in_db() method for database checks
- Add _convert_from_db() and _convert_to_db_dict() helper methods
- Add deprecation warnings to file-based add() method
- Maintain backward compatibility for file-based operations
- Add comprehensive unit tests (29 tests, all passing)
- Update instructions.md to mark Task 4 complete
2025-12-01 19:18:50 +01:00
646385b975 task1 2025-12-01 19:10:02 +01:00
148e6c1b58 Integrate data migration into FastAPI lifespan (Task 3) 2025-12-01 18:16:54 +01:00
de58161014 Add startup migration runner (Task 2) 2025-12-01 18:13:16 +01:00
7e2d3dd5ab Add DataMigrationService for file-to-database migration (Task 1) 2025-12-01 18:09:38 +01:00
36acd3999e Complete Phase 9: Final validation for identifier standardization
- Fix search API key extraction from link slugs
- All 1006 tests pass
- All 19 performance tests pass
- Manual end-to-end testing verified
- Key lookup performance: O(1) ~0.11μs per lookup

Phase 9 tasks completed:
- Task 9.1: Full test suite validation
- Task 9.2: Manual end-to-end testing
- Task 9.3: Performance testing

All identifier standardization phases (1-9) now complete.
2025-11-28 18:46:35 +01:00
85a6b053eb Phase 8: Documentation and deprecation warnings for identifier standardization
- Enhanced infrastructure.md with identifier convention table, format requirements, migration notes
- Updated docs/README.md with series identifier convention section
- Updated docs/api_reference.md with key-based API examples and notes
- Added deprecation warnings to SerieList.get_by_folder()
- Added deprecation warnings to anime.py folder fallback lookup
- Added deprecation warnings to validate_series_key_or_folder()
- All warnings include v3.0.0 removal timeline
- All 1006 tests pass
2025-11-28 18:06:04 +01:00
0c8b296aa6 Phase 6: Update database layer identifier documentation
- Updated AnimeSeries model docstring to clarify key is primary identifier
- Updated folder field to indicate metadata-only usage
- Updated AnimeSeriesService docstring and get_by_key method
- Updated infrastructure.md with database identifier documentation
- All 996 tests passing
2025-11-28 17:19:30 +01:00
a833077f97 Phase 5: Frontend - Use key as primary series identifier
- Updated app.js to use 'key' as primary series identifier
  - selectedSeries Set now uses key instead of folder
  - createSerieCard() uses data-key attribute for identification
  - toggleSerieSelection() uses key for lookups
  - downloadSelected() iterates with key values
  - updateSelectionUI() and toggleSelectAll() use key

- Updated WebSocket service tests
  - Tests now include key and folder in broadcast data
  - Verified both fields are included in messages

- No changes needed for queue.js and other JS files
  - They use download item IDs correctly, not series identifiers

- No template changes needed
  - Series cards rendered dynamically in app.js

All 996 tests passing
2025-11-28 16:18:33 +01:00
5934c7666c Task 4.7: Update template helpers to use key identifier
- Add series context helpers: prepare_series_context, get_series_by_key, filter_series_by_missing_episodes
- Update module docstring with identifier convention documentation
- Add unit tests for new series context helper functions
- Update infrastructure.md with template helpers documentation
- Mark Phase 4 (API Layer) as complete
2025-11-28 16:00:15 +01:00
c00224467f feat: Add validate_series_key() validator for key-based identification (Task 4.6)
- Add validate_series_key() function that validates URL-safe, lowercase,
  hyphen-separated series keys (e.g., 'attack-on-titan')
- Add validate_series_key_or_folder() for backward compatibility during
  transition from folder-based to key-based identification
- Create comprehensive test suite with 99 test cases for all validators
- Update infrastructure.md with validation utilities documentation
- Mark Task 4.6 as complete in instructions.md

Test: conda run -n AniWorld python -m pytest tests/unit/test_validators.py -v
All 99 validator tests pass, 718 total unit tests pass
2025-11-28 07:13:46 +01:00
08c7264d7a chore: Minor formatting fixes (whitespace cleanup) 2025-11-28 07:08:32 +01:00
6d2a791a9d Task 4.5: Update Pydantic models to use key as primary identifier
- Updated AnimeSeriesResponse and SearchResult models in anime.py:
  - Changed 'id' field to 'key' as the primary series identifier
  - Added 'folder' as optional metadata field
  - Added field validator to normalize key to lowercase and strip whitespace
  - Added comprehensive docstrings explaining identifier usage

- Updated DownloadItem and DownloadRequest models in download.py:
  - Added field validator for serie_id normalization (lowercase, stripped)
  - Improved documentation for serie_id (primary identifier) vs serie_folder (metadata)

- Updated test_anime_models.py with comprehensive tests:
  - Tests for key normalization and whitespace stripping
  - Tests for folder as optional metadata
  - Reorganized tests into proper class structure

- Updated test_download_models.py with validator tests:
  - Tests for serie_id normalization in DownloadItem
  - Tests for serie_id normalization in DownloadRequest

All 885 tests pass.
2025-11-27 20:01:33 +01:00
3c8ba1d48c Task 4.4: Update WebSocket API Endpoints to use key identifier
- Updated src/server/api/websocket.py docstrings to document key as primary series identifier
- Updated src/server/models/websocket.py with detailed docstrings explaining key and folder fields in message payloads
- Updated src/server/services/websocket_service.py broadcast method docstrings to document key field usage
- Added WebSocket message example with key in infrastructure.md
- All 83 WebSocket tests pass
- Task 4.4 marked as complete in instructions.md
2025-11-27 19:52:53 +01:00
589141e9aa Task 4.2: Update Download API Endpoints to Use Key
- Updated DownloadRequest and DownloadItem models with comprehensive
  docstrings explaining serie_id (key as primary identifier) vs
  serie_folder (filesystem metadata)
- Updated add_to_queue() endpoint docstring to document request parameters
- Updated all test files to include required serie_folder field:
  - tests/api/test_download_endpoints.py
  - tests/api/test_queue_features.py
  - tests/frontend/test_existing_ui_integration.py
  - tests/integration/test_download_flow.py
- Updated infrastructure.md with Download Queue request/response models
- All 869 tests pass

This is part of the Series Identifier Standardization effort (Phase 4.2)
to ensure key is used as the primary identifier throughout the codebase.
2025-11-27 19:33:06 +01:00
ff5b364852 Task 4.1: Update Anime API Endpoints to use key as primary identifier
- Updated AnimeSummary model with enhanced documentation:
  - key as primary identifier (unique series identifier)
  - folder as metadata only (not used for lookups)
  - Added Field descriptions for all attributes

- Updated AnimeDetail model:
  - Replaced 'id' field with 'key' field
  - Added 'folder' field as metadata
  - Enhanced documentation and JSON schema example

- Updated get_anime() endpoint:
  - Primary lookup by 'key' (preferred)
  - Fallback lookup by 'folder' (backward compatibility)
  - Updated docstring to clarify identifier usage

- Updated add_series() endpoint:
  - Extracts key from link URL (/anime/stream/{key})
  - Returns both key and folder in response
  - Enhanced docstring with parameter descriptions

- Updated _perform_search():
  - Uses key as primary identifier
  - Extracts key from link URL if not present
  - Enhanced docstring with return value details

- Updated list_anime() and search endpoint docstrings:
  - Clarified key as primary identifier
  - Documented folder as metadata only

- Updated instructions.md:
  - Marked Task 4.1 as completed
  - Updated task tracking section

- Updated infrastructure.md:
  - Updated API endpoints documentation
  - Added response model details

All anime API tests passing (11/11)
All unit tests passing (604/604)
2025-11-27 19:02:19 +01:00
6726c176b2 feat(Task 3.4): Implement ScanService with key-based identification
- Create ScanService class (src/server/services/scan_service.py)
  - Use 'key' as primary series identifier throughout
  - Include 'folder' as metadata only for display purposes
  - Implement scan progress tracking via ProgressService
  - Add callback classes for progress, error, and completion
  - Support scan event subscription and broadcasting
  - Maintain scan history with configurable limit
  - Provide cancellation support for in-progress scans

- Create comprehensive unit tests (tests/unit/test_scan_service.py)
  - 38 tests covering all functionality
  - Test ScanProgress dataclass serialization
  - Test callback classes (progress, error, completion)
  - Test service lifecycle (start, cancel, status)
  - Test event subscription and broadcasting
  - Test key-based identification throughout
  - Test singleton pattern

- Update infrastructure.md with ScanService documentation
  - Document service overview and key features
  - Document components and event types
  - Document integration points
  - Include usage example

- Update instructions.md
  - Mark Task 3.4 as complete
  - Mark Phase 3 as fully complete
  - Remove finished task definition

Task: Phase 3, Task 3.4 - Update ScanService to Use Key
Completion Date: November 27, 2025
2025-11-27 18:50:02 +01:00
fb2cdd4bb6 Task 3.3: Update ProgressService to use key as identifier
- Added optional 'key' and 'folder' fields to ProgressUpdate dataclass
- key: Primary series identifier (provider key, e.g., 'attack-on-titan')
- folder: Optional series folder name for display (e.g., 'Attack on Titan (2013)')
- Updated start_progress() and update_progress() methods to accept key/folder parameters
- Enhanced to_dict() serialization to include key/folder when present
- Updated all docstrings to clarify identifier usage
- Added 5 new comprehensive unit tests for key/folder functionality
- All 25 ProgressService tests passing
- Updated infrastructure.md with series identifier documentation
- Maintains backward compatibility - fields are optional
- Completed Phase 3, Task 3.3 of identifier standardization initiative
2025-11-27 18:36:35 +01:00
e8129f847c feat: Complete Task 3.2 - Update AnimeService to use key as primary identifier
- Enhanced class and method docstrings to clarify 'key' as primary identifier
- Documented that 'folder' is metadata only (display and filesystem operations)
- Updated event handler documentation to show both key and folder are received
- Modernized type hints to Python 3.9+ style (list[dict] vs List[dict])
- Fixed PEP 8 line length violations
- All 18 anime service tests passing

Implementation follows identifier standardization initiative:
- key: Primary series identifier (provider-assigned, URL-safe)
- folder: Metadata for display and filesystem paths only

Task 3.2 completed November 23, 2025
Documented in infrastructure.md and instructions.md
2025-11-23 20:19:04 +01:00
e1c8b616a8 Task 3.1: Standardize series identifiers in DownloadService
- Updated DownloadService to use 'serie_id' (provider key) for identification
- Changed 'serie_folder' from Optional to required in models (DownloadItem, DownloadRequest)
- Removed incorrect fallback logic that used serie_id as folder name
- Enhanced docstrings to clarify purpose of each identifier field:
  * serie_id: Provider key (e.g., 'attack-on-titan') for lookups
  * serie_folder: Filesystem folder name (e.g., 'Attack on Titan (2013)') for file operations
- Updated logging to reference 'serie_key' for clarity
- Fixed all unit tests to include required serie_folder field
- All 25 download service tests passing
- All 47 download model tests passing
- Updated infrastructure.md with detailed documentation
- Marked Task 3.1 as completed in instructions.md

Benefits:
- Clear separation between provider identifier and filesystem path
- Prevents confusion from mixing different identifier types
- Consistent with broader series identifier standardization effort
- Better error messages when required fields are missing
2025-11-23 20:13:24 +01:00
883f89b113 Add series key metadata to callback contexts 2025-11-23 20:02:11 +01:00
5c08bac248 style: reorder imports in SeriesApp.py
Minor formatting change - imports reordered alphabetically
2025-11-23 19:54:19 +01:00
8443de4e0f feat(core): standardize SeriesApp to use key as primary identifier
Task 2.1 - Update SeriesApp to Use Key for All Operations

Changes:
- Added 'key' field to DownloadStatusEventArgs and ScanStatusEventArgs
- Updated download() method docstrings to clarify key vs folder usage
- Implemented _get_serie_by_key() helper method for series lookups
- Updated all event emissions to include both key (identifier) and folder (metadata)
- Enhanced logging to show both key and folder for better debugging
- Fixed test mocks to include new key and item_id fields

Benefits:
- Consistent series identification throughout core application layer
- Clear separation between identifier (key) and metadata (folder)
- Better debugging with comprehensive log messages
- Type-safe lookups with Optional[Serie] return types
- Single source of truth for series lookups

Test Results:
- All 16 SeriesApp tests pass
- All 562 unit tests pass with no regressions
- No breaking changes to existing functionality

Follows:
- PEP 8 style guidelines (max 79 chars per line)
- PEP 257 docstring standards
- Project coding standards (type hints, error handling, logging)
2025-11-23 19:51:26 +01:00
51cd319a24 Task 1.5: Update Provider Factory documentation for key usage
- Added comprehensive module-level docstring explaining provider vs series keys
- Enhanced Loaders class docstring with purpose and attributes documentation
- Added detailed docstring to GetLoader() method with Args/Returns/Raises sections
- Added type hints: Dict[str, Loader] for self.dict and -> None for __init__
- Clarified distinction between provider keys (e.g., 'aniworld.to') and series keys
- No functional changes - existing implementation already correct
- All 34 provider tests pass
- All 16 SeriesApp tests pass
- Updated instructions.md to mark Task 1.5 as completed
- Follows PEP 8 and PEP 257 standards
2025-11-23 19:45:22 +01:00
c4ec6c9f0e Task 1.1: Fix PEP 8 compliance in Serie class
- Fixed line length issues (max 79 chars)
- Added UTF-8 encoding to file operations
- Fixed blank line formatting
- Improved code formatting in __str__, to_dict, from_dict methods
- All docstrings now comply with PEP 8
- All 16 Serie class tests pass
- All 5 anime model tests pass
- No functional changes, only style improvements
2025-11-23 19:38:26 +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
8b5b06ca9a feat: Standardize SerieList to use key as primary identifier (Task 1.2)
- Renamed folderDict to keyDict for clarity
- Updated internal storage to use serie.key instead of serie.folder
- Optimized contains() from O(n) to O(1) with direct key lookup
- Added get_by_key() as primary lookup method
- Added get_by_folder() for backward compatibility
- Enhanced docstrings to clarify key vs folder usage
- Created comprehensive test suite (12 tests, all passing)
- Verified no breaking changes (16 SeriesApp tests pass)

This establishes key as the single source of truth for series
identification while maintaining folder as metadata for filesystem
operations only.
2025-11-23 12:25:08 +01:00