架构
进阶
动手做大改动之前,先弄清代码放在哪里、要守哪些规则。
简要说明
简要说明 的链接HolyArrs 是一个 Go 程序,Web 应用内置在里面。它在端口 6262 上提供 Web 应用和 JSON API,数据存在配置文件夹里的 2 个 SQLite 文件中。它会向外调用下载器、来源(通过 Jackett 或 Prowlarr)、媒体服务器、通知渠道和 HolyArrs 元数据服务器。
跟着一条请求走一遍。有人在探索页请求一部电影。
requests记下这条请求。- 批准之后,
movies向sources要资源。 mediafiles里的挑选规则给它们打分。downloads把最好的那个发给下载器。- 下载完成后,
mediafiles导入文件。 mediaservers和alerts收到消息。
代码地图
代码地图 的链接app/backend/cmd/holyarrs/ main.go starts the program; wiring.go builds the modules and joins themapp/backend/internal/<module>/ one flat folder per moduleapp/backend/internal/core/ plumbing every module may useapp/backend/tools/ dev-only programsapp/frontend/ the SvelteKit web app; embed.go bundles its buildapp/frontend/src/routes/<page>/ thin pages that combine module partsapp/frontend/src/lib/<module>/ each module's web codeapp/frontend/src/lib/ui/ parts used by 2 or more modules, and nothing elseapp/frontend/src/lib/core/ server client, app state, helpersapp/tests/ end-to-end tests (Playwright)deploy/ the Dockerfile and release scriptsdocs/ guides and these pagesgo.mod 放在仓库根部,因为 go:embed 够不到上级文件夹。
东西在哪里找
东西在哪里找 的链接| 你想改 | 去这里找 |
|---|---|
| 资源怎么挑选 | internal/mediafiles |
| 某个下载器的客户端 | internal/downloads,契约测试在 internal/downloads/conformance_test.go |
| 某个通知渠道 | internal/alerts |
| 登录、用户、API 密钥 | internal/accounts |
| 首次运行的设置向导 | internal/setup、app/frontend/src/routes/welcome |
| 导入下载好的文件(解压、标签、匹配) | internal/importer |
| 媒体库文件夹、接管和重命名 | internal/library |
| 各行和各栏内容怎么挑、怎么排 | internal/suggest |
| 哪些功能模块是开着的 | internal/core/parts |
| 某个页面地址 | app/frontend/src/routes/ |
| 某个迁移 | internal/core/database/migrations/ |
| Docker 镜像 | deploy/Dockerfile |
规则
规则 的链接app/backend/tools/structurecheck 里的检查会在任何一条规则被破坏时让构建失败。运行它们的命令在测试里。
- 分层顺序。 一个模块只能导入更低层的模块,而且只能导入它们的根包。同一层的模块互不导入。
- 向上调用。 低层模块需要高层模块的东西时,由高层模块把普通数据传下来,或者由低层模块定义一个小接口,交给
wiring.go填上。 - SQL 不出门。 只有模块自己的
store*.go文件里能写 SQL,而且只能操作自己的表。要读别的模块的行,就调用它的服务。 - 共享表归 core。
settings、schedules、secrets、jobs和events要通过 core 的辅助函数来访问。 - 对外只有一个出口。 每个对外调用都走
core/outbound。 - 暂未开放的功能要在
core/startup注册一个开关。开关关着时,路由不存在,页面也会隐藏这个功能。 - 不要杂物包。 不要
util、common、shared或helpers。
分层顺序见模块。
进阶
进阶 的链接模块内部
每个后端模块都用同样的文件名。
| 文件 | 内容 |
|---|---|
routes.go |
API 路由,每条都带着它需要的权限 |
service.go 和各主题文件 |
供其他模块调用的逻辑 |
store.go、store_<topic>.go |
操作模块自己那些表的全部 SQL |
types.go |
模块的记录 |
在 Web 这边,lib/<module>/ 里有 index.ts(其他模块可以用的东西)、它的 Svelte 组件和对应的测试;只有当它有自己的调用或状态时,才会有 api.ts 和 state.svelte.ts。
core 包
core 是底层管道。它不含任何产品规则,也不导入任何模块。
| 包 | 内容 |
|---|---|
core/database |
打开并迁移两个 SQLite 文件、查询辅助函数、设置和事件的辅助函数、共享的行字段、历史记录裁剪 |
core/files |
文件和文件夹的辅助函数、可用磁盘空间 |
core/releasename |
从资源名里读出画质、发布组和集号 |
core/outbound |
调用外部服务器的唯一出口,带地址检查 |
core/secrets |
密钥存储和密钥轮换 |
core/logs |
应用日志和崩溃记录 |
core/jobs |
后台任务队列、计划,以及崩溃后会重启的循环 |
core/webserver |
路由管道、URL 基础路径、压缩、实时推送 |
core/startup |
运行身份用户、低内存模式、暂未开放功能的开关、内存上限、功能模块 |
core/parts |
功能模块开关,每个模块在提供服务或运行之前都要先问它 |
core/model |
共享类型,比如操作者和对象 |
core 必须碰模块数据时,由模块在 wiring.go 里向 core 注册一个钩子。密钥轮换就是这样做的。
数据
| 文件 | 内容 |
|---|---|
holyarrs.db |
媒体库、请求、设置,以及其他所有重要的东西 |
holyarrs-events.db |
历史记录和其他事件行。它会不断变大,裁剪时不会动主文件 |
迁移是带编号的 SQL 文件,放在 core/database/migrations/main 和 core/database/migrations/events 里。它们在启动时运行。
相关页面
相关页面 的链接HolyArrs 是免费的。如果它帮你省了时间,欢迎在 GitHub 上点个 Star、赞助它或请我喝杯咖啡。