Commit Graph

873 Commits

Author SHA1 Message Date
6c502e2014 fix: scan episodes synchronously and disable test mode rate limiting
- Always scan missing episodes sync in add_series to avoid race condition
- Add db fallback in get_anime when in-memory episodeDict empty
- Add with_episodes param to AnimeSeriesService.get_by_key
- Disable auth rate limiting and lockout in test mode (ANIWORLD_TESTING=1)
- Simplify responsive.robot tests: fix setup, remove fragile width checks
2026-06-27 13:42:09 +02:00
b4027be385 Fix setup flow UI tests - update selectors and add server lifecycle
- Remove completed Task 25 from docs
- Add Suite Setup/Teardown with Start Aniworld Server and browser init
- Update element IDs to match current UI (password, strength-text, name, directory, etc.)
- Update form validation and complete setup flow tests with new selectors
- Add redirect testing after setup complete
2026-06-27 00:07:07 +02:00
a5e1c5b14f test(settings_modal.robot): align test IDs with actual UI element IDs
Update test selectors to match current UI implementation:
- scheduler-time-input → scheduled-rescan-time
- logging-* inputs → log-* equivalents
- backup-path-input → backup-path, backup-keep-days-input → backup-keep-days
- tmdb-api-key-input → tmdb-api-key
- create-backup-btn → create-config-backup

Remove unimplemented backup restore/delete and export/import tests.
Update Docs/tasks.md to remove completed Task 24 entry.
2026-06-26 23:22:06 +02:00
66acb45607 fix: queue page tests use Get Element States instead of disabled attribute
Task 24 fix. Robot tests now use Get Element States to check button
enabled state, which works reliably. Also added 100ms delay after auth
to ensure token availability, and error handling in loadQueueData.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 23:12:23 +02:00
2cf008bcf8 fix anime-settings: correct UI module name (UiUtils → UI), update tests with proper selectors
- AniWorld.UiUtils → AniWorld.UI for toast notifications
- Update robot tests to use actual element IDs (settings-section, save-db-btn, field-folder)
- Fix anime key format in test URLs (Attack on Titan - Season 1)
- Remove completed Task 22 from Docs/tasks.md
2026-06-26 22:11:33 +02:00
cece8fcb30 Fix toast pointer-events, add show-all-series button, fix UI tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 21:49:49 +02:00
7e4aeb22db fix: align password label 'for' attribute with input id
Label referenced 'password' but input id is 'password-input'.
Caveman commit auto.
2026-06-26 21:08:47 +02:00
3cfea2e3b3 Remove completed Task 19 from tasks.md 2026-06-26 21:06:13 +02:00
d940460355 Cleanup obsolete tasks, simplify auth lock logic, increase test retry wait
- Remove completed Task 17 and 18 from Docs/tasks.md
- Remove ANIWORLD_TESTING bypass in _check_locked (testing env now uses test auth service)
- Remove redundant lock expiry cleanup (handled by _get_fail_record)
- Fix login.html whitespace formatting
- Increase setup retry wait from 6s to 45s for rate-limited CI environments
2026-06-26 21:04:45 +02:00
313bd1ebf3 auth: fix rate limit bypass, improve error messages
- Disable rate limiting when rate_limit_per_minute = 0
- Add IP lockout mention to 429 response
- Lowercase error messages for consistency
- Raise test mode rate limit 100 -> 10 (more realistic)
2026-06-26 20:46:10 +02:00
46d34efecb fix login error display: use dedicated error div with show/hide
- Rename message-container to login-error for clarity
- Add CSS to hide error by default, show when populated
- Update showMessage() to control visibility
- Update clear on input to hide error div
- Remove completed Task 16 from tasks.md
2026-06-26 20:01:14 +02:00
df0d54cc34 fix(login): align HTML element IDs with Robot Framework selectors
- Rename password input id from 'password' to 'password-input'
- Rename login button id from 'login-button' to 'login-submit-btn'
- Update JS references to match new IDs
- Remove completed Task 15 from Docs/tasks.md
2026-06-26 19:54:10 +02:00
1f3eddf554 fix tests: update JSON paths and add WebSocket keyword library
- download.robot: fix total to total_items in queue statistics test
- websocket.robot: add websocket_keywords.py library and use proper keyword
- tasks.md: remove completed task entries
2026-06-26 19:52:19 +02:00
d00e80e240 simplify queue ops, handle broken pipe errors
- Add OSError errno 32 (broken pipe) handling in progress broadcast
- Remove progress service calls from add/clear queue operations
- Add pending_by_episode cleanup on clear
- Update tests accordingly
2026-06-26 19:50:13 +02:00
5028d4ea27 feat(api): add /resume endpoint for queue processing
Add POST /api/queue/resume endpoint. Alias for start_queue that provides
semantic clarity for resume action after pause/stop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 18:40:48 +02:00
e7d5df3a90 fix: parse string-encoded JSON in episode fields + return success for empty queue
- Add field validators to parse season/episode/title from JSON strings
- Add episodes list parser handling string-encoded dicts
- Return 200 with message instead of 400 when queue empty
- Remove completed tasks 8+9 from Docs
2026-06-26 18:39:02 +02:00
881da35dfd fix test: use pending_count instead of pending in queue status assertions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 18:02:12 +02:00
8fb24ff46a docs: remove completed Task 6 from tasks.md
Task 6 (Config Backup Restore API Test fix) already resolved. Clean up
dead task entry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 18:00:34 +02:00
ae368a0d8e fix: correct JSON key from backup_name to name in config backup tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 17:45:55 +02:00
c6f01ca985 wrap backups list in dict response
Task 4 done: config backup list endpoint now returns {backups: [...]} structure. API contract changed to match expected format.
2026-06-26 17:24:20 +02:00
ea59db302d fix: return 201 on backup create
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 17:13:57 +02:00
6e9c2b853a fix config model: remove ge=0 constraints from LoggingConfig
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 17:12:37 +02:00
42f4f0f5d7 Add name and data_dir to ConfigUpdate model
Allow updating app name and data directory via config endpoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 16:59:28 +02:00
a6e103889f fix: resolve race conditions in auth and episode retrieval
- models.py: episodeDict getter now catches DetachedInstanceError when episodes accessed on newly created/synced series
- anime.py: added error logging for failed series detail retrieval
- fastapi_app.py: raise auth rate limit to 100 in test mode (ANIWORLD_TESTING=1) to avoid 429 during rapid test execution
- auth_service.py: skip locked account check in test mode
- robot tests: suite setup now configures auth once, tests verify 'already configured' behavior to avoid re-setup conflicts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 16:57:22 +02:00
b5e2ba4ac4 fix(robot): resolve suite setup hangs and RF7 syntax errors
- Replace blocking Run Process with Start Process for uvicorn server
- Fix RF7 IF condition syntax: ${status_code} → $status_code
- Add bash wrapper script for reliable conda env server startup
- Add Create Anonymous Session to suite setup for health check polling
- Simplify .gitignore for robot results
2026-06-23 20:25:47 +02:00
572aa0fc78 fix(logging): replace structlog with stdlib logging to prevent broken pipe crashes
structlog fails with BrokenPipeError when stdout is redirected (e.g., background
processes, Docker logs). Replace all structlog.get_logger() calls with
logging.getLogger() and convert keyword-style log calls to %-format strings.

