Add complete Japanese translation for all documentation pages including:
- Home and about pages
- Deployment guides (Docker CLI, Docker Compose, DSM, Local)
- Configuration pages (RSS, Downloader, Parser, Notifier, Manager, Proxy, Experimental)
- Feature documentation (RSS Management, Bangumi, Calendar, Rename, Search)
- FAQ and troubleshooting
- API reference
- Changelogs (2.6, 3.0, 3.1, 3.2)
- Developer guide
Also updates VitePress config to add Japanese locale with full sidebar navigation.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): use absolute paths for images in public folder
Relative paths (../image/) don't work on Vercel since the image/
folder at docs root is not tracked in git. Only public/image/ is
tracked. Using absolute paths (/image/) correctly references the
public folder assets.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: update README image paths to public folder
The images are tracked at docs/public/image/, not docs/image/.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The workflow was using the full PR title (e.g., 'Release 3.2.1') as the
version string, causing Docker tags and release creation to fail.
Now extracts just the version number (X.Y.Z or X.Y.Z-suffix) from the
PR title, handling formats like 'Release 3.2.1', 'v3.2.1', or '3.2.1'.
Images referenced with absolute paths in VitePress frontmatter (e.g.,
/image/icons/rss.png) must be in the public folder to be served correctly.
This fixes missing feature icons on the homepage.
A symlink is created at docs/image -> public/image to maintain compatibility
with relative paths used in markdown files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Configure VitePress locales with zh-CN as root and en-US as /en/
- Translate all documentation to Chinese (31 files)
- Create English documentation under /en/ directory
- Add Chinese UI labels for navigation and pagination
- Language switcher now available in site header
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>
Previously, the rename log message was printed before checking if the
qBittorrent API call succeeded. This caused log spam when rename
operations failed (e.g., due to 409 conflicts or network errors) since
the same file would be attempted again on the next cycle.
Now the log message is only printed after confirming the rename
succeeded, reducing noise in the logs.
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>
The warning "Episode offset 0 would result in negative episode" was
misleading and caused log spam. The actual issue was either:
1. Parsed episode was 0 or negative (parsing failure or special episode)
2. A negative offset would make a valid episode negative
Changes:
- Differentiate between parsing issues vs offset issues in log messages
- Use debug level for parsed episode issues (likely special episodes)
- Keep warning level only for actual offset problems
- Include original episode value in warning for better debugging
- Handle edge case where parsed episode is 0 by falling back to 1
Fixes#962
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>
When users have a SOCKS proxy configured (via HTTP_PROXY or ALL_PROXY
environment variables), httpx's AsyncClient automatically tries to use
it but fails without the socksio package installed.
Changed httpx dependency from httpx>=0.25.0 to httpx[socks]>=0.25.0 to
include the socksio package as an extra dependency.
Fixes#961
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>
- Add filter section with group, resolution, subtitle, season categories
- Implement multi-select filters with smart disabling for incompatible options
- Display result variant tags as non-clickable colored pills
- Unify tag styling (pill shape, 12px font) across filters and results
- Add expand/collapse for filter categories and variant overflow
- Normalize tag values (resolution: FHD/HD/4K, subtitle: 简/繁/双语)
- Calculate poster height to match 4 rows of variant chips (168px)
- Add click-outside-to-close for modal
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- 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>
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>
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>
- 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>
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>
- 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>
- 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>
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>
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>
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>
- 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>
- 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>
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>
- 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>
- 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>
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>
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>
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>