Commit Graph

1751 Commits

Author SHA1 Message Date
Estrella Pan
27a056d01a fix(login): unify input height and font size with buttons
Standardize form element dimensions for visual consistency:
- Input height: 48px → 44px (matches button height)
- Input font: 16px → 14px (consistent with form elements)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:14:38 +01:00
Estrella Pan
5ab38c335d refactor(setup): remove syncMediaPath call from downloader step
Path is now synced directly through downloaderData.path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:12:05 +01:00
Estrella Pan
9b27621861 feat(setup): improve dev mode support for setup wizard testing
- Allow setup in dev mode even if settings differ from defaults
- Add mock downloader type for development testing
- Only check sentinel file in dev mode for need_setup status

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:11:48 +01:00
Estrella Pan
2fb82a5a27 refactor(setup): remove redundant media library step from wizard
The media library path is now taken directly from the downloader path
field, eliminating the unnecessary separate step.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:11:44 +01:00
Estrella Pan
4488a89391 fix(player): normalize URLs without protocol to prevent relative path redirects
URLs entered without http:// or https:// were being treated as relative
paths by the browser. Added normalizeUrl() function that prepends http://
when no protocol is present.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:11:40 +01:00
Estrella Pan
8d09b0cecc fix(i18n): add missing translations for selectAll and theme toggle
- Add common.selectAll and common.items translations
- Add theme.light and theme.dark translations
- Update ab-mobile-nav to use i18n for theme toggle label
- Remove hardcoded fallback in ab-data-list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 19:51:43 +01:00
EstrellaXD
47a10d5828 fix: suppress verbose httpx HTTP request logs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 17:08:29 +01:00
EstrellaXD
359b3e5253 fix: resolve all deprecation warnings
Pydantic V2:
- Replace @validator with @field_validator in models/config.py
- Replace .dict() with .model_dump() in Config, Settings, and BangumiDatabase
- Replace .parse_obj() with .model_validate() in Settings and tests
- Replace Field(example=) with Field(json_schema_extra=) in response models

Datetime:
- Replace datetime.utcnow() with datetime.now(timezone.utc) in jwt.py
- Update factories.py to use timezone-aware datetime

FastAPI:
- Migrate from deprecated @router.on_event() to lifespan context manager
- Move startup/shutdown handlers from program.py to main.py

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:34:19 +01:00
EstrellaXD
7b5c8d9ac5 chore: upgrade Python version to 3.13
- Update requires-python to >=3.13 in pyproject.toml
- Update ruff and black target versions to py313
- Update Dockerfile to use python:3.13-alpine
- Add explicit Python 3.13 setup in CI workflow
- Regenerate uv.lock for Python 3.13

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:30:25 +01:00
EstrellaXD
f22f5c657f fix(test): correct TypeScript types in frontend test mocks
- Use RSS type instead of non-existent RSSItem/RSSResponse
- Add expire field to mockLoginSuccess
- Replace offset with episode_offset/season_offset in mockBangumiAPI
- Add needs_review_reason field to mockBangumiAPI
- Add missing RSS fields (connection_status, last_checked_at, last_error)
- Fix generic types in test utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:24:31 +01:00
EstrellaXD
a137b54b85 test: add comprehensive API tests for backend and frontend
Backend:
- Add API test files for auth, program, downloader, config, log, bangumi extended, search, and passkey endpoints
- Update conftest.py with new fixtures (app, authed_client, unauthed_client, mock_program, mock_webauthn, mock_download_client)
- Update factories.py with make_config and make_passkey functions