Also removes stale Docs/tasks.md (2028 lines) and updates Robot Framework
tests to match current API behavior.
2026-06-21 20:14:31 +02:00
be3e180137 backup 2026-06-21 12:32:44 +02:00
107158eb04 Update tasks documentation 2026-06-21 12:28:35 +02:00
ad1aace0f5 docs: add infrastructure task tracking and Robot Framework deps
- Rename Docs/Tasks.md → Docs/tasks.md (case fix)
- Add comprehensive task docs for INFRA-1 (server startup) and INFRA-2 (teardown)
- Add test-robot make target
- Add robotframework, browser, requests, jsonlibrary to requirements.txt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 12:26:18 +02:00
eabce18e41 feat(anime): rename NFO Diagnostics to Anime Settings + add edit endpoints
Replaces the read-only 'NFO Diagnostics' page with a full per-anime
Settings page reached from the right-click context menu on series cards.
Users can now view and edit key, name, folder, tmdb_id, tvdb_id and site
for each anime; changes are persisted to the DB and optionally written
back to the NFO file or used to regenerate it.

Backend
- Rename NfoDiagnosticsResponse -> NfoSettingsResponse,
  NfoSeriesDiagnostics -> NfoSeriesSettings
- Rename get_nfo_diagnostics -> get_nfo_settings,
  repair_nfo -> repair_nfo_settings
- Fix nfo.py bug: repair was calling non-existent
  update_series_nfo_status(); now uses update_nfo_status() and an
  explicit AnimeSeriesService.update(nfo_path=...)
- New endpoints on /api/anime/{key}:
    GET  /settings            -> AnimeSettingsResponse
    PUT  /settings            -> AnimeSettingsResponse
                                 (body: name/folder/tmdb_id/tvdb_id/site,
                                  options: apply_to_nfo, rename_disk)
    POST /regenerate-nfo      -> AnimeSettingsRegenerateNfoResponse
- New Pydantic models: AnimeSettingsResponse,
  AnimeSettingsUpdateRequest, AnimeSettingsRegenerateNfoResponse
- /anime/settings page route; /settings/nfo now 301-redirects to it

