mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-11-04 14:45:26 +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 地址
183 lines
8.4 KiB
Markdown
183 lines
8.4 KiB
Markdown
# 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)
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
1. RSS feeds are parsed by `module/rss/` to extract torrent information
|
|
2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata
|
|
3. Downloads are managed via `module/downloader/` (qBittorrent API)
|
|
4. Files are organized by `module/manager/` into standard directory structure
|
|
5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`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 an `AsyncSession` and are `async def`. `Database` is 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, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.
|
|
- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.
|
|
- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; 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-hoc `settings.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-dev` branches: Active development (e.g., `4.0-dev`)
|
|
- Bug fixes → PR to current released version's `-dev` branch
|
|
- New features → PR to next version's `-dev` branch
|
|
- Plugin listings → PR to `main`; `plugin-registry.yml` and `docs.yml` publish from `main`. Merge `main` back into the `-dev` branch before each release
|
|
|
|
## Releasing
|
|
|
|
All releases are triggered by manually pushing a tag — merging a PR never releases.
|
|
|
|
### Beta Version
|
|
|
|
1. Update version in `backend/pyproject.toml`
|
|
2. Update `CHANGELOG.md` with the new version heading
|
|
3. Commit and push to the dev branch
|
|
4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):
|
|
```bash
|
|
git tag 3.2.0-beta.4
|
|
git push origin 3.2.0-beta.4
|
|
```
|
|
5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains "beta", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)
|
|
|
|
### Stable Version
|
|
|
|
1. Merge the dev branch into `main` via PR (this only runs tests and a build test)
|
|
2. Tag the merge commit on `main` with the bare semver version and push:
|
|
```bash
|
|
git tag 3.3.2 <merge-commit-on-main>
|
|
git push origin 3.3.2
|
|
```
|
|
3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/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:
|
|
|
|
1. Append a `Migration(version, "description", (…SQL…), already_applied=column_exists("table", "col"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)
|
|
2. Provide an `already_applied` guard (`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_version` makes it run once, so its guard may only say "nothing to fix here".
|
|
3. 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)
|