跳转到内容

下载队列

21 endpoints.

GEThttp://localhost:3000/api/download_queue

下载队列中的每一个项,无论它当前处于什么状态。

需要实时更新时请优先使用 /download_queue/stream,它会在状态变化发生时主动推送,而不必轮询。

响应

200队列。
{
  "items": [
    {}
  ]
}

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue

批量添加。调用者已经自行判断好每个 URL 匹配的是哪个下载插件的 url_pattern;这个端点唯一的校验是 plugin_namespace 能解析到一个已安装的插件。

无效条目会被逐条拒绝,而不是让整批失败,因此粘贴的列表里有一个坏 URL 不会挡住其余的。请检查响应中的 rejected。

请求体

application/json

响应

200已加入的项,以及未能加入的项。
{
  "added": [
    {}
  ],
  "rejected": [
    {
      "reason": "",
      "url": ""
    }
  ]
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

DELETEhttp://localhost:3000/api/download_queue/{id}

从队列中移除一个项。

正在下载中的项会以 409 拒绝——把它的记录从正在运行的后台任务下面抽掉,会让那个任务无处更新,队列里既没有行可以显示进度,也没有办法停止传输。请先停止它。

已经入库的队列项同样会被拒绝;请改为删除由此产生的那份档案。

路径参数

idstring必填

响应

200已删除。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}
409该项正在下载;请先停止再删除。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

PATCHhttp://localhost:3000/api/download_queue/{id}

部分更新:请求体中省略的字段会保留已存储的值,而不是被清空。约定与 PUT /plugins/options 相同。

路径参数

idstring必填

请求体

Any subset of the item's editable fields.

响应

200已更新。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}
404没有该队列项。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}

该端点只接受网页会话(登录本站所用实例后浏览器自动携带的 cookie)。API 令牌会被服务端拒绝,因此这里不提供令牌输入框,上面的命令行也不带 Authorization 头。

填写你自己的实例地址,请求由浏览器直接发往该地址。

AI 质量对比判断(issue #77,针对某个下载队列项)

Section titled “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 自身的文档)。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:44 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue/{id}/compare/export-patch

尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。

下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2604)的译文;原文以源码为准。

POST /download_queue/{id}/compare/export-patch——用用户挑选的 A 侧独有页面(ComparisonResult.a_unmatched_pages,issue #77 自己的后续设计)构建一个 .patch.zip,并返回其原始字节供下载,可直接放到目标档案所在磁盘位置并命名为 <档案文件名>.patch.zip(lanrurugi_scanner::patch)——这个端点自己不会把它写到那里(已确认的设计:「补丁不需要应用,只要放在漫画目录内」——由用户放置的文件,而不是本服务端未经请求就安装的东西)。目标永远是 B(本次冲突所针对的库中已有档案)——补丁只会在用户保留的那一版之上追加 A 自己的额外页面,绝不会反过来。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:61 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

保留书库中已有的那份档案、丢弃新下载的那份

Section titled “保留书库中已有的那份档案、丢弃新下载的那份”
POSThttp://localhost:3000/api/download_queue/{id}/compare/keep-b

尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。

下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2713)的译文;原文以源码为准。

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 旁边的磁盘文件上,而不是队列项的某个标记)。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:65 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

对比视图里某一侧某一页的真实图片

Section titled “对比视图里某一侧某一页的真实图片”
GEThttp://localhost:3000/api/download_queue/{id}/compare/page

尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。

下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2348)的译文;原文以源码为准。

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),为它加缓存不值得。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:53 处的 handler。

该响应没有示例数据。

填写你自己的实例地址,请求由浏览器直接发往该地址。

列出一侧对比项的真实条目名列表(GET /download_queue/{id}/compare/pages?side=a|b)

Section titled “列出一侧对比项的真实条目名列表(GET /download_queue/{id}/compare/pages?side=a|b)”
GEThttp://localhost:3000/api/download_queue/{id}/compare/pages

尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。

下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:2476)的译文;原文以源码为准。

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 刻意不使用页码(为什么以条目名而非可能因档案重新扫描而漂移的下标作为稳定锚点,见该模块的文档)。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:57 处的 handler。

该响应没有示例数据。

填写你自己的实例地址,请求由浏览器直接发往该地址。

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,因此重新打开一个已算好的对比依然是瞬时完成的。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:49 处的 handler。

该响应没有示例数据。

填写你自己的实例地址,请求由浏览器直接发往该地址。

确认保留较旧的版本(回答「是否用旧版本覆盖」这个提问)

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,所以普通的启动按钮不会不小心跳过这个提问。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:45 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

