mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-10-29 03:36:15 +08:00
- 部署文档、升级指南与 README 改为正式版说法:latest = 4.0,3.3 固定为 3.3.7 - docs/changelog/4.0.md 新增 4.0.0 汇总(升级前必读、破坏性变更、新功能、主要修复),链接改为绝对地址 - 文档站与插件市场改为从 main 发布,插件上架 PR 的目标分支改为 main - 文档站页脚版本 v4.0.0;en/ja README 的 star history 地址
8.4 KiB
8.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
AutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.
Development Commands
Backend (Python)
# Install dependencies
cd backend && uv sync
# Install with dev tools
cd backend && uv sync --group dev
# Run development server (port 7892, API docs at /docs)
cd backend/src && uv run python main.py
# Run tests
cd backend && uv run pytest
cd backend && uv run pytest src/test/test_xxx.py -v # run specific test
# Linting and formatting
cd backend && uv run ruff check src
cd backend && uv run ruff format src
# Add a dependency
cd backend && uv add <package>
# Add a dev dependency
cd backend && uv add --group dev <package>
Frontend (Vue 3 + TypeScript)
cd webui
# Install dependencies (uses pnpm, not npm)
pnpm install
# Development server (port 5173)
pnpm dev
# Build for production
pnpm build
# Type checking
pnpm test:build
# Linting and formatting
pnpm lint
pnpm lint:fix
Docker
docker build -t auto_bangumi:latest .
docker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest
Architecture
backend/src/
├── main.py # FastAPI entry point, mounts API at /api
├── module/
│ ├── api/ # REST API routes (v1 prefix)
│ │ ├── auth.py # Authentication endpoints
│ │ ├── bangumi.py # Anime series CRUD
│ │ ├── rss.py # RSS feed management
│ │ ├── config.py # Configuration endpoints
│ │ ├── program.py # Program status/control
│ │ └── search.py # Torrent search
│ ├── core/ # Application logic
│ │ ├── context.py # AppContext composition root (built in create_app, on app.state.ctx)
│ │ ├── scheduler.py # PeriodicTask + Scheduler (generic background-loop runner)
│ │ ├── loops.py # The individual periodic tick functions (rss/rename/offset/calendar)
│ │ └── offset_scanner.py
│ ├── models/ # SQLModel ORM models (Pydantic + SQLAlchemy)
│ ├── database/ # Async DB (aiosqlite) — repos + Database + migrations.py
│ ├── rss/ # RSS parsing and analysis
│ ├── downloader/ # qBittorrent integration
│ │ ├── base.py # Downloader Protocol + DownloaderCapabilities
│ │ └── client/ # Download client implementations (qb, aria2, mock)
│ ├── searcher/ # Torrent search providers (Mikan, DMHY, Nyaa)
│ ├── parser/ # Torrent name parsing, metadata extraction
│ │ └── analyser/ # TMDB, Mikan, OpenAI parsers
│ ├── manager/ # File organization and renaming
│ ├── notification/ # Notification plugins (Telegram, Bark, etc.)
│ ├── conf/ # Configuration management, settings
│ ├── network/ # HTTP client utilities
│ └── security/ # JWT authentication
webui/src/
├── api/ # Axios API client functions
├── components/ # Vue components (basic/, layout/, setting/)
├── pages/ # Router-based page components
├── router/ # Vue Router configuration
├── store/ # Pinia state management
├── i18n/ # Internationalization (zh-CN, en-US)
└── hooks/ # Custom Vue composables
Key Data Flow
- RSS feeds are parsed by
module/rss/to extract torrent information - Torrent names are analyzed by
module/parser/analyser/to extract anime metadata - Downloads are managed via
module/downloader/(qBittorrent API) - Files are organized by
module/manager/into standard directory structure - Periodic loops (
module/core/loops.py) run under aSchedulerowned by the lifespanAppContext(module/core/context.py)
Architecture conventions (3.3+)
- Async DB throughout. Everything runs on the async engine (
sqlite+aiosqlite, WAL). Repositories (database/{bangumi,rss,torrent,user,passkey}.py) take anAsyncSessionand areasync def.Databaseis an async context manager owning one session with the repos attached (db.rss,db.bangumi, …). - Session per operation. Get a session via
Depends(get_db)in routes, orasync with Database() as db:in loops/services. Never store a session on anything that outlives one request or one loop tick.AppContextholds no session. - Services take dependencies in their constructor (composition, not inheritance):
RSSEngine(db),TorrentManager(db),Renamer(client),SearchTorrent(). They useself.db.<repo>internally; callers that only need a repo usedb.<repo>directly. - Downloaders implement the
DownloaderProtocol and declareDownloaderCapabilities; the facade (DownloadClient) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call. - Config reloads go through
AppContext.reload_settings()(settings + http client + notifier + scheduler), not ad-hocsettings.load().
Code Style
- Python: ruff format (88 char lines), Ruff linter (E, F, I rules), target Python 3.14
- TypeScript: ESLint (@antfu/eslint-config)
- Run formatters before committing
Git Branching
main: Stable releases, plus plugin registry PRs (plugins/registry/)X.Y-devbranches: Active development (e.g.,4.0-dev)- Bug fixes → PR to current released version's
-devbranch - New features → PR to next version's
-devbranch - Plugin listings → PR to
main;plugin-registry.ymlanddocs.ymlpublish frommain. Mergemainback into the-devbranch before each release
Releasing
All releases are triggered by manually pushing a tag — merging a PR never releases.
Beta Version
- Update version in
backend/pyproject.toml - Update
CHANGELOG.mdwith the new version heading - Commit and push to the dev branch
- Create and push a tag with the version name (e.g.,
3.2.0-beta.4):git tag 3.2.0-beta.4 git push origin 3.2.0-beta.4 - The CI/CD workflow (
.github/workflows/build.yml) detects the tag contains "beta", uses the tag name as the VERSION string, generatesmodule/__version__.py, and builds the Docker image (tagged<version>+dev-latest)
Stable Version
- Merge the dev branch into
mainvia PR (this only runs tests and a build test) - Tag the merge commit on
mainwith the bare semver version and push:git tag 3.3.2 <merge-commit-on-main> git push origin 3.3.2 - CI validates the tag is
X.Y.Zand points to a commit onmain(refuses otherwise), then builds and pushes Docker images (tagged<version>+latest) and creates the GitHub release with notes fromdocs/changelog/<X.Y>.md
The VERSION is injected at build time via CI — module/__version__.py does not exist in the repo. At runtime, module/conf/config.py imports it or falls back to "DEV_VERSION".
Database Migrations
Schema migrations are tracked via a schema_version table in SQLite. To add a new migration:
- Append a
Migration(version, "description", (…SQL…), already_applied=column_exists("table", "col"))entry to theMIGRATIONStuple inbackend/src/module/database/migrations.py(CURRENT_SCHEMA_VERSIONis derived from the list — do not edit it by hand) - Provide an
already_appliedguard (column_exists/table_exists) so a schema created out-of-band is detected and skipped- For a one-time data fix, pass
data_step=<fn(conn: Connection)>(statements may be empty). It runs after the SQL in the same SAVEPOINT.schema_versionmakes it run once, so its guard may only say "nothing to fix here".
- For a one-time data fix, pass
- Migrations run automatically on startup via
run_migrations()(each in a SAVEPOINT, stopping on first failure)
Notes
- Documentation and comments are in Chinese
- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)
- External integrations: qBittorrent API, TMDB API, OpenAI API
- Version tracked in
/config/version.info(for cross-version upgrade detection)