[3.3] β Beta
3.3 is the largest AutoBangumi release in a while: a fully async backend architecture, aria2 promoted to a first-class download backend, movie/OVA/special support, per-bangumi release preferences, a hardened security stack, and a WebUI that updates over SSE instead of polling. REST API behavior is backward-compatible; existing databases upgrade automatically (migrations v9βv14).
Highlights
- In-app updates (new in beta.2) β check, apply, and roll back updates from the Log page. Bundles are sha256-checked and ed25519-signed (unsigned releases are rejected, and the signature is re-verified at every boot), the database is snapshotted before promotion, and dependencies sync at apply time as a non-root user. Requires the container to run with
restart: unless-stoppedso it can restart itself. - Multi-provider LLM parser (new in beta.2) β OpenAI-compatible endpoints (DeepSeek, Ollama, LM Studio, OpenRouter, β¦), Anthropic Claude, and Google Gemini, with a selectable mode:
fallback(regex first, LLM rescues failures β default) orprimary(LLM first). Calls get timeouts, caching, a concurrency cap, and a failure breaker, and route through the app proxy. - aria2 is now a first-class backend β real add/query/rename/manage support with honest duplicate detection (reconciled against aria2's live state), collision-safe filesystem renames, and offset resolution via a persisted gidβbangumi mapping. Previously aria2 could only add torrents; organization silently did nothing.
- Movies / OVA / Specials β the parser recognizes ε§εΊη/εε ΄η/η΅ε½±η/Movie and OVA/OAD/SP/Special tokens (
episode_type); movies are organized as flatTitle (Year)folders with TMDBsearch/moviefallback, specials go to Season 0. Multi-file movie torrents keep distinct filenames (largest file gets the clean name). - Per-bangumi release preference β set a preferred subtitle group and/or resolution per series; when multiple groups release the same episode, only the best match is downloaded instead of all of them.
- Notifications beyond "new episode" β typed events for RSS feed failures (on state change, not every tick), download-add failures, and offset needs-review;
{{title}}-style message templates now work for every provider, not just webhook. - Offset suggestions you can apply β season/episode offset mismatches are detected from real parsed episodes and applied with one call (
POST /api/v1/bangumi/apply-offset/{id}, single or bulk). - SSE-driven WebUI β status, downloader, and log views subscribe to
/api/v1/events/streaminstead of three polling loops; a dead downloader can no longer freeze the stream (bounded fetch with explicit degraded payload).
Backend β Architecture
The backend went through a modernization refactor (REST API behavior unchanged):
- Database layer fully asynchronous: repositories and
Databaseonsqlite+aiosqlite(WAL + busy_timeout); no synchronous DB calls on the event loop - The
Programgod object replaced by a lifespanAppContextcomposition root with a genericPeriodicTask/Scheduler; startup is awaited and a failed migration aborts boot explicitly - Composition over inheritance throughout (
RSSEngine/TorrentManager/Renamer/β¦ take constructor-injected dependencies) - Table-driven migrations (
database/migrations.py) withalready_appliedguards; old databases upgrade identically DownloaderProtocol with capability flags; qBittorrent login session reused across operations with automatic re-auth on 401/403 (#1039, #900)- Config changes uniformly through
AppContext.reload_settings()β HTTP client, notifier, scheduler, and parser caches all reset consistently
Backend β Features
- Security config model: login IP allowlist, MCP CIDR allowlist + Bearer Token dual authentication,
Authorization: Bearersupport on auth endpoints - Manual air-weekday API with calendar-refresh lock (
PATCH /api/v1/bangumi/{id}/weekday, migration v9) - Configurable TMDB / bgm.tv API base URLs for users behind restrictive networks (#1040, #1042)
- Per-provider parser choice for custom search providers; the OpenAI parser now rescues titles the regex parser fails on instead of replacing it entirely
- Unauthenticated
GET /healthliveness endpoint ({status, version, db_ok}) and a DockerHEALTHCHECK - Auth stack migrated from unmaintained
python-jose/passlib(CVE-2024-33663, CVE-2024-33664) to PyJWT + bcrypt β existing passwords, including >72-byte ones, keep working
Backend β Fixes
- Failed torrent adds now actually retry on the next RSS tick; "already added" duplicates no longer emit failure notifications β and downloader clients now report add outcomes honestly (a transport failure can no longer be mistaken for a duplicate)
- qBittorrent rename verification no longer reports success without seeing the new filename (#754, #749)
- Lifecycle transitions (start/stop/restart/reload) serialized behind a lock; the setup wizard now starts the background loops on completion
- Filter-rejected torrents no longer pollute offset detection
- Season offset can no longer accidentally move regular episodes into Season 0 (Plex/Jellyfin Specials); only true specials land there
- aria2: stale duplicate-tracking rows are reconciled when downloads are removed outside AutoBangumi; metadata-fetching magnets no longer crash the downloader list; renames refuse to overwrite existing files
- qBittorrent SSL: self-signed certificates no longer break the connection (#923)
- Destructive API endpoints converted from GET to POST (CSRF hardening)
- OpenAI parsing no longer blocks the event loop (
AsyncOpenAI)
Backend β Performance
- Missing database indexes backfilled for upgrading installs (previously only fresh databases got them); offset-scanner and preference-dedup queries now index-backed (migrations v13/v14)
- Title parser ~16% faster (all static regex precompiled)
- Renamer fallback lookup batched: 201 β 2 queries at 200 torrents (~11Γ)
- Notification dispatch parallelized across items (with the underlying HTTP-context race fixed first)
WebUI
- UX/accessibility/perf pass (new in beta.2):
- The rule-delete dialog is no longer a trap ("No" used to delete the rule too); destructive actions everywhere (RSS bulk delete, torrent delete, clear log, notification provider removal) now confirm first
- Air weekday is settable from the rule editor β calendar scheduling now works on mobile and keyboard, not just desktop drag
- The mobile bottom nav is actually at the bottom; touch targets raised to 44px across the app; feed errors shown inline on mobile cards
- Self-hosted Inter font (no more render-blocking Google Fonts β noticeable on Chinese networks); lazy poster loading; the log view stays fast by rendering only the newest 1000 lines
- Honest states: failed loads show errors with retry instead of masquerading as empty/onboarding screens; background polls no longer spam error toasts during a backend restart
- Setup wizard: an unreachable downloader can no longer dead-end the wizard, and progress survives a page reload
- Calendar drag-and-drop scheduling: drag an "Unknown" series onto a weekday to set and lock its air day
- Component system unified on naive-ui (fixes a theme crash that could blank the Config page; naive-ui 2.44 for Vue 3.5 compatibility)
- RSS page: per-feed and refresh-all buttons; decluttered table (source metadata beside the name, status column shows only state)
- Calendar cards show the series title when no poster is available; bangumi titles wrap to two lines with full-title tooltips
- Security settings UI (IP allowlists, tokens); mobile nav labels no longer truncate; WCAG AA contrast pass; log page copy fixes
- Oversized editor components split into a shared
useBangumiRuleFormcomposable
Tooling & CI
- mypy type checking in CI at zero errors; ruff + frontend lint/vitest gates on dev-branch PRs
- E2E suite (real qBittorrent + mock RSS via Docker) green: 67/67
scripts/dev.shβ one-command seeded development environment- Backend test suite: 990 tests (was 726 at 3.2)
Upgrade notes
- Migrations v9βv14 run automatically on first start; a failed migration now aborts startup instead of continuing silently
group_tagkeeps its historical meaning (qB rule naming only) β renamed filenames are unchanged, so existing seeding libraries are not touched- Beta feedback welcome, especially on aria2 setups, movie/special organization, and the new preference dedup