Frontend
- New AniWorld.AnimeSettingsManager JS module (single-page form,
  no tabs) with public API init/loadSeries/saveSettings/regenerateNfo/
  validateField/populateForm/showSaveSuccess/showError
- New anime-settings.html template + anime-settings.css
- Right-click menu: data-action 'nfo-diagnostics' replaced by
  'anime-settings' (label 'Anime Settings'), navigates to
  /anime/settings?key=...
- Library 'Open NFO Diagnostics' link renamed to 'Open Anime Settings'

Bug fix
- context-menu click handler was calling hide() BEFORE building the
  navigation URL, which cleared currentSeriesKey to null and produced
  /anime/settings?key=null. Captures the key into a local const first.
  Regression-locked by tests/frontend/unit/context_menu.test.js.

Tests
- 21 new pytest tests in tests/api/test_anime_settings_endpoints.py
  (GET/PUT/regenerate-nfo, auth, validation, nfo-repair bug regression)
- tests/api/test_nfo_endpoints.py trimmed to 6 focused tests
- 31 new Vitest unit tests for AnimeSettingsManager
- 5 new Vitest unit tests for ContextMenu (incl. source-invariant
  regression guard for the hide()-before-key bug)
- 5 new Playwright E2E tests covering right-click, direct nav,
  legacy /settings/nfo redirect, and context-menu labels
- New vitest.config.js (environment: happy-dom)

Docs
- Docs/API.md: new section 'Anime Settings Endpoints'
- Docs/CHANGELOG.md: documents the rename and the context-menu bug fix

Verified
- pytest: 27/27 (21 new + 6 trimmed nfo)
- vitest: 36/36 (31 anime-settings + 5 context-menu)
- playwright e2e: 5/5
2026-06-21 07:52:22 +02:00
e050f6fa2d refactor: remove Edit Metadata right-click option
Removes the Edit Metadata feature from the anime context menu and
deletes all related backend/frontend code:

Backend:
- DELETE PUT /api/anime/{anime_key} endpoint
- DELETE AnimeMetadataUpdate model and KEY_PATTERN regex
- DELETE MAX_INPUT_LENGTH constant

Frontend:
- DELETE edit-modal.js component
- DELETE edit metadata modal HTML from index.html
- DELETE edit-modal.js script tag
- DELETE edit-only CSS (.edit-modal-content, .edit-section,
  .field-error, .input-error, .key-warning, .info-grid,
  .info-item, .input-with-action, .btn-fetch-tmdb, .tmdb-*)
- REMOVE 'Edit Metadata' item from context menu (NFO Diagnostics
  preserved)

Tests:
- DELETE test_anime_edit_endpoints.py
- DELETE test_edit_modal.py
- DELETE test_anime_key_rename.py
2026-06-20 21:02:22 +02:00
a8e54876e3 refactor: overhaul NFO settings UI and backend
- Rework nfo-settings page with improved styling and layout
- Update edit-modal and context-menu with enhanced functionality
- Refactor NFO API endpoints and models
- Remove deprecated test_nfo_diagnostics_repair.py
- Clean up tasks.md documentation
2026-06-20 20:32:46 +02:00
7a1b2e565e feat: add ImageLoadingService for downloading series artwork
- Create ImageLoadingService that downloads poster.jpg, fanart.jpg, and
  logo.png from TMDB when anime is added or during scheduler rescan
- Integrate into BackgroundLoaderService._load_nfo_and_images() to trigger
  image downloads when new anime is added
- Add image_scan_after_rescan config option to scheduler (default: true)
- Add _run_image_scan() to scheduler rescan flow, processing series in
  batches of 10 to respect TMDB rate limits
- Fix SearchResult model missing folder, snippet, and score fields
- Update background_loader tests to match new image loading behavior
2026-06-14 20:51:57 +02:00
6dc3cda810 feat(nfo): implement NFO diagnostics and repair
- Add NFO API endpoints: diagnostics, repair, validate, needs-repair
- Create /settings/nfo page with full NFO management UI
- Add NFO status section to edit modal with repair functionality
- Add anime details API for edit modal pre-fill data
- Fix auth test fixtures in test_nfo_diagnostics_repair.py

Implements NFO diagnostics when editing anime series via right-click menu.
Users can now check NFO status, see missing tags, and repair NFOs
directly from the edit modal or the dedicated NFO settings page.
2026-06-14 19:34:58 +02:00
75084b3941 fix: use ffmpeg downloader for proper progress reporting
VOE provider returns HLS streams (.m3u8) which previously used yt-dlp's
native HLS downloader. That downloader does not report downloaded_bytes/
total_bytes in progress hooks, causing only 0% and 100% to ever show on
the queue page. Explicitly set 'downloader: ffmpeg' so progress updates
with actual byte counts are broadcast, enabling intermediate percentages
(25%, 50%, 75%, etc.) to display correctly.
2026-06-11 20:51:37 +02:00
de330dc146 chore: bump version v1.4.17 2026-06-11 08:45:36 +02:00
4731fd644a fix(tests): resolve 13 failing unit tests
- Use dynamic APP_VERSION instead of hardcoded v1.3.6 in:
  test_template_helpers, test_health, test_page_controller