Frontend:
- Setup vitest testing infrastructure with happy-dom environment
- Add test setup file with mocks for axios, router, i18n, localStorage
- Add mock API data for testing
- Add tests for API logic, store logic, hooks, and basic components
- Add @vue/test-utils and happy-dom dev dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:20:39 +01:00
EstrellaXD
3770d33f77 chore: add beta release notes generator script
Generates concise release notes showing only changes between beta versions:
- Auto-detects previous beta tag
- Groups commits by type (feat, fix, perf, docs)
- Excludes chore/refactor/test commits from notes
- Includes link to full changelog comparison

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:14:01 +01:00
EstrellaXD
4e2a22aba5 chore: bump version to 3.2.0-beta.13
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2.0-beta.13
2026-01-26 15:56:49 +01:00
EstrellaXD
3f4f3a141c feat(database): add title alias system for mid-season naming changes
When subtitle groups change their naming convention mid-season (e.g.,
"LoliHouse" → "LoliHouse&动漫国"), AutoBangumi was creating duplicate
entries. This adds a title alias system that:

- Detects semantic duplicates (same official_title, dpi, subtitle,
  source, and similar group name)
- Merges them as aliases instead of creating new entries
- Updates match_torrent() and match_list() to check aliases
- Adds title_aliases field to Bangumi model (JSON list)
- Includes migration v8 for the new column
- Adds 10 new tests for the feature
- Fixes cache invalidation bug in disable_rule()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 15:44:44 +01:00
EstrellaXD
0ba508cd0b fix(webui): prevent empty search and cancel search on modal close
- Add input validation to prevent search when keyword is empty or whitespace
- Close EventSource connection when search modal is closed to stop ongoing searches

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 15:42:40 +01:00
EstrellaXD
bb8adf6813 fix(webui): fix iOS Safari input zoom and keyboard issues
- Add global CSS rule to prevent auto-zoom on input focus by ensuring
  font-size >= 16px on touch devices
- Update bottom sheet to use dvh units and visualViewport API for
  proper keyboard handling on iOS Safari
- Update modal components (ab-add-rss, ab-search-modal) to use dvh
  units with vh fallback for older browsers
- Add scroll-margin-bottom for inputs in bottom sheets

Closes #959

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 15:15:07 +01:00
EstrellaXD
1f5d92f50b docs(dev): add database developer guide
Comprehensive documentation covering:
- Database architecture and components
- Model schemas (Bangumi, RSSItem, Torrent, User)
- Common CRUD operations for each sub-database
- Caching strategy and invalidation
- Migration system and how to add new migrations
- Performance patterns (batch queries, regex matching, indexes)
- Testing setup with factories
- Common issues and solutions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 14:51:50 +01:00
EstrellaXD
0c8ebb70a3 fix(error-handling): replace bare except clauses with specific exceptions
- qb_downloader.py: catch httpx network errors in logout() and rename_file()
- user.py: log exception details when querying users table fails
- download_client.py: log exception when category creation fails
- title_parser.py: catch specific exceptions (ValueError, AttributeError, TypeError)
  instead of broad Exception in raw_parser()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 14:51:44 +01:00
EstrellaXD
d6e89f62ed perf(database): optimize N+1 queries and add caching
- Replace N individual _is_duplicate() calls with single batch SELECT query
  in add_all() method, reducing database round-trips
- Replace O(n*m) nested loop in match_list() with compiled regex alternation
  pattern for faster torrent-to-bangumi matching
- Add LRU cache (512 entries) to torrent_parser() to avoid redundant regex
  parsing for the same torrent paths
- Extend bangumi search_all() cache TTL from 60s to 300s (5 minutes)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 14:30:16 +01:00
EstrellaXD
ebd58531b5 fix(test): add missing DEV_AUTH_BYPASS constant for test mocking
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2.0-beta.12
2026-01-26 14:06:13 +01:00
EstrellaXD
08a71b877c chore: bump version to 3.2.0-beta.12
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 14:02:19 +01:00
EstrellaXD
3c71cf813f fix(offset): only suggest episode_offset for virtual seasons
- Change episode_offset type from int to int | None
- Only set episode_offset when virtual season split is detected
- For simple season mismatches (e.g., RSS S2 → TMDB S1), episode_offset is now None
- Improve reason messages to clarify when episode offset is/isn't needed
- Update database migration version to 7 and add migration check

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 13:51:55 +01:00
EstrellaXD
01a1a79a33 feat(offset): add suggested offset values to review panel
When offset scanner detects a mismatch, it now stores:
- suggested_season_offset: recommended season offset value
- suggested_episode_offset: recommended episode offset value

