mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-07-27 00:52:21 +08:00
Merging PR #1063 ("Doc update", 3.3-dev -> main) triggered the stable release path, which fell back to the raw PR title as the version string and shipped a Docker image tagged Doc-update as :latest — every container pulling latest then crashed on SemVer parsing (#1065). The release trigger is now explicit: - bare X.Y.Z tag -> stable release, refused unless the tagged commit is an ancestor of main - tag containing alpha/beta -> pre-release (unchanged) - PR merges only run tests and a docker build test Also pass head.ref through an env var instead of inlining it in the script (injection hardening), and take release notes solely from the changelog file since tag pushes carry no PR body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jejs2dffkscAbhZkcjZ1oK
8.0 KiB
8.0 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 black 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
pnpm format
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: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+
- TypeScript: ESLint + Prettier
- Run formatters before committing
Git Branching
main: Stable releases onlyX.Y-devbranches: Active development (e.g.,3.2-dev)- Bug fixes → PR to current released version's
-devbranch - New features → PR to next version's
-devbranch
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 - 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)