- Add unresolved_folders to EXPECTED_TABLES in database/init.py
- Fix shallow copy bug in test_serie_scanner.py episodeDict comparison
- Update test_schema_constants to expect 6 tables instead of 5
2026-06-11 08:36:41 +02:00
9d52ff0c45 fix: use async context manager for TMDBClient to prevent resource leak
The TMDBClient was being instantiated but never closed, causing 'Unclosed
client session' errors in the logs. Fixed by using 'async with' context
manager which properly calls close() on exit.

Changes:
- _lookup_tmdb_id_by_name: wrapped client in async with
- _fetch_tmdb_data: wrapped client in async with
2026-06-11 08:03:03 +02:00
ee5d719f37 fix(scheduler): add to_dict to AnimeSeries for auto-download
AnimeSeries objects returned by SerieList.GetMissingEpisode() lacked
to_dict(), causing AttributeError when _run_auto_download() called
series.get("episodeDict").
2026-06-11 08:02:27 +02:00
cbc44491e7 chore: bump version v1.4.16 2026-06-10 20:14:41 +02:00
e319cfecb8 fix: add episodeDict setter to AnimeSeries model
SerieScanner attempted to assign serie.episodeDict = missing_episodes
but the property had no setter, causing AttributeError during scan.

Added setter that stores value in _episode_dict_cache, which the getter
already checks. This allows SerieScanner to update episodeDict directly.
2026-06-10 20:14:15 +02:00
4f61ded92a chore: bump version v1.4.15 2026-06-10 19:17:39 +02:00
d6082b5cf6 fix: ensure series loaded from DB before NFO scan
- Call _load_series_into_memory() before NFO scan phases to sync DB
  to SeriesApp memory, fixing missing NFO for recently resolved folders
- Add TMDB lookup for series without cached tmdb_id during NFO creation
- Add get_tmdb_client() factory and get_tmdb_image_base_url() helpers
- Fix: use get_tv_show_details instead of deprecated get_series_details
- Fix tests: mock _load_series_into_memory in NFO scan tests
2026-06-10 18:49:53 +02:00
e76cd3a708 test: remove sync_legacy_series_to_db tests
- Removed TestSyncSeriesFromDataFiles class from test_anime_service.py
- Updated TestSyncAnimeFolders tests to expect sync_count=0
- Removed TestSyncSeriesToDatabase class from test_data_file_db_sync.py
2026-06-10 18:26:09 +02:00
08f7f7453c refactor: remove legacy data file sync functionality
Series now loaded directly from database. Removed:
- sync_legacy_series_to_db() from anime_service.py
- Corresponding sync call after directory update in config.py
- Safety nets in initialization_service.py for missing progress IDs
2026-06-10 18:23:01 +02:00
023ddd182f fix(initialization): remove duplicate nfo_scan progress completion
The nfo_scan_completed event handler was calling complete_progress()
which removed the progress before _execute_nfo_scan returned. This caused
perform_nfo_scan_phase to fail with 'Progress with id nfo_scan not found'
when it tried to complete the same progress.

Completion is now only handled by perform_nfo_scan_phase after
_execute_nfo_scan returns, as intended.
2026-06-10 18:20:04 +02:00
288b03cbb4 chore: bump version v1.4.14 2026-06-09 20:50:06 +02:00
f73cc530c3 fix(ui): improve suggestion handling in unresolved series template
- Update Font Awesome from 6.0.0 to 6.6.0
- Replace suggestion links with buttons for better click handling
- Add debug logging for troubleshooting suggestion clicks
- Use 'link' field as primary provider key source
2026-06-09 19:20:27 +02:00
4b835a2439 fix(scheduler): skip rescan during initial setup when anime directory not configured
Prevent scheduler from triggering immediate rescan when:
- No previous scan recorded AND initial setup not yet completed
- Anime directory doesn't exist during initial sync

The setup flow will trigger rescan when ready. Also adds graceful
handling when anime directory is missing during data file sync.

Fixes: 503 error on setup when scheduler triggers rescan before
anime directory is configured
2026-06-09 18:39:36 +02:00
7c1dccfe64 perf(web): use content hash for static asset cache busting
Switch from timestamp-based to MD5 content hash versioning.
Cache now only invalidates when file content actually changes.
2026-06-09 18:26:51 +02:00