These values are returned in the API response for bangumi that need review,
allowing the frontend to display them to help users configure the correct offset.

Database migration v7 adds the new columns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 13:45:40 +01:00
EstrellaXD
95165da3b6 fix(offset): apply season_offset to folder path and update RSS rules
When user sets season_offset, the save path now reflects the adjusted season:
- _gen_save_path() uses (season + season_offset) for folder name
- Files saved directly to correct folder (e.g., Season 2 instead of Season 1)
- update_rule() now updates qBittorrent RSS rule's savePath when offset changes
- Existing torrents are moved to the new location

Renamer changes:
- gen_path() no longer double-applies season_offset (folder already has it)
- Season number taken directly from folder name
- Added path normalization for better save_path matching
- Added debug logging for offset lookup

Torrent name matching (title_raw) remains primary fallback for finding bangumi.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 13:39:01 +01:00
EstrellaXD
f2f00a9f82 fix(passkey): allow no-username passkey login with discoverable credentials
Remove the username requirement check that was blocking passkey login without
entering a username. The backend already supports discoverable credentials mode.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 13:22:57 +01:00
Estrella Pan
bfb94145cb test(renamer): add comprehensive tests for offset lookup functionality
Add tests covering:
- _parse_bangumi_id_from_tags: tag parsing with various formats
- gen_path with offsets: episode/season offset application
- _lookup_offsets: multi-tier lookup (qb_hash, tags, name, path)
- TorrentDatabase hash lookup methods (search_by_qb_hash, search_by_url, update_qb_hash)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-26 08:24:23 +01:00
Estrella Pan
34332d27af fix(renamer): resolve multiple rows error for multi-subscription seasons
When multiple bangumi subscriptions share the same save_path (e.g., split-cour
anime with S01E1-12 and S01E13-24), the renamer's match_by_save_path() query
returned multiple rows causing "Multiple rows were found" errors.

Changes:
- Add qb_hash field to Torrent model for direct hash-to-bangumi linking
- Add database migration v6 for qb_hash column with index
- Add tags parameter to add_torrents() in all downloader clients
- Tag new torrents with ab:{bangumi_id} for offset lookup during rename
- Implement multi-tier lookup in renamer: qb_hash -> tags -> torrent_name -> save_path
- Fix auth tests by mocking DEV_AUTH_BYPASS for proper 401 testing

The renamer now reliably finds the correct bangumi and its offsets even when
multiple subscriptions download to the same directory.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-26 08:20:02 +01:00
Estrella Pan
12ac30c76a fix(core): prevent duplicate startup logo from nested router lifespan events
FastAPI's merged_lifespan mechanism triggers lifespan events for each
nested router layer. Since program_router is included in v1, which is
included in app, the startup handler was being called 3 times.

Added _startup_done flag to ensure Program.startup() only executes once.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-26 07:28:48 +01:00
Estrella Pan
93d2f2e7d2 chore: bump version to 3.2.0-beta.11
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2.0-beta.11
2026-01-25 23:15:52 +01:00
Estrella Pan
d96e84f437 docs: update README with 3.2 features
- Update changelog link to 3.2
- Add new 3.2 features section:
  - Calendar view with Bangumi.tv integration
  - Passkey passwordless login
  - Season/episode offset auto-detection
  - Bangumi archive functionality
  - Search provider settings panel
  - RSS connection status tracking
  - iOS-style notification badges
  - New UI design (dark/light theme, mobile support)
  - Performance improvements
