mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-30 20:54:32 +08:00
- notification 域:渠道能力(MessageChannel→NotificationChannel、ChannelCapability* 迁入 notification.py) - message 域:消息收发(Notification→Message、NotificationType→MessageType、CommingMessage→IncomingMessage、NotificationHistoryItem→MessageHistoryItem、NotificationClear*→MessageClear*) - Agent 工具契约:send_notification_message→send_message、notification_callback→message_callback - 源码不保留旧名物理别名,旧导入经 app/runtime/compat/manifest.py SYMBOL_ALIASES 惰性解析 - API 路径与持久化键冻结不变,前端零改动 - 新增兼容守护测试与 docs/rules/07 命名边界规范
125 lines
6.3 KiB
Markdown
125 lines
6.3 KiB
Markdown
# 07 — Naming Conventions
|
|
|
|
All new code must follow these conventions. Consistent naming is how the codebase communicates intent without comments.
|
|
|
|
---
|
|
|
|
## Files
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| Python source files | `snake_case.py` | `download.py`, `qbittorrent.py`, `package.py` |
|
|
| New files in canonical capability packages | Focused `snake_case.py`; prefer a package-owned noun and an existing owned domain file before adding one | `torrent.py`, `plugin_manager.py`, `package.py` |
|
|
| Module package directories | `snake_case/` | `qbittorrent/`, `synologychat/` |
|
|
| Test files | `test_<domain>.py` | `test_download_chain.py`, `test_subscribe_endpoint.py` |
|
|
| Alembic migrations | Auto-generated by Alembic; do not rename | `20240101_add_column.py` |
|
|
| Skill directories | `<kebab-case>/` | `transfer-failed-retry/`, `moviepilot-cli/` |
|
|
|
|
---
|
|
|
|
## Classes
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| Chain classes | `<Domain>Chain` | `DownloadChain`, `SearchChain`, `SubscribeChain` |
|
|
| Module classes | `<Backend>Module` | `QbittorrentModule`, `EmbyModule`, `TelegramModule` |
|
|
| Oper (data access) classes | `<Model>Oper` | `SubscribeOper`, `SystemConfigOper`, `TransferHistoryOper` |
|
|
| Helper classes | `<Domain>Helper` | `TorrentHelper`, `DirectoryHelper`, `MessageHelper` |
|
|
| Pydantic schema models | `PascalCase`, noun-focused | `MediaInfo`, `TorrentInfo`, `DownloadingTorrent` |
|
|
| SQLAlchemy model classes | `PascalCase`, singular noun | `Subscribe`, `TransferHistory`, `SystemConfig` |
|
|
| Enum classes | `PascalCase` | `MediaType`, `EventType`, `ModuleType` |
|
|
| Manager classes | `<Domain>Manager` | `ModuleManager`, `PluginManager`, `EventManager` |
|
|
| General classes | `PascalCase` | `MetaInfo`, `Context`, `ChainBase` |
|
|
|
|
---
|
|
|
|
## Functions and Methods
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| All functions and methods | `snake_case` | `get_subscribe`, `run_module`, `on_config_changed` |
|
|
| Private methods | `_snake_case` (leading underscore) | `_submit_download_added_task`, `_parse_result` |
|
|
| Event handler methods | `on_<event_name>` or descriptive | `on_transfer_complete`, `handle_config_changed` |
|
|
| Module interface methods | Match `_ModuleBase` contract | `init_module`, `init_setting`, `get_name`, `get_type`, `test`, `stop` |
|
|
| Oper methods | Verb + noun | `get`, `add`, `update`, `delete`, `list` |
|
|
|
|
---
|
|
|
|
## Variables and Parameters
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| Local variables | `snake_case` | `torrent_info`, `media_type`, `download_dir` |
|
|
| Instance attributes | `snake_case` | `self.download_history`, `self.config` |
|
|
| Constants (module-level) | `UPPER_SNAKE_CASE` | `DEFAULT_EVENT_PRIORITY`, `MIN_EVENT_CONSUMER_THREADS` |
|
|
| Private variables | `_snake_case` (leading underscore) | `_instance`, `_lock` |
|
|
| Type variables | `PascalCase` with `TypeVar` | `T = TypeVar("T")` |
|
|
|
|
---
|
|
|
|
## Enums
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| Enum class name | `PascalCase` | `MediaType`, `TorrentStatus`, `EventType` |
|
|
| Enum members | `PascalCase` (for complex enums) | `MediaType.MOVIE`, `EventType.TransferComplete` |
|
|
| String enum values | Match the domain language | `MediaType.MOVIE = '电影'`, `TorrentStatus.TRANSFER = '可转移'` |
|
|
| `SystemConfigKey` values | Match the config key as a string | `SystemConfigKey.RssUrls = "RssUrls"` |
|
|
|
|
---
|
|
|
|
## Configuration and Settings
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| `Settings` / `ConfigModel` fields | `UPPER_SNAKE_CASE` | `API_TOKEN`, `LLM_MODEL`, `QB_HOST` |
|
|
| `SystemConfigKey` enum members | `PascalCase` | `SystemConfigKey.RssUrls`, `SystemConfigKey.SubscribeFilter` |
|
|
| Environment variable names | `UPPER_SNAKE_CASE` | `AI_AGENT_ENABLE`, `DB_TYPE` |
|
|
|
|
---
|
|
|
|
## API Endpoints and Routers
|
|
|
|
| Context | Convention | Examples |
|
|
|---|---|---|
|
|
| Endpoint function names | `snake_case`, verb-first | `get_subscribe_list`, `add_download`, `delete_history` |
|
|
| URL path segments | `kebab-case` or `snake_case` matching existing patterns | `/api/v1/subscribe`, `/api/v1/transfer/history` |
|
|
| Router tags | Match the resource domain name | `"subscribe"`, `"download"`, `"media"` |
|
|
|
|
---
|
|
|
|
## Message / Notification Domain Boundary
|
|
|
|
`message` 与 `notification` 是两个不同的语义域,新增或修改相关代码时必须按职责选名,不得混用:
|
|
|
|
| 语义域 | 职责 | 规范命名示例 |
|
|
|---|---|---|
|
|
| `notification` | 通知渠道能力:渠道枚举、渠道配置、渠道发现、渠道管理、渠道能力描述 | `NotificationChannel`, `NotificationConf`, `NotificationHelper`, `NotificationChain`, `NotificationAction`, `ChannelCapabilityManager`, `ModuleType.Notification`, `channel_manage` |
|
|
| `message` | 各渠道发送或接收的消息:消息体、消息类型、消息链、消息历史、消息队列 | `Message`, `MessageType`, `IncomingMessage`, `MessageChain`, `MessageHistoryItem`, `MessageOper`, `post_message`, `message_parser` |
|
|
|
|
| 规则 | 说明 |
|
|
|---|---|
|
|
| 渠道本身用 notification | 渠道是能力提供方,如 `NotificationChannel` 枚举、`NotificationConf` 渠道配置 |
|
|
| 消息内容与收发用 message | 消息是被传输的内容,如发送体 `Message`、接收体 `IncomingMessage`、分类 `MessageType` |
|
|
| 渠道 × 消息的交叉概念按主导方判断 | 按渠道控制消息开关的 `NotificationSwitch` 属渠道能力;消息历史清理 `MessageClearScope` 属消息 |
|
|
| 历史旧名不在源码保留 | `Notification`、`MessageChannel`、`NotificationType`、`CommingMessage` 等旧名仅登记在 `app/runtime/compat/manifest.py` 的 `SYMBOL_ALIASES`,新代码一律使用规范名 |
|
|
| 持久化值与外部协议冻结 | 枚举值、`SystemConfigKey` 配置值、DB 表名、API 路径、外部平台字段(如 Jellyfin 的 `NotificationType`)不随命名统一变更 |
|
|
|
|
---
|
|
|
|
## Anti-Patterns
|
|
|
|
| Wrong | Correct |
|
|
|---|---|
|
|
| `class downloadchain:` | `class DownloadChain:` |
|
|
| `class QBModule:` | `class QbittorrentModule:` |
|
|
| `def GetSubscribe():` | `def get_subscribe():` |
|
|
| `TORRENT_info = ...` | `torrent_info = ...` |
|
|
| `def handleConfigChanged():` | `def on_config_changed():` or `def handle_config_changed():` |
|
|
| `SystemConfigOper().get("RssUrls")` | `SystemConfigOper().get(SystemConfigKey.RssUrls)` |
|
|
| `class subscribe_oper:` | `class SubscribeOper:` |
|
|
| `MessageChannel.Telegram`(新代码) | `NotificationChannel.Telegram` |
|
|
| `Notification(title=...)`(新代码) | `Message(title=...)` |
|
|
|
|
*Last Updated: 2026-08-16*
|