「获取元数据」按钮的后端路径

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。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:36 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

用新下载覆盖同名文件,从而解决 PendingFilenameConflict

Section titled “用新下载覆盖同名文件,从而解决 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)——之后再想读就没有东西可读了。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:42 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

把冲突的文件重新命名并入库,从而解决 PendingFilenameConflict

Section titled “把冲突的文件重新命名并入库,从而解决 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 自身的文档。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:43 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue/{id}/start

解析该项自己的下载插件(用的是它被加入时选定的那个,而不是现在重新选),标记为正在启动,并在后台发起真正的下载。随着传输推进,该项的 state、job_id 与 error 始终保持最新。

路径参数

idstring必填

响应

200已启动;响应体里带着任务 ID。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}
409该项当前不处于可启动状态。
{
  "error": "",
  "operation": "",
  "success": 0,
  "successMessage": ""
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

停止进行中的队列项(POST /download_queue/{id}/stop,用于 Starting/Downloading 状态的项)

Section titled “停止进行中的队列项(POST /download_queue/{id}/stop,用于 Starting/Downloading 状态的项)”
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,并不值得大声报错,因为无论哪种情况,期望的最终状态(「这一项没有在下载」)都已经成立。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:41 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

清空已完成项(POST /download_queue/clear_completed,删除所有 Done 项并返回删除数量)

Section titled “清空已完成项(POST /download_queue/clear_completed,删除所有 Done 项并返回删除数量)”
POSThttp://localhost:3000/api/download_queue/clear_completed

尚未在此参考中描述。这个端点会被列出,是因为服务端确实注册了它,但它的请求与响应形状还没有写下来。

下面这段是 handler 自己的文档注释(crates/lanrurugi-api/src/download_queue.rs:3092)的译文;原文以源码为准。

POST /download_queue/clear_completed——删除所有 Done 状态的项,返回删除数量。刻意排除 Error——与 Done 不同,出错的项是一个可重试、仍可操作的状态(在本模块其他地方都与 Queued/Cancelled 归为一类:可选中、有重试按钮、显示自己的错误文本),而不是用户已经看完不想再管的「已完成」工作。想丢弃某个具体失败项的用户,仍可通过 DELETE /download_queue/{id} 单独处理(那个端点确实会清理 pending_filename_conflict 自己暂存的临时文件——Done 项从不带这种文件,所以本 handler 没有同类东西需要操心)。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:69 处的 handler。

该响应没有示例数据。

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue/delete_selected

按 ID 批量删除,语义与 start_selected 对齐:不存在或已被删除的 ID 是静默无操作,不是错误,所以可以安全地传入一份过期的选择。

正在下载中的 ID 同样是静默无操作——这正是单项删除用 409 表达的同一套安全规则。

请求体

application/json

响应

200实际被移除的那些 ID。
{
  "deleted": [
    ""
  ]
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue/start_all

并发启动所有处于 queued 状态的项。每一项都会派生自己的后台任务;按域名限流与并发限制由下载管理器在下游统一执行,所以这里不再额外限速。

它的范围刻意比单项启动更窄:处于 error 或 cancelled 的项必须逐个重试,而正在等待版本冲突答复的项绝不会被顺带启动——批量启动它等于用沉默回答了它正卡着的那个问题。

响应

200哪些项启动了、哪些被跳过以及原因。
{
  "skipped": [
    {
      "id": "",
      "reason": ""
    }
  ],
  "started": [
    {
      "id": "",
      "job": ""
    }
  ]
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

POSThttp://localhost:3000/api/download_queue/start_selected

与 start_all 相同,但只作用于给定的那些 ID。

已经进行中、已经完成、或以其他方式无法启动的 ID 是静默无操作,不是错误——这样客户端可以直接传入一份选择,而不必先逐个复查当前状态。

请求体

application/json

响应

200哪些项启动了、哪些被跳过以及原因。
{
  "skipped": [
    {
      "id": "",
      "reason": ""
    }
  ],
  "started": [
    {
      "id": "",
      "job": ""
    }
  ]
}

该端点需要管理员令牌:访客(只读)令牌会被服务端拒绝。

填写你自己的实例地址,请求由浏览器直接发往该地址。

推送下载队列项状态变化的 SSE 端点(GET /download_queue/stream)

Section titled “推送下载队列项状态变化的 SSE 端点(GET /download_queue/stream)”
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 即可完成初始化。

响应

200该端点已响应;其确切结构尚未记录,见 crates/lanrurugi-api/src/download_queue.rs:31 处的 handler。

该响应没有示例数据。

填写你自己的实例地址,请求由浏览器直接发往该地址。