- Update supported downloaders list (qBittorrent, Aria2, Transmission)
- Fix TMDB typo

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-25 23:11:00 +01:00
Estrella Pan
efa8d6baeb docs: update changelog for mobile UI/UX improvements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 23:10:21 +01:00
Estrella Pan
f764279a51 fix(webui): improve mobile UI/UX layout and responsiveness
Mobile Layout Fixes:
- Fix config page horizontal overflow by adding min-width: 0 constraints
- Fix sticky action buttons positioning on config page
- Add loading states to config save/cancel buttons
- Reduce topbar padding and icon spacing for mobile
- Make search button fill space between logo and action icons
- Fix search modal header layout with close button visibility

Component Improvements:
- ab-topbar: Flex search button with "Click to search" text on mobile
- ab-status-bar: Reduce button sizes and gaps on mobile
- ab-fold-panel: Add max-width and overflow constraints
- ab-setting: Add max-width: 100% to prevent input overflow
- ab-search-modal: Reduce padding and element sizes on mobile
- ab-mobile-nav: Increase label font-size from 10px to 11px
- ab-sidebar: Fix toggle animation (rotateY → rotate)

Calendar & Bangumi Pages:
- Add lazy loading to poster images for better performance
- Move unknown air day items to separate section below grid
- Add actionable CTA button to empty state with useAddRss hook

Login Page:
- Add will-change: transform for background animation performance

i18n:
- Add click_to_search translation key for mobile search button
- Add add_rss_btn translation for empty state CTA

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 23:09:53 +01:00
Estrella Pan
6b6ba75d80 docs: update documentation for 3.2 beta features
- Update changelog/3.2.md with beta.5-10 features:
  - Season/episode offset auto-detection
  - Bangumi archive functionality
  - Search provider configuration API
  - RSS connection status tracking
  - iOS-style notification badges
  - Performance improvements (backend & frontend)

- Update feature documentation:
  - search.md: Add search provider settings panel docs
  - bangumi.md: Add archive, offset detection, badges docs
  - rss.md: Add connection status documentation
  - rename.md: Add episode offset section
  - calendar.md: New documentation for calendar view

- Add screenshots for new features:
  - Login page (glassmorphism design)
  - Bangumi list and edit modals
  - Rule selection popup
  - RSS manager with connection status
  - Calendar view
  - Search panel and provider settings

