API reference (Simplified Chinese): 全部端点,每组一页 # API 参考 > 本参考由 `crates/lanrurugi-api-docgen` 从服务端自己的路由注册生成:共 **248** 个端点,分为 **39** 组。每个端点都给出方法、完整路径、参数与响应示例,并带一个请求面板——填入**你自己的实例地址 本参考由 `crates/lanrurugi-api-docgen` 从服务端自己的路由注册生成:共 **248** 个端点,分为 **39** 组。每个端点都给出方法、完整路径、参数与响应示例,并带一个请求面板——填入**你自己的实例地址**即可直接发送,请求由浏览器直接发往该地址。 * [搜索 API](./search/) — 9 * [档案 API](./archives/) — 29 * [数据库 API](./database/) — 14 * [分类 API](./categories/) — 7 * [Tankoubon API](./tankoubons/) — 13 * [图章 API](./stamps/) — 8 * [插件 API](./plugins/) — 12 * [Shinobu API](./shinobu/) — 4 * [Minion API](./minion/) — 3 * [OPDS 目录](./opds/) — 3 * [其他 API](./misc/) — 5 * [活动日志](./activity/) — 6 * [API 令牌](./api-tokens/) — 4 * [档案拆分](./archive-split/) — 5 * [跨域登录](./auth-bridge/) — 4 * [性能基准](./bench/) — 2 * [书签](./bookmarks/) — 13 * [下载队列](./download-queue/) — 21 * [重复检测](./duplicates/) — 3 * [字体模式](./font-pattern/) — 2 * [健康检查](./health/) — 1 * [后台任务](./jobs/) — 3 * [登录](./login/) — 4 * [日志](./logs/) — 1 * [OpenSearch](./opensearch/) — 1 * [插件向导](./plugin-wizard/) — 7 * [偏好设置](./preferences/) — 2 * [推荐](./recommend/) — 1 * [维护脚本](./scripts/) — 3 * [登录设备](./sessions/) — 3 * [设置](./settings/) — 4 * [库统计](./stats/) — 3 * [订阅](./subscriptions/) — 25 * [Tankoubon 分组](./tankoubon-grouping/) — 8 * [术语表](./terminology-glossary/) — 3 * [页面翻译](./translation/) — 6 * [翻译设置](./translation-settings/) — 4 * [版本](./version/) — 1 * [AI 用量](./llm-usage/) — 1 怎么让浏览器能直接请求你自己的实例(跨域、HTTPS、令牌),见[用文档站测试 API](../guide/api-testing/)。 [下载 OpenAPI 文档(JSON)](/openapi.json) # 活动日志 > 6 endpoints. 6 endpoints. ## 删除选中的活动记录 [Section titled “删除选中的活动记录”](#删除选中的活动记录) DELETEhttp\://localhost:3000/api/activity 按 ID 批量删除。仅限会话调用——任何角色的 API 令牌都会被拒绝,因此令牌无法抹掉自己的审计记录。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出活动记录 [Section titled “列出活动记录”](#列出活动记录) GEThttp\://localhost:3000/api/activity 一页活动记录,最新的在前,范围限定为调用者有权看到的内容(见本文件头部的说明)。 目标为某个档案的记录会附带该档案是否仍然存在的标注,这样客户端可以显示「此后已被删除」,而不是一个死链接。 权限差异 * **你能看到哪些条目取决于你的身份。** 网页会话能看到全部记录;管理员令牌能看到它自己产生的、以及所有 guest 令牌产生的记录;guest 令牌只能看到它自己产生的记录。所以令牌持有者看到的是完整日志的一个**子集**——返回空不代表什么都没发生。 #### 查询参数 * cursorstring可选 来自上一次响应 `next_cursor` 的不透明分页游标。 * limitinteger · min: 1 · max: 200 · default: 50可选 无论请求多少都会被夹到一个小固定范围内——不设上限的话,单个请求就能强制触发任意大的扫描。 * start_tsinteger可选 只返回该 Unix 秒级时间戳(含)之后的活动记录。 * end_tsinteger可选 只返回该 Unix 秒级时间戳(含)之前的活动记录。 * actorstring可选 逗号分隔的操作者键;多个值是「或」的关系。 * action_typestring可选 逗号分隔的操作类型;多个值是「或」的关系。 * outcomestring可选 逗号分隔的结果;多个值是「或」的关系。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• cursorquerylimitquerystart_tsqueryend_tsqueryactorqueryaction_typequeryoutcomequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除单条活动记录 [Section titled “删除单条活动记录”](#删除单条活动记录) DELETEhttp\://localhost:3000/api/activity/{id} 按 ID 删除单条记录。仅限会话调用,原因与批量删除相同。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000 idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出活动记录的筛选项 [Section titled “列出活动记录的筛选项”](#列出活动记录的筛选项) GEThttp\://localhost:3000/api/activity/facets 日志中出现过的操作类型与操作者,各自带计数——这样客户端可以按「实际存在的内容」来构建筛选界面,而不是按一份写死的列表。 与列表端点一样,范围限定为调用者可见的内容:只有当调用者有权读取某操作者的记录时,该操作者才会出现。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取活动记录的保留窗口 [Section titled “读取活动记录的保留窗口”](#读取活动记录的保留窗口) GEThttp\://localhost:3000/api/activity/retention 活动记录保留多久,单位为秒。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 设置活动记录的保留窗口 [Section titled “设置活动记录的保留窗口”](#设置活动记录的保留窗口) PUThttp\://localhost:3000/api/activity/retention 修改活动记录的保留时长。仅限会话调用:令牌不能缩短自己留下的痕迹能存活多久。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # API 令牌 > 4 endpoints. 4 endpoints. ## 列出 API 令牌 [Section titled “列出 API 令牌”](#列出-api-令牌) GEThttp\://localhost:3000/api/tokens 每一个已签发令牌的元数据。令牌密钥本身**绝不**包含在内:它只在下面那个创建调用中返回一次,且不会以可恢复的形式存储。 需要会话 cookie 登录。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 创建 API 令牌 [Section titled “创建 API 令牌”](#创建-api-令牌) POSThttp\://localhost:3000/api/tokens 签发一个新令牌并返回它的密钥——**这是它唯一一次被返回**。请当场保存;之后无法找回,只能替换。 过期时间按服务端自己的时钟计算,而不是采用客户端提供的时间戳,因此时钟不准的客户端无法铸造出比它申请的有效期更长的令牌。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 吊销 API 令牌 [Section titled “吊销 API 令牌”](#吊销-api-令牌) DELETEhttp\://localhost:3000/api/tokens/{id} 永久吊销一个令牌。仍在使用它的任何东西会立刻开始失败;令牌无法撤销吊销,只能替换。 需要会话 cookie 登录。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000 idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重命名 API 令牌 [Section titled “重命名 API 令牌”](#重命名-api-令牌) PATCHhttp\://localhost:3000/api/tokens/{id} 修改令牌的标签。需要会话 cookie 登录。 #### 路径参数 * idstring必填 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000 idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 档案拆分 > 5 endpoints. 5 endpoints. ## 获取拆分建议 [Section titled “获取拆分建议”](#获取拆分建议) GEThttp\://localhost:3000/api/archives/{id}/split-suggestion 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_split_suggestion`,位于 crates/lanrurugi-api/src/archive_split.rs:707。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 手动触发「立即分析该档案」 [Section titled “手动触发「立即分析该档案」”](#手动触发立即分析该档案) POSThttp\://localhost:3000/api/archives/{id}/split-suggestion 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archive_split.rs:681)的**译文**;原文以源码为准。 手动触发「立即分析该档案」的端点。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 返回档案内部的目录树(`GET /archives/{id}/split-tree`,含嵌套层级) [Section titled “返回档案内部的目录树(GET /archives/{id}/split-tree,含嵌套层级)”](#返回档案内部的目录树get-archivesidsplit-tree含嵌套层级) GEThttp\://localhost:3000/api/archives/{id}/split-tree 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archive_split.rs:508)的**译文**;原文以源码为准。 `GET /archives/{id}/split-tree`——返回档案内部的目录树,并递归展开其中嵌套的档案。这是只读的浏览用端点:它不调用 LLM,也不生成任何输出 ZIP。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 执行拆分 [Section titled “执行拆分”](#执行拆分) POSThttp\://localhost:3000/api/archives/{id}/split/execute 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `execute_split`,位于 crates/lanrurugi-api/src/archive_split.rs:735。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 拆分进度流 [Section titled “拆分进度流”](#拆分进度流) GEThttp\://localhost:3000/api/archives/{id}/split/stream 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `split_progress_stream`,位于 crates/lanrurugi-api/src/archive_split.rs:793。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 档案 API > 29 endpoints. 29 endpoints. ## 批量删除档案(`DELETE /archives`,请求体 `{ids: [...]}`) [Section titled “批量删除档案(DELETE /archives,请求体 {ids: \[...\]})”](#批量删除档案delete-archives请求体-ids-) DELETEhttp\://localhost:3000/api/archives 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archives.rs:618)的**译文**;原文以源码为准。 `DELETE /archives`(issue #63),请求体 `{ids: [...]}`——沿用本代码库已有的「复数资源 + 用 JSON 请求体指明操作对象」这一形态(见 `activity.rs::bulk_delete_activity` 的 `DELETE /activity`),而不是 `POST .../batch-delete` 那种动作式路径;按 RFC 9110,`DELETE` **可以**带请求体(虽然一些较旧的代理/客户端在实践中会静默丢掉它,但 Axum 和本项目自己的前端都处理得很好,而且本仓库已有先例)。Batch 页面自己的「删除档案」操作此前是在前端按选中的档案逐个发 `DELETE /archives/{id}`,就是一个普通的顺序循环(没有原子性,没有统一的审计点,而且——由于每个请求只报告自己的成功/失败——调用方除非在操作前后对比整个书库,否则无法知道*哪些* id 失败了)。这里把同样的逐 id 工作(`delete_one_archive`,与单条删除端点完全相同的清理)放到服务端一个请求里完成,并返回逐 id 的结果列表,让前端能准确展示发生了什么,而不是假定全部成功。 仅限会话调用(`route_policy.csv` 拒绝所有令牌角色以及 `anonymous`)——刻意比本文件里其他所有会修改档案的端点都更严格,那些端点 Token(Admin 或 Guest)都能调用。一个泄露或被写错的 API 令牌就能在一个请求里抹掉任意规模的库内容,其影响范围远大于令牌访问本来就允许的任何一个单目标端点;而本项目对批量删除并不存在像脚本化上传或元数据编辑那样的正当自动化场景——所以这条额外限制不会破坏任何真实工作流。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取全部档案 [Section titled “获取全部档案”](#获取全部档案) GEThttp\://localhost:3000/api/archives 返回数据库中全部档案的列表。按设计不包含 Tankoubon。 这个 JSON 里的 ID 可以用在其他端点上。 权限差异 * **访客和匿名调用者完全不可达。** 这是无范围的列表:它返回书库中的全部档案,不做任何分类范围限制——给访客开放它等于绕过 `/api/search` 强制的那套「访客可见」限制。访客请走 `/api/search`。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除档案 [Section titled “删除档案”](#删除档案) DELETEhttp\://localhost:3000/api/archives/{id} 同时删除档案元数据和服务器上存储的文件。\ 🙏 调用这个端点前请先向用户确认。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取档案所属分类 [Section titled “获取档案所属分类”](#获取档案所属分类) GEThttp\://localhost:3000/api/archives/{id}/categories 获取当前引用了该档案 ID 的全部分类。 #### 路径参数 * idstring必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 下载档案 [Section titled “下载档案”](#下载档案) GEThttp\://localhost:3000/api/archives/{id}/download 从服务端下载一个档案。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要下载的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 提取档案 [Section titled “提取档案”](#提取档案) GEThttp\://localhost:3000/api/archives/{id}/files 获取指向档案内各图片的 URL 列表。 如有必要,这个端点还会启动一个后台 Minion 任务来解压该档案,使其可供阅读。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * forceboolean可选 强制在后台完整重新提取该档案。在该档案完全重新提取完成之前,后续的 `/api/archives/:id/page` 调用仍可能用到已有的缓存文件。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathforcequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 提取页面缩略图 [Section titled “提取页面缩略图”](#提取页面缩略图) POSThttp\://localhost:3000/api/archives/{id}/files/thumbnails 为指定档案的每一页生成缩略图。 这个端点会把缩略图生成排入后台队列。 如果检测到全部缩略图都已存在,调用会返回 HTTP 200。\ 这个端点可以重复调用——如果该 ID 的缩略图任务已经在进行中,它只会把那个进行中任务的 ID 给你。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * forceboolean可选 是否强制重新生成全部缩略图,即使它们已经存在。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathforcequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清除档案的「新」标记 [Section titled “清除档案的「新」标记”](#清除档案的新标记) DELETEhttp\://localhost:3000/api/archives/{id}/isnew 清除档案上的「新!」标记。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 设置档案的「新」标记 [Section titled “设置档案的「新」标记”](#设置档案的新标记) PUThttp\://localhost:3000/api/archives/{id}/isnew 设置/恢复档案上的「新!」标记。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取档案元数据 [Section titled “获取档案元数据”](#获取档案元数据) GEThttp\://localhost:3000/api/archives/{id}/metadata 获取指定档案的元数据(标题、标签)。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新档案元数据 [Section titled “更新档案元数据”](#更新档案元数据) PUThttp\://localhost:3000/api/archives/{id}/metadata 更新指定档案的标签与标题。\ 通过这个方法提交给服务端的数据会**覆盖**原有数据。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * titlestring可选 档案的新标题。 * tagsstring可选 档案的新标签。 * summarystring可选 档案的新摘要。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathtitlequerytagsquerysummaryquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取档案的某一页 [Section titled “获取档案的某一页”](#获取档案的某一页) GEThttp\://localhost:3000/api/archives/{id}/page 获取档案的某一页。这个调用主要与 `/api/archives/files` 配合使用。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要下载的档案 ID。 #### 查询参数 * pathstring必填 图片路径。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpathquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 返回前 `N` 页的自然像素宽高 [Section titled “返回前 N 页的自然像素宽高”](#返回前-n-页的自然像素宽高) GEThttp\://localhost:3000/api/archives/{id}/page-dimensions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archives.rs:3688)的**译文**;原文以源码为准。 `GET /archives/{id}/page-dimensions?count=N`——只返回前 `N` 页的自然像素宽高,顺序与 `/files` 自己的 `pages` 数组一致(这样前端可以按下标直接配对,不必再做一次名称匹配)。它是对 `/files` 的**新增**端点,而不是折进 `/files`:`/files` 的既有调用方(第三方兼容的文件列表契约)不该被迫为一次需要逐条解析图片头的档案遍历买单;实际调用这个端点的只有无限滚动阅读视图(唯一真正需要它的调用方——用于在跳到恢复位置之前准确摆好尚未加载的 `` 尺寸;为什么它只限定在跳转前的那些页而不是整个档案,见 `read_page_dimensions` 自身的文档)。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除补丁(`DELETE /archives/{id}/patch`,删除 `.patch.zip` 旁挂文件并清理相关状态) [Section titled “删除补丁(DELETE /archives/{id}/patch,删除 .patch.zip 旁挂文件并清理相关状态)”](#删除补丁delete-archivesidpatch删除-patchzip-旁挂文件并清理相关状态) DELETEhttp\://localhost:3000/api/archives/{id}/patch 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archives.rs:1160)的**译文**;原文以源码为准。 `DELETE /archives/{id}/patch`——删除旁挂的 `.patch.zip`(如果有),并清除该档案的 `has_patch` 标记。让用户可以撤销一个补丁——比如在重跑对比流程后换用另一个来源的页面——而不必改动档案本身。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新阅读进度 [Section titled “更新阅读进度”](#更新阅读进度) PUThttp\://localhost:3000/api/archives/{id}/progress/{page} 告诉服务端你当前正在展示/阅读这个档案的第几页,以便它相应地更新内部的阅读进度。\ 这个端点还会用服务端当前时间戳更新该档案的最后阅读时间。 只有在你确认用户确实正在阅读你展示的那一页时才应调用它。\ **不要**在为了预加载图片而请求服务端时使用它。 阅读进度是否允许回退由客户端决定。(网页端在用户开始重读前面的页面时会减小进度值)\ 不过建议在开始更新进度时顺手清掉档案上的「新!」标记——只要新标记还在,网页端就不会显示任何阅读进度。 ⚠ 如果服务端配置为使用客户端进度跟踪,这个 API 调用会返回错误!\ 调用前请务必先用 `/api/info` 确认服务端是否跟踪阅读进度。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 * pageinteger必填 要更新到的当前阅读页码。 **必须**是正整数,且不超过该档案的总页数。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重命名档案(`PUT /archives/{id}/rename`,新增端点,legacy 没有对应功能) [Section titled “重命名档案(PUT /archives/{id}/rename,新增端点,legacy 没有对应功能)”](#重命名档案put-archivesidrename新增端点legacy-没有对应功能) PUThttp\://localhost:3000/api/archives/{id}/rename 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/archives.rs:1277)的**译文**;原文以源码为准。 `PUT /archives/{id}/rename`——新增端点,legacy 没有对应功能(legacy 根本没有档案重命名功能;已核对 `~/LANraragi/lib/LANraragi/Controller/*.pm` 与 `public/js/edit.js`,任何地方都没有 `rename` 相关引用)。它重命名的是档案在磁盘上的文件(不只是存储的 `title`/`name`),并保持 `Archive::file` 与 `LRR_FILEMAP` 同步——参照 `download_manager::ingest` 自己那套「暂存文件改名进 `archive_dir`」的修正逻辑,那是「档案文件路径变了,要同步更新跟踪它的两处」最接近的既有先例。 旁挂的 `.patch.zip`(它如何被关联见 `delete_patch` 自身的文档——同目录、同主文件名,纯靠文件名约定)会随档案一起改名:把它留在旧主文件名下会静默破坏 `patch::patch_path_for` 之后每一次查找,使一个已存在的补丁变得不可见,既不报错也不删除任何东西——这类「静默接近数据丢失」的 bug,远比让本函数直接拒绝这次改名要糟糕。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取档案所属的 Tankoubon [Section titled “获取档案所属的 Tankoubon”](#获取档案所属的-tankoubon) GEThttp\://localhost:3000/api/archives/{id}/tankoubons 获取当前引用了该档案 ID 的全部 Tankoubon。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取档案缩略图 [Section titled “获取档案缩略图”](#获取档案缩略图) GEThttp\://localhost:3000/api/archives/{id}/thumbnail 获取指定档案的缩略图。如果缩略图尚不存在,这个端点会返回一张占位图。若想把缩略图生成排入后台,可以使用 `no_fallback` 查询参数——这样你会拿到一个后台任务 ID,而不是占位图。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID #### 查询参数 * no_fallbackstring · enum: true | false可选 关闭占位图,把缩略图排入提取队列,并返回 code 202 的 JSON。图片已存在时该参数不起作用。(无论哪种情况,只要图片已存在就会以 code 200 返回它) * pageinteger · min: 0可选 指定要取哪一页的缩略图,默认为封面,也就是第 1 页。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathno_fallbackquerytruepagequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新档案缩略图 [Section titled “更新档案缩略图”](#更新档案缩略图) PUThttp\://localhost:3000/api/archives/{id}/thumbnail 更新指定档案的封面缩略图。你可以指定用哪一页作为缩略图,也可以使用默认缩略图。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * pageinteger可选 用哪一页生成缩略图,默认第 1 页。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取页面缩略图 [Section titled “获取页面缩略图”](#获取页面缩略图) GEThttp\://localhost:3000/api/archives/{id}/thumbnails 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 从档案目录中移除条目 [Section titled “从档案目录中移除条目”](#从档案目录中移除条目) DELETEhttp\://localhost:3000/api/archives/{id}/toc 从指定档案的目录中删除一个条目。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * pageinteger必填 要删除的章节页码。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 向档案目录添加条目 [Section titled “向档案目录添加条目”](#向档案目录添加条目) PUThttp\://localhost:3000/api/archives/{id}/toc 向指定档案的目录添加一个条目。 目录以 JSON 编码的键值数组存储,把页码映射到从该页开始的章节标题。 #### 路径参数 * idstring · min: 40 · max: 40 · pattern必填 要处理的档案 ID。 #### 查询参数 * pageinteger必填 章节的起始页码。 * titlestring必填 章节标题。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagequerytitlequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取全部未打标签的档案 [Section titled “获取全部未打标签的档案”](#获取全部未打标签的档案) GEThttp\://localhost:3000/api/archives/untagged 获取没有任何标签记录的档案。 规则与批量打标签的筛选一致,因此 parody:、date_added:、series: 或 artist: 这类标签的存在不影响判定。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 上传档案 [Section titled “上传档案”](#上传档案) PUThttp\://localhost:3000/api/archives/upload 把档案上传到服务端。\ 如果附带该档案的 SHA1 校验和,服务端会做一次可选的传输中文件完整性校验,并在服务端算出的校验和不匹配时拒绝这次上传。 #### 请求体 multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Start or re-attach to a resumable upload [Section titled “Start or re-attach to a resumable upload”](#start-or-re-attach-to-a-resumable-upload) POSThttp\://localhost:3000/api/archives/upload/session Creates a session (an empty staged file plus a sidecar describing it) and returns the id. If `client_key` matches a session that is still alive, that session is returned instead, with the offset its bytes are already at — which is what makes a page refresh resumable rather than restarting the transfer. The returned `offset` is always read from the staged file’s real length, never from the sidecar, so a truncated or edited sidecar cannot make the server believe it holds bytes it does not. Sessions that have not been touched for 24 hours are swept by the operations here; the staged bytes also live in `temp_dir`, so `DELETE /api/tempfolder` reclaims them too. #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Abandon a session [Section titled “Abandon a session”](#abandon-a-session) DELETEhttp\://localhost:3000/api/archives/upload/session/{id} Drops the staged bytes and the sidecar. Safe to call on an unknown id. #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Upload session status [Section titled “Upload session status”](#upload-session-status) GEThttp\://localhost:3000/api/archives/upload/session/{id} The handshake a resuming client starts from: how many bytes the server actually holds for this session. `404` means unknown, expired, or already completed — in every case the client’s correct move is to start a new session. #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Append one chunk [Section titled “Append one chunk”](#append-one-chunk) PUThttp\://localhost:3000/api/archives/upload/session/{id} Appends the request body to the staged file, but only at the position the client claims. `Upload-Offset` is required and must equal the staged file’s real length; the response always reports the authoritative offset, including on failure: * `204` — the chunk was appended; `Upload-Offset` is the new length. * `409` — the client’s offset disagrees with the disk (a lost response, a retried chunk, two tabs); `Upload-Offset` says where to resume from. * `400` — missing or malformed `Upload-Offset`. A connection that dies mid-chunk keeps whatever bytes reached the disk and reports the offset, so a partial chunk is just fewer bytes rather than a corrupt one. The body is bounded at 64 MiB (the one-shot route is deliberately unbounded; a chunk is supposed to be small). #### 路径参数 * idstring必填 #### 请求头 * Upload-Offsetinteger必填 Byte position this chunk starts at; must equal the server's own length. #### 请求体 application/octet-stream #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Finish a session and ingest it [Section titled “Finish a session and ingest it”](#finish-a-session-and-ingest-it) POSThttp\://localhost:3000/api/archives/upload/session/{id}/complete Verifies what landed, hashes it, and hands it to the same ingest the one-shot route uses — including the persistent download-queue row, so a completed upload shows up (and can be removed) exactly like any other queue item. Verification: a `file_size` announced at session creation must equal the staged length (`417` otherwise, and the staged bytes are dropped), and an optional `file_checksum` is compared against the SHA-1 of the finished file (`417` on mismatch). That SHA-1 is computed by reading the staged file once at this point rather than persisting incremental hasher state: a resumed upload’s early chunks were hashed by processes that are long gone, and state that can silently desync from the bytes on disk is a worse trade than one sequential read of an already-local file. After this call the session no longer exists. #### 路径参数 * idstring必填 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 跨域登录 > 4 endpoints. 4 endpoints. ## 跨域登录回调 [Section titled “跨域登录回调”](#跨域登录回调) GEThttp\://localhost:3000/api/auth/bridge/callback 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `bridge_callback`,位于 crates/lanrurugi-api/src/auth_bridge.rs:599。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 准备跨域登录 [Section titled “准备跨域登录”](#准备跨域登录) GEThttp\://localhost:3000/api/auth/bridge/prepare 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `prepare_bridge`,位于 crates/lanrurugi-api/src/auth_bridge.rs:402。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 开始跨域登录 [Section titled “开始跨域登录”](#开始跨域登录) GEThttp\://localhost:3000/api/auth/bridge/start 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `start_bridge`,位于 crates/lanrurugi-api/src/auth_bridge.rs:464。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取认证配置 [Section titled “获取认证配置”](#获取认证配置) GEThttp\://localhost:3000/api/auth/config 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_auth_config`,位于 crates/lanrurugi-api/src/auth_bridge.rs:380。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 性能基准 > 2 endpoints. 2 endpoints. ## 获取报告 [Section titled “获取报告”](#获取报告) GEThttp\://localhost:3000/api/bench/{reportid} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_report`,位于 crates/lanrurugi-api/src/bench.rs:107。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 对调用者提供的 legacy/新版端点执行跨系统对比(两端都由调用者给出) [Section titled “对调用者提供的 legacy/新版端点执行跨系统对比(两端都由调用者给出)”](#对调用者提供的-legacy新版端点执行跨系统对比两端都由调用者给出) POSThttp\://localhost:3000/api/bench/run 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bench.rs:65)的**译文**;原文以源码为准。 对调用者提供的 legacy/新版端点执行跨系统对比(从本 crate 的角度看两者都是外部 HTTP 目标——即使「新版」恰好就是这个正在运行的实例、通过它自己的监听地址访问——所以同一份实现能同等驱动两种情况,与 `lanrurugi-bench-compare` 独立运行时的方式一致)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 书签 > 13 endpoints. 13 endpoints. ## 列出某个档案的书签页(不分页) [Section titled “列出某个档案的书签页(不分页)”](#列出某个档案的书签页不分页) GEThttp\://localhost:3000/api/archives/{id}/bookmarks 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:479)的**译文**;原文以源码为准。 `GET /archives/{id}/bookmarks`——不分页,只返回这一个档案被标记书签的页面(升序,每项附带解析出的文件名)。读者用它判断当前页是否已加书签(那里只关心 `page`),`BookmarkHoverGrid` 也用它(它的标题需要 `page` 和 `filename` 两者,此前要额外发一次 `GET /archives/{id}/files`)。不要求档案存在——与 `remove_bookmark` 的姿态一致:档案不存在就只是没有书签可报告(也没有文件名可解析)。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除书签(`DELETE /archives/{id}/bookmarks/{page}`,幂等) [Section titled “删除书签(DELETE /archives/{id}/bookmarks/{page},幂等)”](#删除书签delete-archivesidbookmarkspage幂等) DELETEhttp\://localhost:3000/api/archives/{id}/bookmarks/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:751)的**译文**;原文以源码为准。 `DELETE /archives/{id}/bookmarks/{page}`——幂等,与 `BookmarksRepository::remove` 自身的契约一致;不会先检查档案是否存在,因为为一个已被删除的档案移除书签属于正当清理,不是错误。下面那次活动日志查询只是一次*尽力而为*的标签获取,与上述宽松处理是两回事——档案缺失时移除本身照常进行,只是 `target.label: None`(退化为只有 `target.id`,与任何其他「资源先消失」的操作类型相同)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 添加书签(`POST /archives/{id}/bookmarks/{page}`,不校验 `page` 是否超出该档案的页数) [Section titled “添加书签(POST /archives/{id}/bookmarks/{page},不校验 page 是否超出该档案的页数)”](#添加书签post-archivesidbookmarkspage不校验-page-是否超出该档案的页数) POSThttp\://localhost:3000/api/archives/{id}/bookmarks/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:689)的**译文**;原文以源码为准。 `POST /archives/{id}/bookmarks/{page}`——bookmarks 不拿档案真实的 `pagecount` 去校验 `page`,与 `update_progress`(`archives.rs`)自身的宽松处理一致:唯一的调用方是读者界面,它总是传入自己当前、已经合法的页码。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 设置或清除该书签自身的名称(`PUT /archives/{id}/bookmarks/{page}/name`) [Section titled “设置或清除该书签自身的名称(PUT /archives/{id}/bookmarks/{page}/name)”](#设置或清除该书签自身的名称put-archivesidbookmarkspagename) PUThttp\://localhost:3000/api/archives/{id}/bookmarks/{page}/name 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:562)的**译文**;原文以源码为准。 `PUT /archives/{id}/bookmarks/{page}/name`——设置或清除该书签自身的名称。书签本身不存在时返回 `404`(名称不能比它所命名的书签活得更久,而在不存在的书签上设置名称会静默留下一个 `NAMES_HASH_KEY` 孤儿条目,任何 `add_bookmark` 调用都不会清理它)——与 `add_stamp`「档案必须先存在」的姿态一致,只是这里检查的是书签存在性而非档案存在性。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出全部书签(`GET /bookmarks`,按档案聚合后依 `sort`/分页参数排序分页) [Section titled “列出全部书签(GET /bookmarks,按档案聚合后依 sort/分页参数排序分页)”](#列出全部书签get-bookmarks按档案聚合后依-sort分页参数排序分页) GEThttp\://localhost:3000/api/bookmarks 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:252)的**译文**;原文以源码为准。 `GET /bookmarks`——全部书签,按档案聚合后依 `sort`/`cursor`/`limit` 排序分页。书签所属的档案已被删除时,它会被静默从结果中剔除,而不是让整个列表报错(与 `BookmarksRepository::list_all` 对个别格式错误条目已有的容忍一致——一个悬空引用不该拖垮其余全部仍然有效的书签)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取已保存的 `BookmarkHoverGrid` 翻页顺序偏好 [Section titled “读取已保存的 BookmarkHoverGrid 翻页顺序偏好”](#读取已保存的-bookmarkhovergrid-翻页顺序偏好) GEThttp\://localhost:3000/api/bookmarks/hover-page-order 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:984)的**译文**;原文以源码为准。 `GET /bookmarks/hover-page-order`——已保存的 `BookmarkHoverGrid` 翻页顺序偏好(从未设置过时是 `None`;那种情况下前端会套用它自己的默认值 `"pageDesc"`)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 写入翻页顺序偏好(不记入活动日志——与 `settings.rs` 对显示类偏好采取的姿态一致) [Section titled “写入翻页顺序偏好(不记入活动日志——与 settings.rs 对显示类偏好采取的姿态一致)”](#写入翻页顺序偏好不记入活动日志与-settingsrs-对显示类偏好采取的姿态一致) PUThttp\://localhost:3000/api/bookmarks/hover-page-order 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:1002)的**译文**;原文以源码为准。 不记入活动日志——属于仅影响显示的偏好,与 `settings.rs` 自己的 `theme` 字段采取的姿态相同(同样没有 `record_manual` 调用)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取「只显示自身匹配 `q` 的书签」这一已保存偏好 [Section titled “读取「只显示自身匹配 q 的书签」这一已保存偏好”](#读取只显示自身匹配-q-的书签这一已保存偏好) GEThttp\://localhost:3000/api/bookmarks/only-matching 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:1018)的**译文**;原文以源码为准。 `GET /bookmarks/only-matching`——已保存的「只显示自身匹配 `q` 的书签」偏好(从未设置过时为 `false`,与历史上一直显示全部的行为一致)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 写入「只显示匹配书签」偏好(不记入活动日志,与翻页顺序偏好姿态一致) [Section titled “写入「只显示匹配书签」偏好(不记入活动日志,与翻页顺序偏好姿态一致)”](#写入只显示匹配书签偏好不记入活动日志与翻页顺序偏好姿态一致) PUThttp\://localhost:3000/api/bookmarks/only-matching 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:1035)的**译文**;原文以源码为准。 不记入活动日志——与 `put_hover_page_order` 相同的「仅影响显示」姿态。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出 Tankoubon 内所有成员档案的书签,并换算成 Tankoubon 全局页码 [Section titled “列出 Tankoubon 内所有成员档案的书签,并换算成 Tankoubon 全局页码”](#列出-tankoubon-内所有成员档案的书签并换算成-tankoubon-全局页码) GEThttp\://localhost:3000/api/tankoubons/{id}/bookmarks 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:877)的**译文**;原文以源码为准。 `GET /tankoubons/{id}/bookmarks`——Tankoubon 内所有成员档案的全部书签,并换算成 Tankoubon 自己的全局页码。不分页,按全局页码升序——与 `list_bookmarks_for_archive` 自身的契约一致(用法也相同,都是给 `BookmarkHoverGrid` 用,只是这里对应 Tankoubon 卡片而不是普通档案卡片)。已不存在的成员档案(或 `pagecount` 为空,例如尚未扫描)会静默不贡献任何内容,而不是让整个请求失败——与 `TankoubonFullResponse` 自身文档所描述的、`full_data` 静默省略缺失成员是同一种容忍。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除 Tankoubon 书签(先换算全局页码再委托给档案级删除) [Section titled “删除 Tankoubon 书签(先换算全局页码再委托给档案级删除)”](#删除-tankoubon-书签先换算全局页码再委托给档案级删除) DELETEhttp\://localhost:3000/api/tankoubons/{id}/bookmarks/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:832)的**译文**;原文以源码为准。 `DELETE /tankoubons/{id}/bookmarks/{page}`——与 \[`add_tank_bookmark`] 相同的「先换算再委托」形态,委托对象是 \[`remove_bookmark`]。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 为 Tankoubon 添加书签(把 Tankoubon 全局页码换算到具体成员档案的页码) [Section titled “为 Tankoubon 添加书签(把 Tankoubon 全局页码换算到具体成员档案的页码)”](#为-tankoubon-添加书签把-tankoubon-全局页码换算到具体成员档案的页码) POSThttp\://localhost:3000/api/tankoubons/{id}/bookmarks/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:817)的**译文**;原文以源码为准。 `POST /tankoubons/{id}/bookmarks/{page}`——把 Tankoubon 全局 `page` 换算到真实的成员档案 + 局部页码(`tankoubons::resolve_tank_page`),然后委托给 \[`add_bookmark`] 自己的逻辑;写入本身仍然落在真实档案 ID 上,与在阅读 Tankoubon 时放置的图章相同(`stamps.rs` 自己的 Tankoubon 路由)——`bookmarks.rs` 底层的 `BookmarksRepository` 没有自己的 `TANK_` 概念,也永远不需要。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重命名 Tankoubon 书签(同样是先换算再委托) [Section titled “重命名 Tankoubon 书签(同样是先换算再委托)”](#重命名-tankoubon-书签同样是先换算再委托) PUThttp\://localhost:3000/api/tankoubons/{id}/bookmarks/{page}/name 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/bookmarks.rs:665)的**译文**;原文以源码为准。 `PUT /tankoubons/{id}/bookmarks/{page}/name`——与 `add_tank_bookmark`/`remove_tank_bookmark` 相同的「先换算再委托」形态,委托对象是 \[`rename_bookmark`]。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 分类 API > 7 endpoints. 7 endpoints. ## 获取全部分类 [Section titled “获取全部分类”](#获取全部分类) GEThttp\://localhost:3000/api/categories 获取服务端保存的全部分类。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 创建分类 [Section titled “创建分类”](#创建分类) PUThttp\://localhost:3000/api/categories 创建一个新分类。 #### 请求体 application/x-www-form-urlencoded, multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除分类 [Section titled “删除分类”](#删除分类) DELETEhttp\://localhost:3000/api/categories/{id} 删除一个分类。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取单个分类 [Section titled “获取单个分类”](#获取单个分类) GEThttp\://localhost:3000/api/categories/{id} 获取指定分类 ID 的详情。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新分类 [Section titled “更新分类”](#更新分类) PUThttp\://localhost:3000/api/categories/{id} 修改一个分类。 #### 请求体 application/x-www-form-urlencoded, multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把档案移出分类 [Section titled “把档案移出分类”](#把档案移出分类) DELETEhttp\://localhost:3000/api/categories/{id}/{archive} 把某个档案 ID 从一个分类中移除。 #### 路径参数 * idstring · min: 14 · max: 14 · pattern必填 要移出的分类 ID。 * archivestring · min: 40 · max: 40 · pattern必填 要移除的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpatharchivepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把档案加入分类 [Section titled “把档案加入分类”](#把档案加入分类) PUThttp\://localhost:3000/api/categories/{id}/{archive} 把指定的档案 ID(见「档案 API」)加入给定分类。 #### 路径参数 * idstring · min: 14 · max: 14 · pattern必填 要加入的分类 ID。 * archivestring · min: 40 · max: 40 · pattern必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpatharchivepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 数据库 API > 14 endpoints. 14 endpoints. ## 获取备份 JSON [Section titled “获取备份 JSON”](#获取备份-json) GEThttp\://localhost:3000/api/database/backup 扫描整个数据库并以 JSON 形式返回备份。 数据库较大时建议改用 POST 版本——这个基础 GET 端点如果生成备份耗时过长可能会超时。\ 这份备份可以通过「备份与恢复」功能手动重新导入。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 排入一个备份任务 [Section titled “排入一个备份任务”](#排入一个备份任务) POSThttp\://localhost:3000/api/database/backup 排入一个 Minion 任务来生成备份 JSON 文件。\ 用返回的任务 ID 查看进度,完成后下载该文件。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 从已完成的任务下载备份 JSON [Section titled “从已完成的任务下载备份 JSON”](#从已完成的任务下载备份-json) GEThttp\://localhost:3000/api/database/backup/{jobid} 下载由已完成的备份任务生成的备份 JSON 文件。 #### 路径参数 * jobidinteger必填 已完成的备份任务 ID。 #### 查询参数 * formatstring · enum: json | file可选 返回的备份格式,默认 `file`。`json` 会以 JSON 响应返回备份。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• jobidpathformatqueryjson 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清理数据库 [Section titled “清理数据库”](#清理数据库) POSThttp\://localhost:3000/api/database/clean 清理数据库:先隐藏、再移除那些文件已不在文件系统上的条目。\ 文件已不存在的条目在第一次清理时只做解除关联,因此不会出现在界面上——之后再跑一次清理才会**删除**这些已解除关联的条目。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清空数据库 [Section titled “清空数据库”](#清空数据库) POSThttp\://localhost:3000/api/database/drop 删除整个数据库,包括用户偏好设置。 这是个相当危险的端点,调用它可能会让你作为客户端被锁在服务端之外! #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 导入调用者直接上传的 LANraragi(或 LANrurugi)备份 JSON 文件——不需要实例在线 [Section titled “导入调用者直接上传的 LANraragi(或 LANrurugi)备份 JSON 文件——不需要实例在线”](#导入调用者直接上传的-lanraragi或-lanrurugi备份-json-文件不需要实例在线) POSThttp\://localhost:3000/api/database/import-legacy 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/database.rs:789)的**译文**;原文以源码为准。 导入调用者直接上传的 LANraragi(或 LANrurugi)备份 JSON 文件——不连接任何远端 Redis 实例(原因见 `lanrurugi_backup::import_legacy` 自身的模块文档:官方 LANraragi Docker 镜像默认从不把它内置的 Redis 暴露到容器外)。与上面的 `queue_restore` 是相同的 multipart 文件上传形态,但这里刻意做成独立的 handler/解析/持久化路径,而不是 `queue_restore` 的一个变体——尽管两者的 JSON 形状表面相似却绝不能共用代码,原因见 `import_legacy` 自身的文档。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 本实例一共执行过多少次 LANraragi 导入——前端在导入前会读它 [Section titled “本实例一共执行过多少次 LANraragi 导入——前端在导入前会读它”](#本实例一共执行过多少次-lanraragi-导入前端在导入前会读它) GEThttp\://localhost:3000/api/database/import-legacy/count 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/database.rs:998)的**译文**;原文以源码为准。 本实例一共执行过多少次 LANraragi 导入——前端在展示导入界面之前会读它,以便在第 2 次及以后的导入时给出提醒(「你之前做过这个——建议先做一次完整备份」),而不必等导入本身完成。只读,与 `queue_import_legacy` 自己的递增(在真实导入完成后发生)分开,与 `ImportSnapshotRepository::import_count` 自身的读/增分离一致。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 导入快照的元数据列表,最新的在前(不含 `document` 内容) [Section titled “导入快照的元数据列表,最新的在前(不含 document 内容)”](#导入快照的元数据列表最新的在前不含-document-内容) GEThttp\://localhost:3000/api/database/import-snapshots 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/database.rs:1025)的**译文**;原文以源码为准。 按时间倒序的元数据列表(不含 `document` 内容——见 `ImportSnapshotRepository::list_metadata` 自身的文档),供备份页面那个「时光机」式回滚点选择器使用。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除导入快照 [Section titled “删除导入快照”](#删除导入快照) DELETEhttp\://localhost:3000/api/database/import-snapshots/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `delete_import_snapshot`,位于 crates/lanrurugi-api/src/database.rs:1067。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把完整的 `BackupDocument` 内容作为可下载的 JSON 文件返回(与导入时接受的格式相同) [Section titled “把完整的 BackupDocument 内容作为可下载的 JSON 文件返回(与导入时接受的格式相同)”](#把完整的-backupdocument-内容作为可下载的-json-文件返回与导入时接受的格式相同) GEThttp\://localhost:3000/api/database/import-snapshots/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/database.rs:1045)的**译文**;原文以源码为准。 把完整的 `BackupDocument` 内容作为可下载的 JSON 文件返回——与 `POST /database/restore` 接受的形状相同,因此前端自己的「恢复」流程可以把这个文件原样喂回去,两端都不需要任何格式转换。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清除全部「新」标记 [Section titled “清除全部「新」标记”](#清除全部新标记) DELETEhttp\://localhost:3000/api/database/isnew 清除全部档案上的「新!」标记。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重建索引 [Section titled “重建索引”](#重建索引) POSThttp\://localhost:3000/api/database/rebuild-index 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `rebuild_index`,位于 crates/lanrurugi-api/src/database.rs:706。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 排入一个恢复任务 [Section titled “排入一个恢复任务”](#排入一个恢复任务) POSThttp\://localhost:3000/api/database/restore 排入一个 Minion 任务,从备份 JSON 文件恢复。\ 用返回的任务 ID 查看进度。 #### 请求体 multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取统计信息 [Section titled “获取统计信息”](#获取统计信息) GEThttp\://localhost:3000/api/database/stats 从数据库获取标签,并附带表示其流行度的数值。 #### 查询参数 * minweightinteger可选 只想取权重不低于给定最小值的标签时传这个参数。 不传时默认为 1,即返回全部标签。 * hide_excluded_namespacesstring可选 设为 true 时,把服务端设置里配置的命名空间从结果中排除。默认返回全部标签。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• minweightqueryhide_excluded_namespacesquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 下载队列 > 21 endpoints. 21 endpoints. ## 列出队列项 [Section titled “列出队列项”](#列出队列项) GEThttp\://localhost:3000/api/download_queue 下载队列中的每一个项,无论它当前处于什么状态。 需要实时更新时请优先使用 `/download_queue/stream`,它会在状态变化发生时主动推送,而不必轮询。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 向队列添加下载项 [Section titled “向队列添加下载项”](#向队列添加下载项) POSThttp\://localhost:3000/api/download_queue 批量添加。调用者已经自行判断好每个 URL 匹配的是哪个下载插件的 `url_pattern`;这个端点唯一的校验是 `plugin_namespace` 能解析到一个已安装的插件。 无效条目会被**逐条拒绝**,而不是让整批失败,因此粘贴的列表里有一个坏 URL 不会挡住其余的。请检查响应中的 `rejected`。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除一个队列项 [Section titled “删除一个队列项”](#删除一个队列项) DELETEhttp\://localhost:3000/api/download_queue/{id} 从队列中移除一个项。 正在下载中的项会以 409 拒绝——把它的记录从正在运行的后台任务下面抽掉,会让那个任务无处更新,队列里既没有行可以显示进度,也没有办法停止传输。请先停止它。 已经入库的队列项同样会被拒绝;请改为删除由此产生的那份档案。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新一个队列项 [Section titled “更新一个队列项”](#更新一个队列项) PATCHhttp\://localhost:3000/api/download_queue/{id} 部分更新:请求体中省略的字段会保留已存储的值,而不是被清空。约定与 `PUT /plugins/options` 相同。 #### 路径参数 * idstring必填 #### 请求体 Any subset of the item's editable fields. #### 响应 服务器地址http\://localhost:3000 idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## AI 质量对比判断(issue #77,针对某个下载队列项) [Section titled “AI 质量对比判断(issue #77,针对某个下载队列项)”](#ai-质量对比判断issue-77针对某个下载队列项) POSThttp\://localhost:3000/api/download_queue/{id}/compare 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:1857)的**译文**;原文以源码为准。 `POST /download_queue/{id}/compare`——issue #77 针对 `PendingFilenameConflict` 的 AI 质量对比判断:把刚暂存下来的下载(`temp_path`,在响应中暴露为 \[`imgcompare::Side::A`])与已经入库、持有同名文件的那个档案(`existing_id` 自己的文件,暴露为 \[`imgcompare::Side::B`])做页面对齐与清晰度比较——只读,自身不解决任何冲突;前端之后仍会根据用户(借助或不借助这次对比)的决定去调用 `.../overwrite` 或 `.../rename`。响应里刻意不把 `A`/`B` 标为「新」/「旧」(见 \[`lanrurugi_imgcompare::Side`] 自身的文档)——是这个 handler 为这个具体调用方赋予了那层含义。 它与下面流式的 \[`compare_queue_item_stream`] 并存(而不是被其取代),作为给不愿使用 SSE 的调用方准备的普通请求/响应降级方案——前端自己的 `ComparisonResultModal` 流程现在改走流式端点(原因见那个 handler 自身的文档)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 用用户挑选的页面生成 `.patch.zip` [Section titled “用用户挑选的页面生成 .patch.zip”](#用用户挑选的页面生成-patchzip) POSThttp\://localhost:3000/api/download_queue/{id}/compare/export-patch 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2610)的**译文**;原文以源码为准。 `POST /download_queue/{id}/compare/export-patch`——用用户挑选的 A 侧独有页面(`ComparisonResult.a_unmatched_pages`,issue #77 自己的后续设计)构建一个 `.patch.zip`,并返回其原始字节供下载,可直接放到目标档案所在磁盘位置并命名为 `<档案文件名>.patch.zip`(`lanrurugi_scanner::patch`)——这个端点自己不会把它写到那里(已确认的设计:「补丁不需要应用,只要放在漫画目录内」——由用户放置的文件,而不是本服务端未经请求就安装的东西)。目标永远是 B(本次冲突所针对的库中已有档案)——补丁只会在用户保留的那一版之上追加 A 自己的额外页面,绝不会反过来。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 保留书库中已有的那份档案、丢弃新下载的那份 [Section titled “保留书库中已有的那份档案、丢弃新下载的那份”](#保留书库中已有的那份档案丢弃新下载的那份) POSThttp\://localhost:3000/api/download_queue/{id}/compare/keep-b 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2719)的**译文**;原文以源码为准。 `POST /download_queue/{id}/compare/keep-b`——「保留库中已有的档案、丢弃这次下载」这一解决方式(issue #77 自己的后续设计)。它与本文件里其他所有解决动作都不同:那些都会把*暂存的*文件(A)以某种形式入库,要么替换 B(`overwrite_queue_item`),要么与 B 并存(`rename_queue_item`)——这一个则什么都不入库。B 已经在库里,就原样留在那里;实际发生的只有两件事:(1) `insertions`(如果有)会被直接写进 B 自己的旁挂 `.patch.zip`(不像 \[`export_compare_patch`] 那样只是返回给用户自行放置——这个流程的前端在用户*选择*保留 B 的过程中已经引导他挑好了插入点,所以没有「现在去把这个文件放好」这一步留给他做),以及 (2) 该队列项被直接删除,与普通的 `DELETE /download_queue/{id}` 相同——它已经没有东西需要跟踪了(已确认的设计:补丁的存在本身体现在 B 旁边的磁盘文件上,而不是队列项的某个标记)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 对比视图里某一侧某一页的真实图片 [Section titled “对比视图里某一侧某一页的真实图片”](#对比视图里某一侧某一页的真实图片) GEThttp\://localhost:3000/api/download_queue/{id}/compare/page 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2354)的**译文**;原文以源码为准。 `GET /download_queue/{id}/compare/page?side=a|b&index=N`——`.../compare` 自身响应中某个 `PageComparison` 样本背后的真实页面图片,供前端的叠加/位移切换对比视图使用。`side=a` 读取尚未入库的暂存下载(`temp_path`——此时还不存在档案 ID,所以无法复用 `archives.rs` 自己的 `GET /archives/{id}/page`);`side=b` 读取已有档案自己的文件。`index` 是自然排序下的页位置(与 `lanrurugi_imgcompare::PageComparison` 自己的 `a_page_index`/`b_page_index` 一致),每次调用都用 `list_pages` 现算成条目名,而不是缓存——这个端点每个冲突只会被访问寥寥几次(issue #77 自己确认的样本量为 3–5),为它加缓存不值得。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出一侧对比项的真实条目名列表(`GET /download_queue/{id}/compare/pages?side=a|b`) [Section titled “列出一侧对比项的真实条目名列表(GET /download_queue/{id}/compare/pages?side=a|b)”](#列出一侧对比项的真实条目名列表get-download_queueidcomparepagessideab) GEThttp\://localhost:3000/api/download_queue/{id}/compare/pages 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2482)的**译文**;原文以源码为准。 `GET /download_queue/{id}/compare/pages?side=a|b`——对比中某一侧的真实条目名列表,按自然排序(页)顺序给出。前端自己那个「选择把 A 侧未匹配页面插入到哪里」的界面(issue #77 自己的后续设计)需要 B 的真实条目名,以便在 `.../export-patch` 里作为 `after_filename`/`before_filename` 发送——它除此之外只处理数字页码(与 `PageComparison.a_page_index`/`b_page_index` 一致),而 `patch.rs` 自己的 JSON schema 刻意不使用页码(为什么以条目名而非可能因档案重新扫描而漂移的下标作为稳定锚点,见该模块的文档)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 对比队列项的 SSE 流式版本 [Section titled “对比队列项的 SSE 流式版本”](#对比队列项的-sse-流式版本) GEThttp\://localhost:3000/api/download_queue/{id}/compare/stream 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:1988)的**译文**;原文以源码为准。 `GET /download_queue/{id}/compare/stream`——上面 \[`compare_queue_item`] 的 SSE 流式孪生版本,依据 issue #77 自己确认的两阶段设计(完整的阶段一/阶段二拆分见 `lanrurugi_imgcompare::compare_archives_streaming` 自身的文档):开启一条 `EventSource` 兼容的流(用 GET 而非 POST——`EventSource` 无法发送请求体,也无法使用任何其他 HTTP 方法),每当出现一个 `CompareEvent::Sample` 就发出一个 `event: sample`(先粗后精,精确的替换样本随后陆续流入),最后发出一个终止性的 `event: done`,携带 `ComparisonResult` 其余字段——绝不把连接关闭/超时当作隐含的结束信号(「并且sse要有结束标记」)。前端在**第一个** `sample` 事件到达时就打开结果视图,而不是等整个对比完成;对于一对约 200 页的档案,否则会有好几秒的空白等待(「假设有6对结果(粗加工),可以用sse分6次发,发第一对的时候就开始显示modal,这样是一个很大的提速」)。 缓存命中(策略与 `compare_queue_item` 自己的相同)会以一批 `sample` 事件(全部是 `phase: coarse`——缓存结果已经过两个阶段,而前端只关心「这个值是否是最终展示值」,一旦值本身已定,`Coarse` 与 `Precise` 其实没有区别)一次性重放,紧接着发出 `done`,因此重新打开一个已算好的对比依然是瞬时完成的。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 确认保留较旧的版本(回答「是否用旧版本覆盖」这个提问) [Section titled “确认保留较旧的版本(回答「是否用旧版本覆盖」这个提问)”](#确认保留较旧的版本回答是否用旧版本覆盖这个提问) POSThttp\://localhost:3000/api/download_queue/{id}/confirm-older 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:707)的**译文**;原文以源码为准。 `POST /download_queue/{id}/confirm-older`——回答当一次下载被判定为比库中已有档案更*旧*的版本时弹出的那个 `AwaitingRevisionConfirmation` 提问(issue #107 的 `warn_then_conflict_menu`)。 `proceed: true` 会把该决定记录到该项上并重新启动它——由于此时 `revision_confirmed` 已置位,重启会直接穿过同一套版本历史检查,而不会再次停在那里。`proceed: false` 会把该项移到 `Cancelled`,那本来就是「用户主动停下的、仍可重启」的状态,因此不需要新的终态。 刻意与 `.../start` 分开:`AwaitingRevisionConfirmation` 不属于 `is_startable`,所以普通的启动按钮不会不小心跳过这个提问。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 「获取元数据」按钮的后端路径 [Section titled “「获取元数据」按钮的后端路径”](#获取元数据按钮的后端路径) POSThttp\://localhost:3000/api/download_queue/{id}/fetch-metadata 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:148)的**译文**;原文以源码为准。 `POST /download_queue/{id}/fetch-metadata`——「获取元数据」按钮的后端路径。它跑的是与下载后自动抓取相同的那套插件 `execMetadata` + `metadata_preview` 缓存逻辑(`plugins::ensure_metadata_cached`),因此手动预览与自动抓取共用同一条代码路径(以及同一个 10 分钟 TTL),而不必让前端自己去调用 `POST /plugins/use`。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 用新下载覆盖同名文件,从而解决 `PendingFilenameConflict` [Section titled “用新下载覆盖同名文件,从而解决 PendingFilenameConflict”](#用新下载覆盖同名文件从而解决-pendingfilenameconflict) POSThttp\://localhost:3000/api/download_queue/{id}/overwrite 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:1362)的**译文**;原文以源码为准。 `POST /download_queue/{id}/overwrite`——通过删除已有档案(B)并把暂存下载(A)以它原本预期的文件名入库来解决 `PendingFilenameConflict`。 给定 `body.insertions` 时,会把 B 自己独有的页面打包成 `.patch.zip` 交给*新的* A 档案(issue #77 自己的后续设计:即使 A 总体上胜出,B 的某些页面可能仍值得保留)——这必须在调用 `resolve_conflict` **之前**读取 B 的页面并解析 B 自己的分类/标签/进度元数据,因为那次调用在把 A 入库的过程中会删除 B 的文件与记录(`pipeline.rs::delete_existing_archive`)——之后再想读就没有东西可读了。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把冲突的文件重新命名并入库,从而解决 `PendingFilenameConflict` [Section titled “把冲突的文件重新命名并入库,从而解决 PendingFilenameConflict”](#把冲突的文件重新命名并入库从而解决-pendingfilenameconflict) POSThttp\://localhost:3000/api/download_queue/{id}/rename 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:1649)的**译文**;原文以源码为准。 `POST /download_queue/{id}/rename`——通过改为以 `body.filename` 把暂存下载入库来解决 `PendingFilenameConflict`,原文件名的持有者(已有档案)保持不变(成为一个全新的、独立并存的档案)。如果 `filename` 本身也与某个其他档案冲突,该项会得到一个*新的* `PendingFilenameConflict`(仍可解决,只是针对另一个已有档案/文件名),而不是丢掉已经下载好的字节——见 `ingest::resolve_rename` 自身的文档。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 启动一个队列项 [Section titled “启动一个队列项”](#启动一个队列项) POSThttp\://localhost:3000/api/download_queue/{id}/start 解析该项自己的下载插件(用的是它被加入时选定的那个,而不是现在重新选),标记为正在启动,并在后台发起真正的下载。随着传输推进,该项的 `state`、`job_id` 与 `error` 始终保持最新。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 停止进行中的队列项(`POST /download_queue/{id}/stop`,用于 `Starting`/`Downloading` 状态的项) [Section titled “停止进行中的队列项(POST /download_queue/{id}/stop,用于 Starting/Downloading 状态的项)”](#停止进行中的队列项post-download_queueidstop用于-startingdownloading-状态的项) POSThttp\://localhost:3000/api/download_queue/{id}/stop 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:1253)的**译文**;原文以源码为准。 `POST /download_queue/{id}/stop`——取消一个进行中(`Starting`/`Downloading`)的队列项的下载,并把它退回 `Queued` 以便重新启动。这是协作式而非强制式的:它只是给该项在 `AppState::download_cancellations` 里的令牌发个信号——后台任务自己会在下一次 `tokio::select!` 轮询时察觉(见 `download_manager::stream::download_one`),并在真正结束前自行清理不完整的文件,此时 `start_download` 会把队列项状态改回去(见那里 `cancel_for_task.is_cancelled()` 分支)。没有令牌意味着要么该项其实从未在下载(没什么可停的),要么它恰好在本次请求到达前自己完成了——两者都是 `NotRunning`,并不值得大声报错,因为无论哪种情况,期望的最终状态(「这一项没有在下载」)都已经成立。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清空已完成项(`POST /download_queue/clear_completed`,删除所有 `Done` 项并返回删除数量) [Section titled “清空已完成项(POST /download_queue/clear_completed,删除所有 Done 项并返回删除数量)”](#清空已完成项post-download_queueclear_completed删除所有-done-项并返回删除数量) POSThttp\://localhost:3000/api/download_queue/clear_completed 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:3098)的**译文**;原文以源码为准。 `POST /download_queue/clear_completed`——删除所有 `Done` 状态的项,返回删除数量。刻意排除 `Error`——与 `Done` 不同,出错的项是一个可重试、仍可操作的状态(在本模块其他地方都与 `Queued`/`Cancelled` 归为一类:可选中、有重试按钮、显示自己的错误文本),而不是用户已经看完不想再管的「已完成」工作。想丢弃某个具体失败项的用户,仍可通过 `DELETE /download_queue/{id}` 单独处理(那个端点确实会清理 `pending_filename_conflict` 自己暂存的临时文件——`Done` 项从不带这种文件,所以本 handler 没有同类东西需要操心)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除选中的队列项 [Section titled “删除选中的队列项”](#删除选中的队列项) POSThttp\://localhost:3000/api/download_queue/delete_selected 按 ID 批量删除,语义与 `start_selected` 对齐:不存在或已被删除的 ID 是**静默无操作**,不是错误,所以可以安全地传入一份过期的选择。 正在下载中的 ID 同样是静默无操作——这正是单项删除用 409 表达的同一套安全规则。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 启动全部排队项 [Section titled “启动全部排队项”](#启动全部排队项) POSThttp\://localhost:3000/api/download_queue/start_all 并发启动所有处于 `queued` 状态的项。每一项都会派生自己的后台任务;按域名限流与并发限制由下载管理器在下游统一执行,所以这里不再额外限速。 它的范围刻意比单项启动更窄:处于 `error` 或 `cancelled` 的项必须逐个重试,而正在等待版本冲突答复的项**绝不会**被顺带启动——批量启动它等于用沉默回答了它正卡着的那个问题。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 启动选中的队列项 [Section titled “启动选中的队列项”](#启动选中的队列项) POSThttp\://localhost:3000/api/download_queue/start_selected 与 `start_all` 相同,但只作用于给定的那些 ID。 已经进行中、已经完成、或以其他方式无法启动的 ID 是**静默无操作**,不是错误——这样客户端可以直接传入一份选择,而不必先逐个复查当前状态。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 推送下载队列项状态变化的 SSE 端点(`GET /download_queue/stream`) [Section titled “推送下载队列项状态变化的 SSE 端点(GET /download_queue/stream)”](#推送下载队列项状态变化的-sse-端点get-download_queuestream) GEThttp\://localhost:3000/api/download_queue/stream 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:75)的**译文**;原文以源码为准。 `GET /download_queue/stream`——SSE 端点,推送由 `update_queue_item_state` 在每次成功写入 Redis 后广播的队列项增量状态变化。第一个事件是 `full`,携带当前完整列表,使客户端无需另外发一次 HTTP GET 即可完成初始化。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 重复检测 > 3 endpoints. 3 endpoints. ## 清除重复项(`DELETE /database/duplicates`,对应 legacy 同一页面路由上的 `?delete=1` 参数) [Section titled “清除重复项(DELETE /database/duplicates,对应 legacy 同一页面路由上的 ?delete=1 参数)”](#清除重复项delete-databaseduplicates对应-legacy-同一页面路由上的-delete1-参数) DELETEhttp\://localhost:3000/api/database/duplicates 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/duplicates.rs:228)的**译文**;原文以源码为准。 `DELETE /database/duplicates`——对应 legacy 同一页面路由上的 `?delete=1` 参数。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取所有已存储的重复组,把 ID 解析成当前的档案元数据,并剔除已失效的条目 [Section titled “读取所有已存储的重复组,把 ID 解析成当前的档案元数据,并剔除已失效的条目”](#读取所有已存储的重复组把-id-解析成当前的档案元数据并剔除已失效的条目) GEThttp\://localhost:3000/api/database/duplicates 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/duplicates.rs:169)的**译文**;原文以源码为准。 读取所有已存储的重复组,把 ID 解析成当前的档案元数据,并剔除自扫描以来已消失(被删除)的条目——与 legacy 在 `Controller/Duplicates.pm::index` 中的自愈行为一致(若剔除后组成员少于 2 个就丢弃整组,否则只移除消失的 ID 并重写该组)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把重复扫描排入后台任务(对应 legacy 的 `/api/minion/find_duplicates/queue`) [Section titled “把重复扫描排入后台任务(对应 legacy 的 /api/minion/find_duplicates/queue)”](#把重复扫描排入后台任务对应-legacy-的-apiminionfind_duplicatesqueue) POSThttp\://localhost:3000/api/database/duplicates/scan 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/duplicates.rs:47)的**译文**;原文以源码为准。 把扫描排入后台任务(对应 legacy 的 `/api/minion/find_duplicates/queue` 是由 Minion 承载而非同步执行),因为对每一对档案做哈希是 O(n²),不该阻塞请求。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 字体模式 > 2 endpoints. 2 endpoints. ## 获取字体模式 [Section titled “获取字体模式”](#获取字体模式) GEThttp\://localhost:3000/api/volumes/{id}/font-pattern 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_font_pattern`,位于 crates/lanrurugi-api/src/font_pattern.rs:35。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重置字体模式 [Section titled “重置字体模式”](#重置字体模式) POSThttp\://localhost:3000/api/volumes/{id}/font-pattern/reset 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `reset_font_pattern`,位于 crates/lanrurugi-api/src/font_pattern.rs:52。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 健康检查 > 1 endpoint. 1 endpoint. ## 健康检查 [Section titled “健康检查”](#健康检查) GEThttp\://localhost:3000/health 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `health`,位于 crates/lanrurugi-api/src/health.rs:68。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 后台任务 > 3 endpoints. 3 endpoints. ## 清除全部已完成任务 [Section titled “清除全部已完成任务”](#清除全部已完成任务) DELETEhttp\://localhost:3000/api/jobs 移除已到达终止状态的任务——`finished` **或** `failed`。仍在进行中(`queued`、`active`)的任务保持被跟踪;等它们结束后再用单项端点处理。 只接受 `state=finished`。这个名字的含义是「任何处于终止状态的任务」,所以 `failed` 的也会被一并清掉。 #### 查询参数 * statestring · enum: finished必填 只接受 `finished`;缺失或传入其他值会返回 400。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• statequeryfinished 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出正在跟踪的后台任务 [Section titled “列出正在跟踪的后台任务”](#列出正在跟踪的后台任务) GEThttp\://localhost:3000/api/jobs 本实例正在跟踪的每一个任务,最新的在前。 进度与字节数是尽力而为的:无法报告细粒度进度的任务会直接从 0 跳到 1,而不是伪造一个中间值;对于没有传输可报告的任务,字节字段是真正的缺失(而不是 `0`)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清除单个任务 [Section titled “清除单个任务”](#清除单个任务) DELETEhttp\://localhost:3000/api/jobs/{id} 按 ID 清除单个任务,且只在该任务已到达终止状态后进行。 仍处于 `queued` 或 `active` 的任务会返回 409,而不是被悄悄杀掉——一个工作还在跑却报告成功的任务,比一个错误更糟。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # AI 用量 > 各项 AI 功能的请求次数、token 用量、耗时与失败统计。 各项 AI 功能的请求次数、token 用量、耗时与失败统计。 ## usage [Section titled “usage”](#usage) GEThttp\://localhost:3000/api/llm/usage 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `usage`,位于 crates/lanrurugi-api/src/llm_usage.rs:124。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 登录 > 4 endpoints. 4 endpoints. ## 登录 [Section titled “登录”](#登录) POSThttp\://localhost:3000/api/login 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `login`,位于 crates/lanrurugi-api/src/login.rs:236。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 查询调用者是否「已登录」(用于权限门控判断,`GET /login/status`) [Section titled “查询调用者是否「已登录」(用于权限门控判断,GET /login/status)”](#查询调用者是否已登录用于权限门控判断get-loginstatus) GEThttp\://localhost:3000/api/login/status 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/login.rs:669)的**译文**;原文以源码为准。 `GET /login/status`——报告调用者就「是否显示仅管理员可见的界面」这一判断而言是否「已登录」,与 legacy 自己的 `userlogged` 模板变量一致(`Controller/Reader.pm`/`Index.pm`:`enable_pass == 0 || session('is_logged')`)。刻意做成自己的端点,而不是在 `/info` 上加一个新字段——`/info` 逐字段镜像 legacy 的第三方 `ServerInfo` OpenAPI schema(宪法原则 II),而 `logged_in` 在那个契约里没有位置。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 登出(refresh token 现在是有状态的,所以登出会真正吊销它) [Section titled “登出(refresh token 现在是有状态的,所以登出会真正吊销它)”](#登出refresh-token-现在是有状态的所以登出会真正吊销它) POSThttp\://localhost:3000/api/logout 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/login.rs:751)的**译文**;原文以源码为准。 由于 refresh token 现在是有状态的(`lanrurugi_storage::refresh_tokens`),登出现在会真的吊销——烧掉调用者 access token 所源自的整个 refresh token 家族(与 `rotate` 自己那条重放检测路径采取的补救相同),而不是只清掉浏览器 cookie、然后指望那个已成孤儿的 access token 在接下来几小时里自己安静过期。 它从 *access* token 里读 `fid`(`session::COOKIE_NAME`,`Path=/`),而不是从 refresh cookie 读——这是刻意的,这样 `REFRESH_COOKIE_PATH` 就能继续只限定于 `POST /api/token/refresh`,不必再覆盖本端点。这里用的是 `family_id_ignoring_expiry` 而非平常那个会检查过期的验证器:用户在 access token 已经过期之后(闲置的标签页,还没碰到任何会触发静默刷新的端点)点击「登出」,他的 refresh token 家族仍然必须被真正吊销——一个已过期的 access token 仍能通过其签名证明来源真实,而这正是这里唯一需要的东西。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 刷新令牌(`POST /token/refresh`,legacy 没有对应端点) [Section titled “刷新令牌(POST /token/refresh,legacy 没有对应端点)”](#刷新令牌post-tokenrefreshlegacy-没有对应端点) POSThttp\://localhost:3000/api/token/refresh 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/login.rs:404)的**译文**;原文以源码为准。 `POST /token/refresh`——legacy 没有对应端点。用 refresh cookie 换取一个新的 access token + 轮换后的 refresh cookie(轮换/重放检测的语义见 `lanrurugi_storage::refresh_tokens::rotate` 自身的文档)。前端会在任何其他端点返回 401 时透明地调用它(`apps/frontend/src/api/client.ts`),且在此之前不会跳转到 `/login`。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 日志 > 1 endpoint. 1 endpoint. ## 获取日志行 [Section titled “获取日志行”](#获取日志行) GEThttp\://localhost:3000/api/logs/{category} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_log_lines`,位于 crates/lanrurugi-api/src/logs.rs:26。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # Minion API > 3 endpoints. 3 endpoints. ## 获取 Minion 任务的基本状态 [Section titled “获取 Minion 任务的基本状态”](#获取-minion-任务的基本状态) GEThttp\://localhost:3000/api/minion/{jobid} 给定 Minion 任务 ID,检查它是成功还是失败。\ Minion 任务用于缩略图、缓存预热、处理新进来的文件等各种场合。\ 对部分任务,你可以查看 notes 字段获取进度信息。详见 。 #### 路径参数 * jobidinteger必填 要查询状态的任务 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• jobidpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取 Minion 任务的完整状态 [Section titled “获取 Minion 任务的完整状态”](#获取-minion-任务的完整状态) GEThttp\://localhost:3000/api/minion/{jobid}/detail 获取一个 Minion 任务的状态。\ 这个 API 主要供内部使用,但你可以用它来获取插件执行、URL 下载这类任务的详细状态。 #### 路径参数 * jobidinteger必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• jobidpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 排入一个 Minion 任务 [Section titled “排入一个 Minion 任务”](#排入一个-minion-任务) POSThttp\://localhost:3000/api/minion/{jobname}/queue 按指定的类型和参数排入一个任务。\ 可用的任务类型及各自所需参数见 LANraragi::Utils::Minion 。 对于某个任务类型在给定服务端版本上是否存在,并没有 API 契约,所以除非你有充分理由,否则不建议使用它。 #### 路径参数 * jobnamestring · enum: thumbnail_task | tank_thumbnail_task | page_thumbnails | regen_all_thumbnails | find_duplicates | build_stat_hashes | handle_upload | download_url | run_plugin必填 要实例化的任务类型。 #### 查询参数 * argsstring必填 参数,以 JSON 数组字符串给出 * priorityinteger · default: 0可选 Minion 任务的优先级。数字越大越优先。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• jobnamepaththumbnail_taskargsquerypriorityquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 其他 API > 5 endpoints. 5 endpoints. ## 把 URL 排入下载队列 [Section titled “把 URL 排入下载队列”](#把-url-排入下载队列) POSThttp\://localhost:3000/api/download_url 添加一个 URL,交由服务端下载并加入其书库。 #### 查询参数 * urlstring可选 要下载的 URL * catidstring · min: 14 · max: 14 · pattern可选 把下载到的 URL 加入的分类 ID。 #### 请求体 multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• urlquerycatidquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取服务端信息 [Section titled “获取服务端信息”](#获取服务端信息) GEThttp\://localhost:3000/api/info 返回这个服务端所运行的 LRR 实例的一些基本信息。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 查询是否已配置 LLM 密钥(`GET /api/llm/key-status`,返回 `{ configured: true/false }`) [Section titled “查询是否已配置 LLM 密钥(GET /api/llm/key-status,返回 { configured: true/false })”](#查询是否已配置-llm-密钥get-apillmkey-status返回--configured-truefalse-) GEThttp\://localhost:3000/api/llm/key-status 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/misc.rs:118)的**译文**;原文以源码为准。 `GET /api/llm/key-status`——返回 `{ configured: true/false }`。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重新生成缩略图 [Section titled “重新生成缩略图”](#重新生成缩略图) POSThttp\://localhost:3000/api/regen_thumbs 排入一个 Minion 任务,在服务端重新生成缺失的/全部的缩略图。 #### 查询参数 * forceboolean可选 是生成全部缩略图,还是只生成缺失的那些。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• forcequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 清理临时目录 [Section titled “清理临时目录”](#清理临时目录) DELETEhttp\://localhost:3000/api/tempfolder 清理服务端的临时目录。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # OPDS 目录 > 3 endpoints. 3 endpoints. ## 获取 OPDS 目录 [Section titled “获取 OPDS 目录”](#获取-opds-目录) GEThttp\://localhost:3000/api/opds 以兼容 PSE 1.1 的 OPDS 1.2 目录形式获取档案索引。 #### 查询参数 * categorystring可选 分类 ID。传入后,OPDS 目录会被过滤为只显示该分类下的档案。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• categoryquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 通过 OPDS 获取指定档案 [Section titled “通过 OPDS 获取指定档案”](#通过-opds-获取指定档案) GEThttp\://localhost:3000/api/opds/{id} 以 XML 返回某个特定的 OPDS 条目。结果中只会为该 ID 显示一个 ``,而不是全部档案。 #### 路径参数 * idstring必填 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## OPDS-PSE 分页图片 [Section titled “OPDS-PSE 分页图片”](#opds-pse-分页图片) GEThttp\://localhost:3000/api/opds/{id}/pse 以 XML 返回 OPDS-PSE 的某个具体图片页。 #### 路径参数 * idstring必填 #### 查询参数 * pageinteger可选 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # OpenSearch > 1 endpoint. 1 endpoint. ## OpenSearch 描述文档 [Section titled “OpenSearch 描述文档”](#opensearch-描述文档) GEThttp\://localhost:3000/opensearch.xml 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `opensearch_xml`,位于 crates/lanrurugi-api/src/opensearch.rs:74。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 插件向导 > 7 endpoints. 7 endpoints. ## 分析登录 [Section titled “分析登录”](#分析登录) POSThttp\://localhost:3000/api/plugin-wizard/analyze-login 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `analyze_login`,位于 crates/lanrurugi-api/src/plugin_wizard/analyze_login.rs:55。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## `GET /plugin-wizard/generate/{id}/record` — the whole read surface; no UI [Section titled “GET /plugin-wizard/generate/{id}/record — the whole read surface; no UI”](#get-plugin-wizardgenerateidrecord--the-whole-read-surface-no-ui) GEThttp\://localhost:3000/api/plugin-wizard/generate/{id}/record 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugin_wizard/record.rs:118),**逐字引用、未翻译**——它是写给本代码库维护者看的,可能会提到内部标识符。 `GET /plugin-wizard/generate/{id}/record` — the whole read surface; no UI. #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 启动插件生成(`POST /plugin-wizard/generate/start`,为何这样设计见该模块自身的顶部文档) [Section titled “启动插件生成(POST /plugin-wizard/generate/start,为何这样设计见该模块自身的顶部文档)”](#启动插件生成post-plugin-wizardgeneratestart为何这样设计见该模块自身的顶部文档) POSThttp\://localhost:3000/api/plugin-wizard/generate/start 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugin_wizard/generate.rs:193)的**译文**;原文以源码为准。 `POST /plugin-wizard/generate/start`——为什么生成被拆成这里加 `generate_stream`、而不是一个返回 JSON 的 `POST`,见本模块自身的顶部文档。它把请求体当作原始的 \[`serde_json::Value`] 接收(而不是带类型的 `GenerateRequest`),正是为了让本端点永远不必重复实现 `GenerateRequest` 自己的字段/默认值处理——真正带类型的解析只在 `generate_stream` 时发生一次,针对的是这里原样暂存下来的内容。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 插件生成的 `EventSource` 兼容流式端点(`GET /plugin-wizard/generate/stream/{id}`) [Section titled “插件生成的 EventSource 兼容流式端点(GET /plugin-wizard/generate/stream/{id})”](#插件生成的-eventsource-兼容流式端点get-plugin-wizardgeneratestreamid) GEThttp\://localhost:3000/api/plugin-wizard/generate/stream/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugin_wizard/generate.rs:211)的**译文**;原文以源码为准。 `GET /plugin-wizard/generate/stream/{id}`——真正 `EventSource` 兼容的流式端点;完整的事件序列见本模块自身的顶部文档。`id` 是一次性的(本方法被调用的那一刻就从 `pending_generate_requests` 中移除),因此重放同一个 id(一个过期的书签、一次双击竞态)总会得到 `generation_not_found`,而不会静默重跑一个旧请求。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 查询 [Section titled “查询”](#查询) POSThttp\://localhost:3000/api/plugin-wizard/lookup 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `lookup`,位于 crates/lanrurugi-api/src/plugin_wizard/mod.rs:22。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 保存 [Section titled “保存”](#保存) POSThttp\://localhost:3000/api/plugin-wizard/save 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `save`,位于 crates/lanrurugi-api/src/plugin_wizard/save.rs:71。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 试运行 [Section titled “试运行”](#试运行) POSThttp\://localhost:3000/api/plugin-wizard/trial-run 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `trial_run`,位于 crates/lanrurugi-api/src/plugin_wizard/trial_run.rs:148。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 插件 API > 12 endpoints. 12 endpoints. ## 列出可用插件 [Section titled “列出可用插件”](#列出可用插件) GEThttp\://localhost:3000/api/plugins/{type} 列出给定类型的全部插件。 #### 路径参数 * typestring · enum: download | login | metadata | script | all必填 要列出的插件类型。传 "all" 可以一次取回所有类型。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• typepathdownload 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 导出插件(`GET /plugins/export?namespace=...`,见 `specs/006-ai-plugin-wizard` FR-028) [Section titled “导出插件(GET /plugins/export?namespace=...,见 specs/006-ai-plugin-wizard FR-028)”](#导出插件get-pluginsexportnamespace见-specs006-ai-plugin-wizard-fr-028) GEThttp\://localhost:3000/api/plugins/export 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugins.rs:1038)的**译文**;原文以源码为准。 `GET /plugins/export?namespace=...`(`specs/006-ai-plugin-wizard` FR-028)——把一个已安装的插件(无论是否由向导创建)下载为包含它自己 `.ts` 文件的 `.zip`,文件以该命名空间自身最后一段路径命名(例如 `custom/metadata/foo` → 内含 `foo.ts` 的 `foo.zip`),而不是用完整命名空间,因为命名空间那个以 `/` 分隔的类别前缀在单独解压出来后没有意义。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 批量导出插件(`POST /plugins/export-batch`,与单个导出相同,但一次处理多个命名空间) [Section titled “批量导出插件(POST /plugins/export-batch,与单个导出相同,但一次处理多个命名空间)”](#批量导出插件post-pluginsexport-batch与单个导出相同但一次处理多个命名空间) POSThttp\://localhost:3000/api/plugins/export-batch 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugins.rs:1109)的**译文**;原文以源码为准。 `POST /plugins/export-batch`——与 \[`export_plugin`] 类似,但一次处理多个命名空间,打包进一个 `.zip`。每个条目以其完整命名空间路径存放(`custom/download/foo.ts`,而不只是 `foo.ts`),因为两个不同的命名空间可以共用同一个文件主名(`custom/download/foo` 与 `custom/metadata/foo`)——把两者都压成 `foo.ts` 会在写 zip 时静默丢掉其中一个。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除插件选项 [Section titled “删除插件选项”](#删除插件选项) DELETEhttp\://localhost:3000/api/plugins/options 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `delete_plugin_options`,位于 crates/lanrurugi-api/src/plugins.rs:931。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取插件选项 [Section titled “获取插件选项”](#获取插件选项) GEThttp\://localhost:3000/api/plugins/options 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_plugin_options`,位于 crates/lanrurugi-api/src/plugins.rs:785。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 写入插件选项 [Section titled “写入插件选项”](#写入插件选项) PUThttp\://localhost:3000/api/plugins/options 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `put_plugin_options`,位于 crates/lanrurugi-api/src/plugins.rs:854。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 持久化某个插件 `type` 分组内拖拽排序后的显示顺序(`PUT /plugins/priority`) [Section titled “持久化某个插件 type 分组内拖拽排序后的显示顺序(PUT /plugins/priority)”](#持久化某个插件-type-分组内拖拽排序后的显示顺序put-pluginspriority) POSThttp\://localhost:3000/api/plugins/priority 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugins.rs:567)的**译文**;原文以源码为准。 `PUT /plugins/priority`——持久化某个插件 `type` 分组内拖拽排序后的显示顺序(新增端点,legacy 没有对应功能:legacy 的 `plugins.html.tt2` 完全没有这种交互)。它把 `order` 中列出的每个命名空间在其自己的 `LRR_PLUGIN_` 哈希(与 `customargs`/`enabled` 同一处存储)里的 `priority` 字段重写为其在 `order` 中的位置,使后续的 `GET /plugins/{type}` 按此排序。实际类型与 `body.type` 不符的命名空间会被跳过(不写入,也不让整个请求报错)——为什么会有这个检查,见 `PutPluginPriorityBody::kind` 自身的文档。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 异步执行插件 [Section titled “异步执行插件”](#异步执行插件) POSThttp\://localhost:3000/api/plugins/queue 执行一个插件并返回与本次执行对应的 Minion 任务 ID。若你想执行耗时较长、用标准端点可能会超时的插件,这个端点很有用。 #### 查询参数 * idstring · min: 40 · max: 40 · pattern可选 要在其上执行插件的档案 ID。只有元数据插件才必须提供。 * priorityinteger · default: 0可选 Minion 任务的优先级。数字越大越优先。 * pluginstring可选 要使用的插件命名空间。 * argstring可选 执行该插件时可选的 One-Shot 参数。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idquerypriorityquerypluginqueryargquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取插件当前持久化的 `customargs`(`GET /plugins/settings?namespace=...`,按定义补齐/截断) [Section titled “读取插件当前持久化的 customargs(GET /plugins/settings?namespace=...,按定义补齐/截断)”](#读取插件当前持久化的-customargsget-pluginssettingsnamespace按定义补齐截断) GEThttp\://localhost:3000/api/plugins/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/plugins.rs:461)的**译文**;原文以源码为准。 `GET /plugins/settings?namespace=...`——插件当前持久化的 `customargs`(会被补齐/截断到它自己声明的 `parameters.len()` 恰好长度——一个比插件当前声明更长或更短的过期已保存数组,例如插件升级增删过参数之后,会被静默调整到当前形状,而不是作为不匹配暴露出来,与 legacy 在 `get_plugin_parameters` 里「先填默认值再覆盖」的行为一致)以及 `enabled`(legacy 的「自动运行」开关——`is_plugin_enabled`,从未设置时为 `false`,与 legacy 自己那个以 `hexists` 为条件的默认值相同)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 写入插件设置 [Section titled “写入插件设置”](#写入插件设置) PUThttp\://localhost:3000/api/plugins/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `put_plugin_settings`,位于 crates/lanrurugi-api/src/plugins.rs:497。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 上传插件 [Section titled “上传插件”](#上传插件) POSThttp\://localhost:3000/api/plugins/upload 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `upload_plugin`,位于 crates/lanrurugi-api/src/plugins.rs:3924。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 执行插件 [Section titled “执行插件”](#执行插件) POSThttp\://localhost:3000/api/plugins/use 执行一个插件并返回结果。 如果用的是元数据插件,匹配到的档案不会在数据库中被修改。插件的更多说明见文档中对应的章节。 #### 查询参数 * idstring · min: 40 · max: 40 · pattern可选 要在其上执行插件的档案 ID。只有元数据插件才必须提供。 * pluginstring可选 要使用的插件命名空间。 * argstring可选 执行该插件时可选的 One-Shot 参数。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idquerypluginqueryargquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 偏好设置 > 2 endpoints. 2 endpoints. ## 读取调用者自己的偏好设置 [Section titled “读取调用者自己的偏好设置”](#读取调用者自己的偏好设置) GEThttp\://localhost:3000/api/preferences 调用者自己的书库视图偏好;任何从未设置过的值都会回落到默认值。未认证的调用者拿到的是默认值——不是别人的设置。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新调用者自己的偏好设置 [Section titled “更新调用者自己的偏好设置”](#更新调用者自己的偏好设置) PUThttp\://localhost:3000/api/preferences 保存调用者的书库视图偏好。请求中省略的字段保持原样。需要已认证的调用者;未认证的调用会被拒绝,而不是悄悄写进一个共享的存储桶。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 推荐 > 1 endpoint. 1 endpoint. ## 获取推荐 [Section titled “获取推荐”](#获取推荐) GEThttp\://localhost:3000/api/reader/recommendations/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_recommendations`,位于 crates/lanrurugi-api/src/recommend.rs:438。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 维护脚本 > 3 endpoints. 3 endpoints. ## 修复乱码元数据(`POST /database/scripts/repair-mojibake`) [Section titled “修复乱码元数据(POST /database/scripts/repair-mojibake)”](#修复乱码元数据post-databasescriptsrepair-mojibake) POSThttp\://localhost:3000/api/database/scripts/repair-mojibake 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/scripts.rs:61)的**译文**;原文以源码为准。 `POST /database/scripts/repair-mojibake`——为什么在导入器早已学会修复之后,已存储的记录里仍可能存在双重编码的文本,见 `crate::mojibake` 自身的文档。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 按子目录批量建分类(`POST /database/scripts/subfolders-to-categories`,扫描档案目录并为每个子目录建一个分类) [Section titled “按子目录批量建分类(POST /database/scripts/subfolders-to-categories,扫描档案目录并为每个子目录建一个分类)”](#按子目录批量建分类post-databasescriptssubfolders-to-categories扫描档案目录并为每个子目录建一个分类) POSThttp\://localhost:3000/api/database/scripts/subfolders-to-categories 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/scripts.rs:182)的**译文**;原文以源码为准。 `POST /database/scripts/subfolders-to-categories`——扫描档案目录,并为每个直接包含档案的子目录创建一个静态分类(`FolderToCat.pm::run_script`)。 响应里会报告它自己的墙上时钟耗时 `elapsed_ms`(从遍历目录到创建分类,含两端),以便与 `plugins/script/foldertocat.ts` 直接对比——那是一个真实的 `.ts` 脚本插件,自己完成完全相同的目录遍历与分组逻辑(用 `Deno.readDir`,而不是由宿主注入路径——用户要的是真正的正面对比,而不是让插件拿着别人遍历好的数据这种人为构造的场景),用来衡量把这类 I/O 密集的整库扫描放进 Deno 子进程插件沙箱、相对原生 Rust 究竟有多少真实开销。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 按子目录批量建 Tankoubon(`POST /database/scripts/subfolders-to-tankoubons`,只扫描**第一层子目录**) [Section titled “按子目录批量建 Tankoubon(POST /database/scripts/subfolders-to-tankoubons,只扫描第一层子目录)”](#按子目录批量建-tankoubonpost-databasescriptssubfolders-to-tankoubons只扫描第一层子目录) POSThttp\://localhost:3000/api/database/scripts/subfolders-to-tankoubons 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/scripts.rs:494)的**译文**;原文以源码为准。 `POST /database/scripts/subfolders-to-tankoubons`——只扫描档案目录的**第一层子目录**,并为每个这样的子目录创建一个 Tankoubon。该第一层子目录下的所有档案(包括更深层嵌套子目录里的)都会被加入同一个 Tankoubon;嵌套子目录不会创建自己的 Tankoubon。允许重名;这是非破坏性操作,绝不会删除或去重已有的 Tankoubon。 配置了 DeepSeek API 密钥时,该端点会尽力用 LLM 推断一个更好的 Tankoubon 名称以及一个 `artist:`/`circle:` 作者标签。没有密钥、或 LLM 调用失败时,它会回退到原始目录名并跳过作者标签。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 搜索 API > 对档案索引执行搜索。 对档案索引执行搜索。 ## 搜索档案 [Section titled “搜索档案”](#搜索档案) GEThttp\://localhost:3000/api/search 搜索档案。这个 JSON 里的 ID 可以用在其他端点上。 权限差异 * 访客(开启访客访问时的未认证访问者)只能看到所属分类被标记为「访客可见」的档案;其他身份能看到整个书库。 #### 查询参数 * categorystring · min: 14 · max: 14 · pattern可选 限定本次搜索范围的分类 ID。 * filterstring可选 搜索查询串。可以在这当中使用下列特殊字符: **双引号 ("...")** 精确字符串搜索。让一个搜索词可以包含空格;一对双引号内的所有内容会被当成单个词条处理。通配符仍然按通配符解释。 **问号 (?)、下划线 (\_)** 通配符,匹配任意单个字符。 **星号 (\*)、百分号 (%)** 通配符,匹配任意长度的字符序列(也可以一个都不匹配)。 **减号 (-)** 排除。放在某个词前面,搜索结果就不会包含该词。 **美元符号 ($)** 加在标签末尾,对该标签做精确搜索,而不是显示所有以该词开头的结果。它只匹配标签,不受搜索参数影响,因此也可以当作排除项,用来在搜索里忽略杂项标签。 * startinteger可选 从结果总数中的第几个档案开始枚举。单页显示的档案数取决于服务端的每页条数偏好。 从 0.8.2 起,这里传 "-1" 可以取到完整的、不分页的数据。 * sortbystring可选 结果排序所依据的命名空间。可用的排序键有: - \*title\*:按标题排序 - \*lastread\*:按上次阅读时间排序(需开启 **服务端进度跟踪** ) (默认值是 title。按 lastread 排序时,从未读过的 ID 会被从搜索结果里移除。) * orderstring可选 排序方向,`asc` 或 `desc`。 * newonlyboolean可选 只搜索未读过的档案。 * untaggedonlyboolean可选 只搜索未打标签的档案。 * hidecompletedboolean可选 隐藏已读到末尾的档案。 * groupby_tanksboolean · default: true可选 启用或关闭 Tankoubon 分组,默认开启。 开启时,搜索结果里会显示 Tankoubon,取代它包含的所有档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• categoryqueryfilterquerystartquerysortbyqueryorderquerynewonlyqueryuntaggedonlyqueryhidecompletedquerygroupby_tanksquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 原始档案搜索端点(`GET /search/archives`),共用 `/search` 的查询参数,但不会把成员档案折叠进 Tankoubon [Section titled “原始档案搜索端点(GET /search/archives),共用 /search 的查询参数,但不会把成员档案折叠进 Tankoubon”](#原始档案搜索端点get-searcharchives共用-search-的查询参数但不会把成员档案折叠进-tankoubon) GEThttp\://localhost:3000/api/search/archives 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/search.rs:435)的**译文**;原文以源码为准。 新增的原始档案搜索端点(`GET /search/archives`),共用 `/search` 的查询语法、筛选、排序与分页,但绝不把成员档案折叠到 Tankoubon 之后。它刻意是一个独立端点,而不是 `/search` 上的一个新默认行为:既有的分组搜索调用方保持完全一致的行为,而重复项/库成员检查则可以索取底层的档案记录,而不是一个 `TANK_` 聚合体。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 丢弃搜索缓存 [Section titled “丢弃搜索缓存”](#丢弃搜索缓存) DELETEhttp\://localhost:3000/api/search/cache 丢弃存放用户历史搜索的缓存。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Forget one entry [Section titled “Forget one entry”](#forget-one-entry) DELETEhttp\://localhost:3000/api/search/history What the search panel’s `Delete` key calls on a highlighted history row. Removes every occurrence, so a hand-edited list cannot leave a row the reader cannot dismiss. #### 查询参数 * filterstring必填 The exact history entry to forget. #### 响应 服务器地址http\://localhost:3000API 令牌••••• filterquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## The account’s recent searches [Section titled “The account’s recent searches”](#the-accounts-recent-searches) GEThttp\://localhost:3000/api/search/history Newest first, at most 8 entries (the cap the browser-side version kept). With `filter`, only the entries related to it, judged with the engine’s own folding, so `くろ` still offers a stored `クロガネ`; without it, the whole history. A caller with no account (e.g. a read-only token) gets an empty list; guests are denied by the route policy. #### 查询参数 * filterstring可选 What the reader is typing; limits the answer to the related entries. #### 响应 服务器地址http\://localhost:3000API 令牌••••• filterquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Remember one applied filter [Section titled “Remember one applied filter”](#remember-one-applied-filter) POSThttp\://localhost:3000/api/search/history Moves the entry to the front, removing any previous occurrence and trimming to the cap, in one atomic pipeline. Called only for a genuinely applied filter. #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 搜索档案 ID [Section titled “搜索档案 ID”](#搜索档案-id) GEThttp\://localhost:3000/api/search/ids 与 `/api/search` 一样搜索档案,但只返回匹配档案 ID 的有序列表,不带随附的元数据。 权限差异 * 作用域与 `/api/search` 相同:访客只会拿到访客可见档案的 ID。 #### 查询参数 * categorystring · min: 14 · max: 14 · pattern可选 限定本次搜索范围的分类 ID。 * filterstring可选 搜索查询串,规则与 `/api/search` 相同。 * startinteger可选 从结果总数中的第几个档案开始枚举。单页显示的档案数取决于服务端的每页条数偏好。 从 0.8.2 起,这里传 "-1" 可以取到完整的、不分页的 ID 列表。 * sortbystring可选 结果排序所依据的命名空间。可用的排序键有: - \*title\*:按标题排序 - \*lastread\*:按上次阅读时间排序(需开启 **服务端进度跟踪** ) (默认值是 title。按 lastread 排序时,从未读过的 ID 会被从搜索结果里移除。) * orderstring可选 排序方向,`asc` 或 `desc`。 * newonlyboolean可选 只搜索未读过的档案。 * untaggedonlyboolean可选 只搜索未打标签的档案。 * hidecompletedboolean可选 隐藏已读到末尾的档案。 * groupby_tanksboolean · default: true可选 启用或关闭 Tankoubon 分组,默认开启。 开启时,搜索结果里会显示 Tankoubon,取代它包含的所有档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• categoryqueryfilterquerystartquerysortbyqueryorderquerynewonlyqueryuntaggedonlyqueryhidecompletedquerygroupby_tanksquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 随机搜索档案 [Section titled “随机搜索档案”](#随机搜索档案) GEThttp\://localhost:3000/api/search/random 按给定的筛选条件和/或分类,随机取出一批档案。 权限差异 * 作用域与 `/api/search` 相同:访客只会在访客可见的档案中随机抽取。 #### 查询参数 * categorystring · min: 14 · max: 14 · pattern可选 限定本次搜索范围的分类 ID。 * filterstring可选 搜索查询串,规则与 `/api/search` 相同。 * countinteger · default: 5可选 要随机取多少个档案,默认 5。 如果搜索结果的条数不够你要的数量,就返回全部搜索结果打乱后的结果。 * newonlyboolean可选 只搜索未读过的档案。 * untaggedonlyboolean可选 只搜索未打标签的档案。 * hidecompletedboolean可选 隐藏已读到末尾的档案。 * groupby_tanksboolean · default: true可选 启用或关闭 Tankoubon 分组,默认开启。 开启时,搜索结果里会显示 Tankoubon,取代它包含的所有档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• categoryqueryfilterquerycountquerynewonlyqueryuntaggedonlyqueryhidecompletedquerygroupby_tanksquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 为书库搜索框的标题自动补全提供数据的轻量端点 [Section titled “为书库搜索框的标题自动补全提供数据的轻量端点”](#为书库搜索框的标题自动补全提供数据的轻量端点) GEThttp\://localhost:3000/api/search/suggest 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/search.rs:603)的**译文**;原文以源码为准。 新增的轻量端点,为书库搜索框的标题自动补全提供数据。与 `/search` 不同,它只返回前几个匹配项中的 `arcid` + `title`——没有标签、进度或体积——因为前端每敲一次键(已做防抖)就会调用它,而一次返回 100 条档案记录的完整 `/search` 页会有几百 KB 的 JSON,建议列表拿到后立刻就丢掉了。查询语法相同、筛选相同、默认的 `title` 排序也相同(这正是建议列表想要的),并且访客范围限制也相同:这里同样应用 `restrict_to_archive_ids`,因此 `guest_visitor` 绝不可能通过这个端点看到一个 `/search` 会拒绝返回的越界标题。 权限差异 * 作用域与 `/api/search` 相同,因此访客不可能看到 `/api/search` 会拒绝返回的档案标题。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 登录设备 > 3 endpoints. 3 endpoints. ## 列出已登录设备 [Section titled “列出已登录设备”](#列出已登录设备) GEThttp\://localhost:3000/api/sessions 每一个活跃的 refresh token 家族——也就是每一台当前已登录的设备——包括发出本次请求的这一台,它会被标记出来,以免客户端不小心提出吊销自己。 需要会话 cookie 登录。任何角色的 API 令牌都会被拒绝。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 吊销一台已登录设备 [Section titled “吊销一台已登录设备”](#吊销一台已登录设备) DELETEhttp\://localhost:3000/api/sessions/{family_id} 通过吊销某个会话的整个 refresh token 家族来结束它,该设备必须重新登录。需要会话 cookie 登录。 #### 路径参数 * family_idstring必填 #### 响应 服务器地址http\://localhost:3000 family_idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重命名一台已登录设备 [Section titled “重命名一台已登录设备”](#重命名一台已登录设备) PATCHhttp\://localhost:3000/api/sessions/{family_id} 为某个会话设置自定义显示名,这样设备列表读起来是「客厅平板」而不是一串 user-agent。需要会话 cookie 登录。 #### 路径参数 * family_idstring必填 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000 family_idpath 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 设置 > 4 endpoints. 4 endpoints. ## 获取设置 [Section titled “获取设置”](#获取设置) GEThttp\://localhost:3000/api/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_settings`,位于 crates/lanrurugi-api/src/settings.rs:628。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 写入设置 [Section titled “写入设置”](#写入设置) PUThttp\://localhost:3000/api/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `put_settings`,位于 crates/lanrurugi-api/src/settings.rs:755。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 设置新的管理员密码,哈希方式与 legacy 存密码的方式一致(`{CRYPT}$2a$...`) [Section titled “设置新的管理员密码,哈希方式与 legacy 存密码的方式一致({CRYPT}$2a$...)”](#设置新的管理员密码哈希方式与-legacy-存密码的方式一致crypt2a) POSThttp\://localhost:3000/api/settings/password 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/settings.rs:1021)的**译文**;原文以源码为准。 设置新的管理员密码,哈希方式与 legacy 存密码的方式一致(`{CRYPT}$2a$...`——见 `lanrurugi_core::password`),这样共用同一 Redis 的 legacy 实例也仍然接受它。空字符串会清除密码保护的实际效果,但方式与 legacy 配置页「留空则保持当前密码」的约定*不同*——这个端点总是设置提交上来的内容,因此除非用户确实想设一个空密码,前端绝不能提交空字段。 #### 响应 服务器地址http\://localhost:3000 该端点**只接受网页会话**(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读取主题(issue #92:这个响应现在还带着 `language`,不只是 `theme`) [Section titled “读取主题(issue #92:这个响应现在还带着 language,不只是 theme)”](#读取主题issue-92这个响应现在还带着-language不只是-theme) GEThttp\://localhost:3000/api/theme 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/settings.rs:160)的**译文**;原文以源码为准。 issue #92:这个响应现在还带着 `language`,不只是 `theme`——`useApplyTheme`/`useApplySettingsLanguage`(`apps/frontend/src/theme.ts`/`i18n/index.ts`)过去都从完整的、需要鉴权的 `GET /settings` 里读取各自那个字段(该响应还带着 API 密钥和其他确实属于机密的字段,无法公开,因此登录前会 401)——每个在会话存在之前渲染的页面(登录页自己那套特制的 `usePublicTheme` 回退除外)都撞上那个 401,而 `client.ts` 里那个*全局* 401 处理器在每一次上都强制跳转到 `/login`,不管发起调用的 hook 自己是否已经准备好了回退值,从而使 issue #92 自己「留在当前页、不要跳转」的要求对任何在登出状态下渲染的内容都失效(新加的 404 页面尤其如此——实测报告了一次真实的双重跳转:先闪一下 404 内容,然后还是去了 `/login`)。`theme`/`language` 是会话存在之前唯一需要的两个字段,而且两者都完全不机密,所以把 `language` 折进这个已经公开的端点,比为多一个字段再撑起一整套公开设置接口要简单。响应里还带着 `admin_theme`——始终是管理员自己的 `theme`,与访客资格无关——这样即使开启了访客模式、且访客主题是另一套,登录页也能用管理员的主题渲染。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # Shinobu API > 4 endpoints. 4 endpoints. ## 获取 Shinobu 状态 [Section titled “获取 Shinobu 状态”](#获取-shinobu-状态) GEThttp\://localhost:3000/api/shinobu 获取 FileWatcher 的当前状态。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重新扫描 filemap 并重启 Shinobu [Section titled “重新扫描 filemap 并重启 Shinobu”](#重新扫描-filemap-并重启-shinobu) POSThttp\://localhost:3000/api/shinobu/rescan 这会删除系统上已扫描文件的内部映射(即「filemap」)并重启 Shinobu,相当于触发一次对文件系统的完整重新扫描。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 重启 Shinobu [Section titled “重启 Shinobu”](#重启-shinobu) POSThttp\://localhost:3000/api/shinobu/restart 重启 Shinobu 文件监视器 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 停止 Shinobu [Section titled “停止 Shinobu”](#停止-shinobu) POSThttp\://localhost:3000/api/shinobu/stop 停止文件监视器。用 `/api/shinobu/restart` 再次启动它。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 图章 API > 8 endpoints. 8 endpoints. ## 获取该档案中至少含有一个图章的页面 [Section titled “获取该档案中至少含有一个图章的页面”](#获取该档案中至少含有一个图章的页面) GEThttp\://localhost:3000/api/archives/{id}/stamps 获取该档案中至少含有一个图章的页面。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring必填 档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取链接到该页面的图章 [Section titled “获取链接到该页面的图章”](#获取链接到该页面的图章) GEThttp\://localhost:3000/api/archives/{id}/stamps/{index} 获取链接到该页面的图章。 权限差异 * 对**不在访客可见范围内**的档案,这里返回 **404** 而不是 403——刻意与「档案不存在」不可区分,因此这个响应无法被用来探测访客范围之外的档案是否存在。 #### 路径参数 * idstring必填 档案 ID。 * indexinteger必填 档案的页码。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathindexpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 添加图章标注 [Section titled “添加图章标注”](#添加图章标注) PUThttp\://localhost:3000/api/archives/{id}/stamps/{index} 在给定坐标处向该页面添加一个新图章。 #### 路径参数 * idstring必填 档案 ID。 * indexinteger必填 档案的页码。 #### 查询参数 * contentstring可选 图章文本。 * positionstring可选 图章在页面中的位置。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathindexpathcontentquerypositionquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除图章 [Section titled “删除图章”](#删除图章) DELETEhttp\://localhost:3000/api/stamps/{id} 从某个档案中移除一个图章。 #### 路径参数 * idstring必填 图章 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取图章 [Section titled “获取图章”](#获取图章) GEThttp\://localhost:3000/api/stamps/{id} 从某个档案获取一个图章。 #### 路径参数 * idstring必填 图章 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新图章 [Section titled “更新图章”](#更新图章) PUThttp\://localhost:3000/api/stamps/{id} 更新某个档案中的一个图章。 #### 路径参数 * idstring必填 图章 ID。 #### 查询参数 * contentstring可选 图章文本。 * positionstring可选 图章在页面中的位置。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathcontentquerypositionquery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取 Tankoubon 中某页的图章 [Section titled “获取 Tankoubon 中某页的图章”](#获取-tankoubon-中某页的图章) GEThttp\://localhost:3000/api/tankoubons/{id}/stamps/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `tank_stamps_by_page`,位于 crates/lanrurugi-api/src/stamps.rs:58。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 向 Tankoubon 添加图章 [Section titled “向 Tankoubon 添加图章”](#向-tankoubon-添加图章) PUThttp\://localhost:3000/api/tankoubons/{id}/stamps/{page} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `tank_add_stamp`,位于 crates/lanrurugi-api/src/stamps.rs:72。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 库统计 > 3 endpoints. 3 endpoints. ## The archives behind one bar of one chart [Section titled “The archives behind one bar of one chart”](#the-archives-behind-one-bar-of-one-chart) GEThttp\://localhost:3000/api/stats/bucket A drill-down: given one bucket of one `/stats` chart, the archives in it, for the list the page shows under the chart. Fetched per click rather than folded into `/stats/overview`, which is a whole-library snapshot that would have to carry every bucket’s archive list to support this. Deliberately not expressed as a search query, even though some of these buckets have one: “last read on day X” has no search operator at all, and the progress ladder’s `unread` rung means “never *opened*” (its own `is_read`) while the search’s `read:`/`is:unread` filters key on the `progress` field alone — so they disagree about an archive that was opened without a page turn. Deriving the list from the same classification the chart used is what keeps the list and the bar consistent by construction. Requesting this as a guest is scoped to what that guest may see, matching `/stats/overview`. #### 查询参数 * metricstring · enum: ingest | read | size | rating | progress必填 `ingest`/`read` are time buckets and need `from`+`to`; `size`/`rating`/`progress` are keyed buckets and need `key`. * fromstring可选 `ingest`/`read` only. First day of the bucket, `YYYY-MM-DD`, inclusive. The client sends the span it actually drew rather than a unit+key pair, so no bucket-key-to-span arithmetic has to exist in two languages. * tostring可选 `ingest`/`read` only. Last day of the bucket, `YYYY-MM-DD`, inclusive. * keystring可选 `size` bucket key (`lt_1mb` … `gte_500mb`), a `rating` of `0`-`5` (where `0` is the unrated-or-zero slot, exactly as the chart's own distribution counts it), or a `progress` ladder key (`unread`, `1_20`, `21_40`, `41_60`, `61_80`, `81_99`, `finished`). #### 响应 服务器地址http\://localhost:3000API 令牌••••• metricqueryingestfromquerytoquerykeyquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## Aggregated library statistics [Section titled “Aggregated library statistics”](#aggregated-library-statistics) GEThttp\://localhost:3000/api/stats/overview One snapshot covering: headline totals, archive size distribution, container format/MIME breakdown, ingestion history (by month, by ingestion path, and the newest arrivals), reading history (per-day, progress distribution, ratings, and the most recently/most often read works), and a weighted reading-preference analysis over tags, authors and categories. Requesting this as a guest yields counts and breakdowns restricted to what that guest may actually see, matching `/database/stats`’s own scoping. Weighted preference values are relative rankings, not probabilities or percentages: they are only ever meaningful against each other within one response. #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## One metric’s daily time series [Section titled “One metric’s daily time series”](#one-metrics-daily-time-series) GEThttp\://localhost:3000/api/stats/timeline The page’s time-series source, kept separate from `/stats/overview` because it is driven interactively: the overview is one expensive snapshot (its preference analysis runs a search per dynamic category), while this endpoint is refetched per range change and re-bucketed entirely client-side. The series is **always daily**, whatever granularity the reader is looking at, so that changing granularity — or zooming and panning — needs no request at all once the range has been fetched once. A request wider than the server’s own cap is clamped to the *newest* days of it, and `available_from` still reports where the data really begins. Requesting this as a guest is scoped to what that guest may see, matching `/stats/overview`. #### 查询参数 * metricstring · enum: ingest | reading必填 `ingest` counts archives added per day (from each archive's own `date_added` tag); `reading` reports page turns and archives-last-read per day. * frominteger可选 Unix seconds. Defaults to the whole available range — which is what the page asks for, so every later zoom is local. Clamped to the library's own data. * tointeger可选 Unix seconds; defaults to now, and is never later than it. #### 响应 服务器地址http\://localhost:3000API 令牌••••• metricqueryingestfromquerytoquery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 订阅 > 25 endpoints. 25 endpoints. ## 列出预留 [Section titled “列出预留”](#列出预留) GEThttp\://localhost:3000/api/reservations 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `list_reservations`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:1007。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 放弃预留 [Section titled “放弃预留”](#放弃预留) POSThttp\://localhost:3000/api/reservations/{id}/discard 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `discard_reservation`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:1027。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列表 [Section titled “列表”](#列表) GEThttp\://localhost:3000/api/subscriptions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `list`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:172。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 创建 [Section titled “创建”](#创建) POSThttp\://localhost:3000/api/subscriptions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `create`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:249。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 移除 [Section titled “移除”](#移除) DELETEhttp\://localhost:3000/api/subscriptions/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `remove`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:352。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 详情 [Section titled “详情”](#详情) GEThttp\://localhost:3000/api/subscriptions/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `detail`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:292。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新 [Section titled “更新”](#更新) PUThttp\://localhost:3000/api/subscriptions/{id} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `update`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:311。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 用户自己投的反对票:这些作品从此不再被该订阅下载 [Section titled “用户自己投的反对票:这些作品从此不再被该订阅下载”](#用户自己投的反对票这些作品从此不再被该订阅下载) POSThttp\://localhost:3000/api/subscriptions/{id}/block 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:644)的**译文**;原文以源码为准。 用户自己投的「不」:这些作品从此不再被该订阅下载。 刻意与「规则拒绝」区分开——规则读取的值会变化,所以拒绝是临时性的,每个周期都重新判定(FR-011i);而这是一个答复,重新判定就等于把用户已经说过的话再问一遍。预览界面按行提供这一操作;`forget_seen` 可以撤销它。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 立即执行一次真实检查,而不是等排期(FR-024) [Section titled “立即执行一次真实检查,而不是等排期(FR-024)”](#立即执行一次真实检查而不是等排期fr-024) POSThttp\://localhost:3000/api/subscriptions/{id}/check 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:846)的**译文**;原文以源码为准。 立即执行一次真实检查,而不是等待排期(FR-024)。 它是派生出去执行的,而不是被 await:一次检查要联系来源,还可能翻页遍历,比一个请求应该保持打开的时间更长。结果会出现在该订阅自己的历史里。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 停用 [Section titled “停用”](#停用) POSThttp\://localhost:3000/api/subscriptions/{id}/disable 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `disable`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:388。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 启用 [Section titled “启用”](#启用) POSThttp\://localhost:3000/api/subscriptions/{id}/enable 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `enable`,位于 crates/lanrurugi-api/src/subscriptions/api.rs:378。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 让某个订阅重新考虑它已经处理过的作品 [Section titled “让某个订阅重新考虑它已经处理过的作品”](#让某个订阅重新考虑它已经处理过的作品) POSThttp\://localhost:3000/api/subscriptions/{id}/forget 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:597)的**译文**;原文以源码为准。 让某个订阅重新考虑它已经处理过的作品。 「已看过」在其他情况下是永久性的,这对通常情形是正确的——用户故意删掉的作品绝不能在下次检查时回来。但有两种情况需要撤销它:一次误删,以及一条后来被放宽的规则(在旧规则下被拒绝的作品在被拒绝的那一刻就被记为已看过,所以没有任何东西会重新考虑它们)。 带 `sources` 时只遗忘指定的那些。带 `all: true` 时清空整个集合——它被保留为一个独立的、显式的请求,因为在长期运行的订阅上,它可能一次匹配到全部历史目录,后果的量级不同。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 预览一次检查会做什么,但不真的执行 [Section titled “预览一次检查会做什么,但不真的执行”](#预览一次检查会做什么但不真的执行) POSThttp\://localhost:3000/api/subscriptions/{id}/preview 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:803)的**译文**;原文以源码为准。 预览一次检查会做什么,但不真的执行。 它刻意可以作用于**已停用**的订阅:「这条规则实际会抓到什么」恰恰是在调整一条关掉的规则时问的。不会入队、不会记为已看过、也不会写日志,因此可以安全地反复运行——唯一的代价是向来源发一次请求。 接受一个可选的请求体携带尚未保存的订阅,这样规则可以在提交之前先预览。没有这一点,用户就得先保存一条规则才能知道它做什么。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 解除系统施加的暂停 [Section titled “解除系统施加的暂停”](#解除系统施加的暂停) POSThttp\://localhost:3000/api/subscriptions/{id}/resume 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:400)的**译文**;原文以源码为准。 解除系统施加的暂停。与 `enable` 不同,因为被暂停的订阅是*被系统*停下的,它欠用户一个解释——恢复就是用户对这个解释的回应。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 用户显式屏蔽过的全部作品,最新的在前 [Section titled “用户显式屏蔽过的全部作品,最新的在前”](#用户显式屏蔽过的全部作品最新的在前) GEThttp\://localhost:3000/api/subscriptions/blocked 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:417)的**译文**;原文以源码为准。 用户显式屏蔽过的全部作品,最新的在前,跨所有订阅。 它有自己的端点,而不是在历史记录上加个筛选:屏蔽是一个*答复*——用户对这个作品说了不——而历史是不断被后续周期重写的决策日志(一个先入队后入库的作品在每条记录里都读作 `already_held`)。只有屏蔽列表始终保持在用户留下的样子,这正是它值得单独展示、并从这里撤销的原因。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 生成 [Section titled “生成”](#生成) POSThttp\://localhost:3000/api/subscriptions/condition/ai 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `generate`,位于 crates/lanrurugi-api/src/subscriptions/ai_condition.rs:301。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 解析 [Section titled “解析”](#解析) POSThttp\://localhost:3000/api/subscriptions/condition/parse 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `parse`,位于 crates/lanrurugi-api/src/subscriptions/ai_condition.rs:284。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 全部订阅的近期候选,合并成一条按时间倒序的流 [Section titled “全部订阅的近期候选,合并成一条按时间倒序的流”](#全部订阅的近期候选合并成一条按时间倒序的流) GEThttp\://localhost:3000/api/subscriptions/history 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:450)的**译文**;原文以源码为准。 全部订阅的近期候选,合并成一条按时间倒序的流。 按订阅分开的历史已经存在,但它回答的是「*这条*规则做了什么」——而实际被问到的通常是另一个问题:最近来了什么,以及某个预期中的东西为什么没来。那需要把各个订阅交错在一起,而不是逐个读。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 等待用户确认的已匹配作品 [Section titled “等待用户确认的已匹配作品”](#等待用户确认的已匹配作品) GEThttp\://localhost:3000/api/subscriptions/pending 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:859)的**译文**;原文以源码为准。 已匹配、等待用户确认的作品。它之所以可达,仅仅因为 `auto_download` 默认关闭——否则那个默认值会让候选被记录下来却无从答复。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 批准——这一刻之后,无人值守的匹配才变成要花钱的操作 [Section titled “批准——这一刻之后,无人值守的匹配才变成要花钱的操作”](#批准这一刻之后无人值守的匹配才变成要花钱的操作) POSThttp\://localhost:3000/api/subscriptions/pending/approve 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:892)的**译文**;原文以源码为准。 批准就是无人值守的匹配变成有人值守的花钱的时刻——在此之前不消耗任何下载额度。 部分成功会如实上报而不是整体回滚:有多个条目时,其中一个入队失败没有理由把其余的也一并撤销批准,调用方会被告知究竟哪些没能入队。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 忽略——把每个作品标记为已看过,后续检查就不会再问同样的问题 [Section titled “忽略——把每个作品标记为已看过,后续检查就不会再问同样的问题”](#忽略把每个作品标记为已看过后续检查就不会再问同样的问题) POSThttp\://localhost:3000/api/subscriptions/pending/dismiss 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:980)的**译文**;原文以源码为准。 忽略会把每个作品标记为已看过,因此后续检查不会再提出同样的问题。这是用户在回答「不」——与预留不同,后者是系统在报告它*无法*下载某个东西。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 预览一个还不存在的订阅 [Section titled “预览一个还不存在的订阅”](#预览一个还不存在的订阅) POSThttp\://localhost:3000/api/subscriptions/preview 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:744)的**译文**;原文以源码为准。 预览一个还不存在的订阅。 带 id 的路由无法承担这件事:没有记录可读。而恰恰是在创建一个订阅的时候,「这条规则实际会抓到什么」最重要——之后用户就已经把规则定下来了。草稿是按来源当前的状态求值的,无论结果如何都不会存储任何东西。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 在可能不同的条件下,重新评判一份已抓取的列表 [Section titled “在可能不同的条件下,重新评判一份已抓取的列表”](#在可能不同的条件下重新评判一份已抓取的列表) POSThttp\://localhost:3000/api/subscriptions/preview/judge 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:684)的**译文**;原文以源码为准。 在可能不同的条件下,重新评判一份已抓取的列表。 改一个条件并不会改变来源会返回什么——只有 `criteria` 影响请求——所以重新抓取纯属浪费、很慢,而且是对一个有限流的来源又多发一次请求。判断仍然发生在这里而不是浏览器里,因为条件树的第二份实现迟早会与真实的那份产生分歧。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 哪些来源可以支撑一个订阅,以及各自的间隔上下限——好让界面只提供合法选项 [Section titled “哪些来源可以支撑一个订阅,以及各自的间隔上下限——好让界面只提供合法选项”](#哪些来源可以支撑一个订阅以及各自的间隔上下限好让界面只提供合法选项) GEThttp\://localhost:3000/api/subscriptions/sources 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:186)的**译文**;原文以源码为准。 哪些来源可以支撑一个订阅,以及各自的间隔上下限——好让界面只提供可行的来源,并在用户提交*之前*就显示这些上下限,而不是通过一次拒绝来教会用户规则。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 哪些订阅已经处理过某个作品(按其来源 URL 查) [Section titled “哪些订阅已经处理过某个作品(按其来源 URL 查)”](#哪些订阅已经处理过某个作品按其来源-url-查) GEThttp\://localhost:3000/api/subscriptions/tracking 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/subscriptions/api.rs:555)的**译文**;原文以源码为准。 哪些订阅已经处理过某个作品(按其来源 URL 查)。 在删除档案之前询问,这样删除流程只会为「确实由某个订阅带进来」的档案提供「不要再让它回来」这个选项——对一个手动上传的文件提供该选项等于给了一个没有效果的开关,那比不给选项更糟。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # Tankoubon 分组 > 8 endpoints. 8 endpoints. ## AI 分组建议 [Section titled “AI 分组建议”](#ai-分组建议) POSThttp\://localhost:3000/api/tankoubons/ai-group-suggestions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `ai_group_suggestions`,位于 crates/lanrurugi-api/src/tankoubon_grouping.rs:775。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 取消忽略某条 AI 分组建议(`DELETE /tankoubons/ai-group-suggestions/ignore`) [Section titled “取消忽略某条 AI 分组建议(DELETE /tankoubons/ai-group-suggestions/ignore)”](#取消忽略某条-ai-分组建议delete-tankoubonsai-group-suggestionsignore) DELETEhttp\://localhost:3000/api/tankoubons/ai-group-suggestions/ignore 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping.rs:1259)的**译文**;原文以源码为准。 `DELETE /tankoubons/ai-group-suggestions/ignore`——重新启用一条此前被忽略的建议(前端「显示已忽略的组合」清单里自己的「取消忽略」按钮)。幂等——取消忽略一个当前并未被忽略的组合是无操作,不是错误。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 忽略某条 AI 分组建议(「不要再建议这个组合」) [Section titled “忽略某条 AI 分组建议(「不要再建议这个组合」)”](#忽略某条-ai-分组建议不要再建议这个组合) POSThttp\://localhost:3000/api/tankoubons/ai-group-suggestions/ignore 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping.rs:1216)的**译文**;原文以源码为准。 `POST /tankoubons/ai-group-suggestions/ignore`——对某一条具体建议执行「不要再建议这个」。幂等(忽略一个已被忽略的组合只会覆盖它的 `ignored_at` 时间戳,见 `IgnoredGroupSuggestionsRepository::ignore` 自身的契约)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 列出被忽略的 AI 分组建议(支撑「显示已忽略的组合」) [Section titled “列出被忽略的 AI 分组建议(支撑「显示已忽略的组合」)”](#列出被忽略的-ai-分组建议支撑显示已忽略的组合) GEThttp\://localhost:3000/api/tankoubons/ai-group-suggestions/ignored 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping.rs:1281)的**译文**;原文以源码为准。 `GET /tankoubons/ai-group-suggestions/ignored`——支撑「显示已忽略的组合」清单本身(标题由客户端针对已加载的档案列表解析,用的就是 `AiSmartTankoubonModal.tsx` 已经为主建议卡片构建的那张 `titleById` 映射——这个端点只需要返回原始的已忽略条目,不必在服务端做补全)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## `DELETE /tankoubons/ai-group-suggestions/labels` (FR-017) [Section titled “DELETE /tankoubons/ai-group-suggestions/labels (FR-017)”](#delete-tankoubonsai-group-suggestionslabels-fr-017) DELETEhttp\://localhost:3000/api/tankoubons/ai-group-suggestions/labels 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping/labels.rs:197),**逐字引用、未翻译**——它是写给本代码库维护者看的,可能会提到内部标识符。 `DELETE /tankoubons/ai-group-suggestions/labels` (FR-017). #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## `GET /tankoubons/ai-group-suggestions/labels` [Section titled “GET /tankoubons/ai-group-suggestions/labels”](#get-tankoubonsai-group-suggestionslabels) GEThttp\://localhost:3000/api/tankoubons/ai-group-suggestions/labels 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping/labels.rs:185),**逐字引用、未翻译**——它是写给本代码库维护者看的,可能会提到内部标识符。 `GET /tankoubons/ai-group-suggestions/labels`. #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## `POST /tankoubons/ai-group-suggestions/labels` [Section titled “POST /tankoubons/ai-group-suggestions/labels”](#post-tankoubonsai-group-suggestionslabels) POSThttp\://localhost:3000/api/tankoubons/ai-group-suggestions/labels 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping/labels.rs:128),**逐字引用、未翻译**——它是写给本代码库维护者看的,可能会提到内部标识符。 `POST /tankoubons/ai-group-suggestions/labels`. #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## `POST /tankoubons/ai-group-suggestions/review` — never an HTTP error for a review failure: the [Section titled “POST /tankoubons/ai-group-suggestions/review — never an HTTP error for a review failure: the”](#post-tankoubonsai-group-suggestionsreview--never-an-http-error-for-a-review-failure-the) POSThttp\://localhost:3000/api/tankoubons/ai-group-suggestions/review 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubon_grouping/review\.rs:489),**逐字引用、未翻译**——它是写给本代码库维护者看的,可能会提到内部标识符。 `POST /tankoubons/ai-group-suggestions/review` — never an HTTP error for a review failure: the card always renders, with the local result when the review could not be had. #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # Tankoubon API > 13 endpoints. 13 endpoints. ## 获取全部 Tankoubon [Section titled “获取全部 Tankoubon”](#获取全部-tankoubon) GEThttp\://localhost:3000/api/tankoubons 分页获取 Tankoubon 列表。 #### 查询参数 * pageinteger可选 Tankoubon 列表的页码。 每页数量取决于服务端的 `archives_per_page` 设置。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• pagequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 创建 Tankoubon [Section titled “创建 Tankoubon”](#创建-tankoubon) PUThttp\://localhost:3000/api/tankoubons 创建一个新 Tankoubon,或更新已有 Tankoubon 的名称。 #### 请求体 application/x-www-form-urlencoded, multipart/form-data #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除 Tankoubon [Section titled “删除 Tankoubon”](#删除-tankoubon) DELETEhttp\://localhost:3000/api/tankoubons/{id} 从服务端移除一个 Tankoubon。这不会删除它底下的档案。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取单个 Tankoubon [Section titled “获取单个 Tankoubon”](#获取单个-tankoubon) GEThttp\://localhost:3000/api/tankoubons/{id} 获取指定 tankoubon ID 的详情。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新 Tankoubon 的元数据与内容 [Section titled “更新 Tankoubon 的元数据与内容”](#更新-tankoubon-的元数据与内容) PUThttp\://localhost:3000/api/tankoubons/{id} 修改 Tankoubon 的完整元数据(名称、摘要、附加标签)或它的内容。\ 如果你只需要改名称,考虑直接用 PUT `/api/tankoubons`。 注意:如果不需要更新 `data` 里某个键对应的内容,就不要发送那个键——否则可能产生非预期的结果。 #### 路径参数 * idstring · min: 15 · max: 15 · pattern必填 要更新的 Tankoubon ID。 #### 请求体 application/json #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把档案移出 Tankoubon [Section titled “把档案移出 Tankoubon”](#把档案移出-tankoubon) DELETEhttp\://localhost:3000/api/tankoubons/{id}/{archive} 把某个档案移出一个 Tankoubon。 #### 路径参数 * idstring · min: 15 · max: 15 · pattern必填 要更新的 Tankoubon ID。 * archivestring · min: 40 · max: 40 · pattern必填 要移除的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpatharchivepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 把档案加入 Tankoubon [Section titled “把档案加入 Tankoubon”](#把档案加入-tankoubon) PUThttp\://localhost:3000/api/tankoubons/{id}/{archive} 把一个档案追加到 Tankoubon 的最后一位。 #### 路径参数 * idstring · min: 15 · max: 15 · pattern必填 要更新的 Tankoubon ID。 * archivestring · min: 40 · max: 40 · pattern必填 要追加的档案 ID。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpatharchivepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## AI 重命名章节 [Section titled “AI 重命名章节”](#ai-重命名章节) POSThttp\://localhost:3000/api/tankoubons/{id}/ai/rename-chapter 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `ai_rename_chapter`,位于 crates/lanrurugi-api/src/tankoubons.rs:1714。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## AI 重命名建议 [Section titled “AI 重命名建议”](#ai-重命名建议) POSThttp\://localhost:3000/api/tankoubons/{id}/ai/rename-suggestions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/tankoubons.rs:1588)的**译文**;原文以源码为准。 把 tankoubon 的标题、成员档案名与顺序发给 DeepSeek,返回 AI 生成的改名建议(tankoubon 名称 + 每个档案的章节名)。必须配置 LLM 密钥;未配置时返回 400。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取单个 Tankoubon 的完整详情 [Section titled “获取单个 Tankoubon 的完整详情”](#获取单个-tankoubon-的完整详情) GEThttp\://localhost:3000/api/tankoubons/{id}/full 获取指定 tankoubon ID 的详情,附带分页的档案元数据。 每页的档案数取决于服务端的 `archives_per_page` 设置。 #### 查询参数 * pageinteger · default: -1可选 档案列表的页码。默认 -1,返回全部档案。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• pagequery 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新 Tankoubon 阅读进度 [Section titled “更新 Tankoubon 阅读进度”](#更新-tankoubon-阅读进度) PUThttp\://localhost:3000/api/tankoubons/{id}/progress/{page} 告诉服务端你当前正在阅读这个 Tankoubon 的第几页,以便它相应地更新内部的阅读进度。 页码是在该 tank 内所有档案上全局计数的(如果一个 tank 有两个档案,分别有 20 页和 25 页,那么第 26 页就是第 2 个档案的第 6 页)。 ⚠ 如果服务端配置为使用客户端进度跟踪,这个 API 调用会返回错误! 调用前请务必先用 `/api/info` 确认服务端是否跟踪阅读进度。 #### 路径参数 * idstring · min: 15 · max: 15 · pattern必填 要更新的 Tankoubon ID。 * pageinteger · min: 1必填 要更新到的全局页码,从 1 开始计数。必须是正整数。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• idpathpagepath 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取 Tankoubon 缩略图 [Section titled “获取 Tankoubon 缩略图”](#获取-tankoubon-缩略图) GEThttp\://localhost:3000/api/tankoubons/{id}/thumbnail 获取指定 Tankoubon 的封面缩略图。 默认情况下,缩略图取自第一个档案的第一页。 如果缩略图尚不存在,这个端点会返回一张占位图。 若想把缩略图生成排入后台, 可以使用 `no_fallback` 查询参数。 #### 查询参数 * no_fallbackstring · enum: true | false可选 关闭占位图,把缩略图排入提取队列,并返回 code 202 的 JSON。图片已存在时该参数不起作用。(无论哪种情况,只要图片已存在就会以 code 200 返回它) #### 响应 服务器地址http\://localhost:3000API 令牌••••• no_fallbackquerytrue 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新 Tankoubon 缩略图 [Section titled “更新 Tankoubon 缩略图”](#更新-tankoubon-缩略图) PUThttp\://localhost:3000/api/tankoubons/{id}/thumbnail 用跨该 tank 内所有档案(按顺序)的全局页码,设置指定 Tankoubon 的封面缩略图。全局页码会自动换算到正确的档案与其中的局部页码。 #### 查询参数 * pageinteger · min: 1必填 跨整个 Tankoubon 内所有档案的全局页码,从 1 开始计数。第 1 页就是第一个档案的第一页,依此类推。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• pagequery 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 术语表 > 3 endpoints. 3 endpoints. ## 获取术语表 [Section titled “获取术语表”](#获取术语表) GEThttp\://localhost:3000/api/volumes/{id}/terminology-glossary 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_glossary`,位于 crates/lanrurugi-api/src/terminology_glossary.rs:38。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 删除条目 [Section titled “删除条目”](#删除条目) DELETEhttp\://localhost:3000/api/volumes/{id}/terminology-glossary/{term} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `delete_entry`,位于 crates/lanrurugi-api/src/terminology_glossary.rs:139。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 编辑单条记录 [Section titled “编辑单条记录”](#编辑单条记录) PUThttp\://localhost:3000/api/volumes/{id}/terminology-glossary/{term} 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/terminology_glossary.rs:59)的**译文**;原文以源码为准。 编辑单条记录。在下一次翻译请求时生效(FR-007d)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 页面翻译 > 6 endpoints. 6 endpoints. ## 检测结果,加上浏览器在本地翻译与合成所需的全部数据 [Section titled “检测结果,加上浏览器在本地翻译与合成所需的全部数据”](#检测结果加上浏览器在本地翻译与合成所需的全部数据) GEThttp\://localhost:3000/api/archives/{id}/page/{page}/text-regions 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:406)的**译文**;原文以源码为准。 检测结果,加上浏览器在本地翻译与合成所需的全部数据。 包含云端路径所组装的同一份 `context`,因此本地托管的后端也能获得 FR-007a–e 的一致性收益,尽管它的翻译调用从不经过本服务端。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 读者的「重新翻译」:丢弃本页的检测缓存、全部已翻译记录与合成结果 [Section titled “读者的「重新翻译」:丢弃本页的检测缓存、全部已翻译记录与合成结果”](#读者的重新翻译丢弃本页的检测缓存全部已翻译记录与合成结果) DELETEhttp\://localhost:3000/api/archives/{id}/page/{page}/translation 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:203)的**译文**;原文以源码为准。 阅读界面的「重新翻译」:丢弃本页的检测缓存、全部已翻译记录以及渲染出的图片,使下一次 `GET .../translation` 重新跑完整的 OCR → 翻译 → 合成流程,而不是复用过期缓存(例如由旧版流程产生的,或区域检测不完整的那一份)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 为云端后端路径提供合成好的译文页面(T028) [Section titled “为云端后端路径提供合成好的译文页面(T028)”](#为云端后端路径提供合成好的译文页面t028) GEThttp\://localhost:3000/api/archives/{id}/page/{page}/translation 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:275)的**译文**;原文以源码为准。 为云端后端路径提供合成好的译文页面(T028)。 有缓存渲染结果时直接返回。未命中时它会**触发**真正的编排流程——OCR → 字体路由 → 批量翻译 → 合成 → 写缓存(`translation_pipeline::translate_page`)——覆盖本页及其预读窗口,然后立刻报告「尚未就绪」。 这里刻意不等待该工作完成:一个完整的 OCR + LLM 周期要几十秒,而 FR-012 要求阅读界面在此期间继续显示原图并给出非阻塞的提示。客户端轮询即可;后续某次轮询就能拿到这次触发的缓存条目。阅读永远不应等待翻译(SC-007)。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 记录浏览器用它自己的本地模型得到的译文(T049a) [Section titled “记录浏览器用它自己的本地模型得到的译文(T049a)”](#记录浏览器用它自己的本地模型得到的译文t049a) POSThttp\://localhost:3000/api/archives/{id}/page/{page}/translation/record 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:591)的**译文**;原文以源码为准。 记录浏览器用它自己的本地模型得到的译文(T049a)。 **这里不会发生任何 LLM 调用**——它只是一次轻量写入。其目的是让本地后端翻译出的名称/术语仍然进入服务端共享的术语表,从而使后续同一卷的云端路径(或其他设备)请求与之保持一致。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 报告该档案当前是否开启翻译,以及开启的是该档案自身的设置还是它所属 Tankoubon 的 [Section titled “报告该档案当前是否开启翻译,以及开启的是该档案自身的设置还是它所属 Tankoubon 的”](#报告该档案当前是否开启翻译以及开启的是该档案自身的设置还是它所属-tankoubon-的) GEThttp\://localhost:3000/api/archives/{id}/translation/scope 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:118)的**译文**;原文以源码为准。 报告该档案当前是否开启翻译,以及开启的是它自己的设置还是从它所属的 Tankoubon 继承来的——后者是为了让阅读界面能告诉用户「这一项跟随整本书的设置」,而不是把一个只影响本文件的开关呈现得好像切换它会影响到别处。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 设置当前实际管辖该档案的那个开关(若档案属于某个 Tankoubon,则是该 Tankoubon 的) [Section titled “设置当前实际管辖该档案的那个开关(若档案属于某个 Tankoubon,则是该 Tankoubon 的)”](#设置当前实际管辖该档案的那个开关若档案属于某个-tankoubon则是该-tankoubon-的) PUThttp\://localhost:3000/api/archives/{id}/translation/scope 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation.rs:144)的**译文**;原文以源码为准。 设置当前实际管辖该档案的那个开关(若它属于某个 Tankoubon 则是该 Tankoubon 的,否则是该档案自身)——为什么在这里切换只会作用于其中之一、从不两者同时,见 `TranslationScopeRepository::set_enabled` 自身的文档。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 翻译设置 > 4 endpoints. 4 endpoints. ## 更新预算 [Section titled “更新预算”](#更新预算) PUThttp\://localhost:3000/api/translation/budget 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `update_budget`,位于 crates/lanrurugi-api/src/translation_settings.rs:335。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 获取翻译设置 [Section titled “获取翻译设置”](#获取翻译设置) GEThttp\://localhost:3000/api/translation/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_translation_settings`,位于 crates/lanrurugi-api/src/translation_settings.rs:118。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## 更新翻译设置 [Section titled “更新翻译设置”](#更新翻译设置) PUThttp\://localhost:3000/api/translation/settings 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `update_translation_settings`,位于 crates/lanrurugi-api/src/translation_settings.rs:172。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 该端点需要**管理员**令牌:访客(只读)令牌会被服务端拒绝。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 ## FR-014 要求的四个粒度上的当前用量 [Section titled “FR-014 要求的四个粒度上的当前用量”](#fr-014-要求的四个粒度上的当前用量) GEThttp\://localhost:3000/api/translation/usage 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/translation_settings.rs:277)的**译文**;原文以源码为准。 FR-014 要求的四个粒度上的当前用量。 没有配置计量后端时返回一个全零结果而不是错误——本地托管的后端本来就没有用量可报告。 #### 响应 服务器地址http\://localhost:3000API 令牌••••• 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。 # 版本 > 1 endpoint. 1 endpoint. ## 获取版本 [Section titled “获取版本”](#获取版本) GEThttp\://localhost:3000/api/version 尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。 对应的 handler 是 `get_version`,位于 crates/lanrurugi-api/src/version.rs:528。 #### 响应 服务器地址http\://localhost:3000 该端点不需要认证。 发送复制为 cURL **请求失败** — 常见原因:实例地址填错或不可达;实例未开启「为客户端 API 启用 CORS」;或者文档站是 HTTPS 而实例是局域网内的纯 HTTP(浏览器按混合内容拦截)。可以用上面的「复制为 cURL」在终端里发同样的请求。 ``` ``` 填写你自己的实例地址,请求由浏览器直接发往该地址。