- Update VitePress config to include Calendar in sidebar

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-25 23:00:48 +01:00
Estrella Pan
a0a21a71e5 feat(webui): add search provider settings panel
- Add config-search-provider.vue component for managing search sources
- Support CRUD operations for custom search providers
- Default providers (mikan, nyaa, dmhy) cannot be deleted
- URL template validation ensures %s placeholder is present
- Add backend API endpoints GET/PUT /search/provider/config
- Add i18n translations for zh-CN and en

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 22:27:33 +01:00
Estrella Pan
5e0efc01b9 fix(webui): use episode_offset instead of offset in components
The BangumiRule type uses episode_offset but components were using offset,
causing TypeScript errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 22:16:54 +01:00
XYenon
3695452fb7 Fix parser (#877)
Thanks for the fix! The improved regex pattern will help parse more anime titles correctly. Closes #876 and #924. 🎉
2026-01-25 22:12:43 +01:00
Wu Ying Ying
0385129f5d fix: None official_title in bangumi stopping rss parsing (#866)
Thanks for catching this edge case! This defensive fix prevents crashes when parsing RSS items with empty titles. 🎉
2026-01-25 22:12:41 +01:00
Leohearts
61c071e035 [fix] better json parsing in openai.py (#913)
Thanks for the contribution\! This fix helps users who use alternative GPT APIs like Moonshot that don't support structured output mode. 🎉
2026-01-25 22:12:38 +01:00
Estrella Pan
66c7127f21 feat(offset): add automatic season/episode offset detection
- Add offset detector to identify season mismatches between RSS and TMDB
- Only suggest season_offset (user sets episode_offset manually)
- Add background scanner for existing bangumi rules
- Add detect-offset and dismiss-review API endpoints
- Add warning banner in edit dialog with auto-detect button
- Add iOS-style notification badge for needs_review items
- Yellow badge with "!" for warnings, purple badge for multi-rule count
- Combined badge shows "! | 2" when both conditions apply
- Yellow glow animation on cards needing review
- Highlight warning items in rule selection popup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 21:03:18 +01:00
Estrella Pan
9790dce06c fix(passkey): add data field to ResponseModel for passkey login
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2.0-beta.10
2026-01-25 19:37:53 +01:00
Estrella Pan
c044b65fef chore: bump version to 3.2.0-beta.9
Fix TypeScript error in ab-search-bar.vue and include pending changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2.0-beta.9
2026-01-25 19:29:12 +01:00
Estrella Pan
f1fb4d7926 chore: bump version to 3.2.0-beta.8 3.2.0-beta.8 2026-01-25 19:25:06 +01:00
Estrella Pan
22870b8ae3 feat(auth): support usernameless passkey login (discoverable credentials)
- Change resident key requirement from PREFERRED to REQUIRED during registration
- Add discoverable authentication options (empty allowCredentials)
- Add verify_discoverable_authentication method in WebAuthn service
- Update auth strategy to lookup user from credential when username not provided
- Make username optional in frontend passkey login flow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:23:39 +01:00
Estrella Pan
9e6a528e57 fix(search): resolve multiple issues in search and subscription flow
- Fix axios interceptor error when response.data is undefined by adding
  optional chaining (?.msg_en, ?.msg_zh)
- Fix XML parsing crash in backend by catching ParseError exceptions
- Remove brotli (br) from Accept-Encoding header to fix mikan RSS fetch
  issues (httpx doesn't auto-decompress brotli)
- Fix search card click event not triggering confirmation modal by
  changing from native 'click' to custom 'select' event with typed payload
- Add NMessageProvider to App.vue to fix useMessage() outside setup error
- Replace structuredClone with JSON.parse/stringify in confirm modal
  to handle Vue reactive Proxy objects

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 17:33:46 +01:00
Estrella Pan
da6e578404 fix(network): improve torrent fetch reliability and error handling
- Add browser-like headers and full Chrome User-Agent to avoid Cloudflare blocking
- Use appropriate Accept headers for torrent files (application/x-bittorrent)
- Increase timeouts (connect: 5s→10s, read: 10s→30s) for slow responses
- Filter out None values from failed torrent fetches before sending to qBittorrent
- Add try-catch around add_torrents to prevent request crashes
- Improve logging from DEBUG to WARNING level for better visibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 14:11:11 +01:00
Estrella Pan
6ce3f92c74 chore: bump version to 3.2.0-beta.7 3.2.0-beta.7 2026-01-25 11:50:32 +01:00
Estrella Pan
362c7b81ca feat(ui): redesign search panel with modal and filter system
- Replace dropdown search results with full-screen modal
- Add 4-tier filter chips: subtitle group, resolution, subtitle type, season
- Auto-extract filter options from search results
- Add confirmation modal before subscribing
- Support toggle close (click search input, Escape, or X button)
- Responsive grid layout: 1-4 columns based on viewport
- SSE streaming with fade-in card animations
- Add i18n translations for search filters and confirmation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:48:32 +01:00
Estrella Pan
8e7e8933e4 fix(downloader): add retry logic for transient network errors in add_torrents
Handles httpx.ReadError and other network exceptions when adding torrents
to qBittorrent by retrying up to 3 times with a 2-second delay.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:47:26 +01:00
Estrella Pan
2031836b2e feat(ui): redesign login panel with modern glassmorphism style
- Add animated gradient background with floating blobs
- Use glassmorphism card with backdrop blur
- Add brand logo with theme-aware switching (light/dark)
- Improve form layout with input icons and better spacing
- Make login button full-width for better UX
- Add loading state for login button
- Improve passkey button styling with dashed border
- Respect prefers-reduced-motion for animations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:09:02 +01:00
Estrella Pan
9dd65cc28e fix(ui): widen unknown column in calendar layout
Make the "unknown" day column span 2 grid columns and display
items in a grid layout for better use of space.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:08:53 +01:00