File Browser Operator
by @kami1983
Operate FileBrowser via REST API—login, list/upload/download resources, manage users. Scan for 采购单 files in scope, prompt user to download by number or all,...
clawhub install kam-filebrowser-operator📖 About This Skill
name: filebrowser-api description: Operate FileBrowser via REST API—login, list/upload/download resources, manage users. Scan for 采购单 files in scope, prompt user to download by number or all, or provide download/browser link. Organize files by order type (e.g. 采购单) into 类型/年份/月份/ structure; report files that could not be organized and why. Use when automating FileBrowser, calling its API, or integrating with it.
FileBrowser API 操作
通过 REST API 操作 FileBrowser:认证、文件列表/上传/下载、用户管理等。本技能适用于脚本、自动化或与其他系统集成。
首次使用:向用户确认配置
在通过本技能调用 FileBrowser API 或生成相关脚本之前,按以下顺序获取 Base URL、用户名、密码:
1. 优先:若存在 kam-filebrowser-operator/config.json,从中读取 baseUrl、username、password、scope(该文件已加入 .gitignore,勿提交)。
2. 否则:若项目根目录有 .env 或环境变量中有 FB_BASE_URL/FB_USER/FB_PASSWORD,可从中读取。
3. 否则:必须先向用户询问:
- Base URL:例如 http://127.0.0.1:9888
- 用户名:FileBrowser 登录账号
- 密码:至少 12 位
首次使用本 skill 时,可复制 kam-filebrowser-operator/config.example.json 为 kam-filebrowser-operator/config.json 并填写真实值;务必保证 config.json 不被提交到版本库,且不得上传到 FileBrowser 或任何远程位置。
安全:密码与凭证
你的密码、$FB_PASSWORD)或从环境变量/配置文件读取。kam-filebrowser-operator/config.json(已加入 .gitignore)或项目根目录 .env 中。kam-filebrowser-operator/config.json:该文件含登录凭证,不得通过本 skill、FileBrowser API 或任何方式上传到 FileBrowser 或其它远程;执行上传、同步、备份等操作时须排除该文件。.env 或持久化凭证的上传/登录脚本(例如 upload-to-filebrowser.sh 等)。仅提供一次性命令(如 curl),由用户在已设置环境变量的终端中执行,或每次由用户临时提供 Base URL、用户名、密码。FB_USER、FB_PASSWORD)或受保护的配置读取账号密码,不要硬编码。可操作目录(scope)
kam-filebrowser-operator/config.json 中必须配置 scope,表示本 skill 仅允许在该 FileBrowser 目录下操作(如 "/Qianlu")。scope 之下;不得访问或操作 scope 以外的路径。POST /api/resources//?override=false ,路径末尾带 /,不传 Body)建立该目录,再继续执行用户请求的操作。scope,须拒绝并说明仅支持在配置的目录内操作;若未配置 scope,须提示用户先在 config.json 中设置 scope 再执行操作。基础配置
kam-filebrowser-operator/config.json(字段 baseUrl、username、password、scope);若无则用项目 .env 或环境变量;再无则向用户询问。http://127.0.0.1:9888。可在 config.json 或 .env 中配置。X-Auth: 。1. 登录获取 Token
POST /api/login
Content-Type: application/json{
"username": "Username",
"password": "你的密码",
"recaptcha": ""
}
成功响应体为 JSON,其中包含 token 字段。后续所有 API 请求需添加:
X-Auth:
2. 资源(文件/目录)接口
列出目录
GET /api/resources?path=
GET /api/resources?path=/子目录
Query 参数 path 必须在 config 的 scope 之下(如 scope 为 /Qianlu 时,用 Qianlu 或 Qianlu/子目录;部分环境 path 带前导 / 如 /Qianlu)。响应为 JSON,形如:
{
"items": [
{ "name": "文件名.txt", "path": "相对路径", "isDir": false, "size": 123, "extension": ".txt" },
{ "name": "子目录", "path": "子目录", "isDir": true, ... }
],
"numDirs": 1,
"numFiles": 1
}
items 中 isDir === true 的项为子目录,isDir === false 的为文件。path 为相对于根或 scope 的路径(如 Qianlu、Qianlu/采购单),下一层子项在 items[].name 或 items[].path 中。遍历目录并获取文件名称
1. 单层:GET /api/resources?path=<目录路径>,从响应 items 中取每项的 name(即该层下的文件名与子目录名)。
2. 递归遍历:
- 先请求 path= 得到根层 items;
- 对每个 item:若 item.isDir === true,再请求 path=<当前路径>/(当前路径首层为 scope 名,如 Qianlu),得到该子目录下的 items;
- 重复上述步骤直到没有子目录,或达到所需层级;
- 收集所有 isDir === false 的 item.name 即为该目录树下的全部文件名(可同时保留相对路径:当前路径 + / + item.name)。
3. 路径约定:path 使用与 API 一致的格式(多数为 scope 或 scope/子路径,无前导 /),遍历时用「当前 path + / + 子项 name」拼出子路径。
上传文件
POST /api/resources/<文件路径>?override=true
X-Auth:
Content-Type: application/octet-stream
或具体类型,如 text/plain、application/json
<文件二进制或文本内容作为 Body>
<文件路径> 必须在 config 的 scope 之下,且必须带 scope 前缀才会进入 scope 目录内(如 scope 为 /Qianlu 时,用 Qianlu/文件名,不要只用 文件名,否则会落在根目录)。子路径示例:Qianlu/doc.txt、Qianlu/子目录/file.txt。override=true 表示覆盖已存在文件;不传或 false 则存在时可能报错。kam-filebrowser-operator/config.json、.env 及任何含凭证的文件不得通过本接口上传。下载 / 原始文件
GET /api/raw/<文件路径>
X-Auth:
<文件路径> 必须在 scope 之下。返回文件原始内容,用于下载或直接读取。
采购单扫描与下载流程
在 scope 内扫描出采购单相关文件(如通过搜索「采购单」或遍历目录筛选名称)后,按以下步骤与用户交互:
1. 列出清单并编号
将结果整理为带编号的列表,例如:
1. 采购单-RFQ0311.xlsx、2. 采购单-XXX.xlsx
或使用文件名、编号等便于区分的标识。
2. 提示是否下载 明确询问用户:是否需要下载?可回复对应编号(如 1、2)或「全部」。 未选择则视为不需要下载。
3. 执行下载或提供链接
- 能直接提供文件时:按用户选择的编号或「全部」,用 GET /api/raw/<路径> 拉取文件,在对话中提供或说明已准备好(视环境是否支持传输文件)。
- 用户要求直接下载链接或无法在对话中提供文件时:按下方「分享链接(直接下载链接)」流程生成链接;若不可用则用方式二。
- 方式二(备用):提供 FileBrowser 内下载说明:在浏览器打开 baseUrl,登录后进入对应路径(如 Qianlu/采购单-xxx.xlsx)即可下载。并提示:可在 FileBrowser Web 界面对该文件点击「分享」自行生成有效链接。
- 提供链接时注明:分享链接有效期视服务端配置(expire 为 0 通常表示长期有效),若失效可再次请求生成。
分享链接(与网页流程一致)
用于生成无需登录即可打开分享页并下载的链接,用户要求「分享链接」时使用。
> 关键:端点是 /api/share/<文件路径>(单数 share,路径在 URL),不是 /api/shares(复数)。复数端点会导致 path 被存为 "s",生成的链接无效。
1. 创建分享
POST /api/share/
X-Auth:
Content-Type: application/json {}
- 文件路径放在 URL 中,如 POST /api/share/Qianlu/采购单-RFQ0311.xlsx(路径须在 scope 内)。
- Body 为空 JSON {}。若需设置有效期,Body 传 {"expires":"<秒数>","unit":"seconds"},例如 1 小时:{"expires":"3600","unit":"seconds"}。不传则长期有效(expire = 0)。
- 响应示例:{"hash":"0wod80NP","path":"/Qianlu/采购单-RFQ0311.xlsx","userID":1,"expire":0},取 hash。
2. 拼出分享链接
- 分享页(与网页「复制链接」一致):baseUrl/share/
- 示例:http://127.0.0.1:9888/share/0wod80NP
- 用户在浏览器中打开即可查看/下载(无需登录)。
- 直接下载(同一 hash):baseUrl/api/public/dl/
3. 验证
- 创建后检查响应中的 path 是否与请求路径一致(如 /Qianlu/采购单-RFQ0311.xlsx)。若 path 异常(如 "s" 或与请求不符),说明使用了错误端点,须检查 URL 是否为 /api/share/<路径>(单数)。
- 可用 curl -s -o /dev/null -w "%{http_code}" 验证链接是否可下载(应返回 200)。注意:不要用 HEAD(curl -I)验证,该端点不支持 HEAD 方法。
4. 删除分享
- DELETE /api/share/,Header X-Auth: 。
按订单类型整理(如「对采购单进行整理」)
当用户提出对某类订单文件进行整理(例如「对采购单进行整理」)时,按以下流程执行,并在结束时明确告知:已整理到哪些路径、哪些文件无法整理及原因。
1. 确定订单类型与范围
- 从用户表述中识别订单类型名称(如「采购单」),及是否限定扩展名(默认可限定为 .xlsx 等常见表格格式,或不做扩展名限制)。
- 在 scope 内通过搜索或递归列出目录,收集名称包含该类型关键词且为文件的项(如名称含「采购单」)。只处理 scope 下的文件,不处理已在「类型/年份/月份」子目录下且已按规则命名的文件(可选:避免重复整理)。
2. 解析年月
- 对每个文件,尝试解析年份(YYYY)和月份(MM),用于生成目标路径 类型/YYYY/MM/(例如 采购单/2026/03/)。
- 优先从文件名解析:若文件名中存在连续 8 位数字且形如 YYYYMMDD(如 20260312),取前 4 位为年、第 5–6 位为月;若为 6 位 YYYYMM,则取前 4 位为年、后 2 位为月。
- 若无则用修改时间:使用该文件在 API 返回的 modified 字段(若存在),转换为本地或 UTC 的年份与月份。
- 若仍无法得到年月:该文件不移动,归入「无法整理」列表,原因写为「无法从文件名或修改时间解析年月」。
3. 创建目录结构
- 在 scope 下创建目录:<类型>/(如 Qianlu/采购单/2026/03/)。对涉及的所有 (YYYY, MM) 组合逐层创建,使用 POST /api/resources/<目录路径>/?override=false,路径末尾带 /,不传 Body。
4. 移动文件
- 目标路径为:<类型>/(如 采购单/2026/03/采购单-xxx-20260312.xlsx),须在 scope 内。
- FileBrowser 无「移动到新路径」的单次 API,采用:GET /api/raw/<原路径> 下载内容 → POST /api/resources/<目标路径>?override=true 上传 → DELETE /api/resources/<原路径> 删除原文件。若目标已存在且用户未要求覆盖,可视为「目标已存在,未移动」,归入无法整理并说明原因。
- 若下载、上传或删除任一步失败:该文件留在原位置,归入「无法整理」列表,原因写为「移动失败」并尽量附带接口返回信息(如权限不足、目标已存在等)。
5. 汇总并提示用户
- 已整理:列出已成功移动到 类型/年份/月份/ 下的文件及目标路径(如 采购单/2026/03/采购单-xxx.xlsx)。
- 未整理(留在原位置):列出每个文件的当前路径(或文件名)及原因,例如:
- 「无法从文件名或修改时间解析年月」
- 「目标路径已存在,未覆盖」
- 「移动失败:<简短错误原因>」
6. 约定
- 所有路径均在 scope 之下;类型子目录(如 采购单)建在 scope 根下,即 scope名/采购单/2026/03/。
- 若某文件已位于 类型/YYYY/MM/ 下且名称符合当前命名规则,可视为已整理,无需再次移动;若用户希望「重新整理」再按上述规则执行并覆盖或跳过由实现决定(建议默认不覆盖已存在目标,并归入无法整理说明原因)。
创建目录
POST /api/resources/<目录路径>/?override=false
X-Auth:
/,否则会创建成空文件而非目录。例如创建目录 Qianlu 用 Qianlu/,创建 Qianlu/子目录 用 Qianlu/子目录/。{}。<目录路径> 必须在 scope 之下。删除
DELETE /api/resources/<路径>
X-Auth:
删除文件或目录;路径必须在 scope 之下。
3. 用户管理(需管理员权限)
GET /api/users,Header 需带 X-Auth。POST /api/users,Body 为 JSON,包含 username、password(至少 12 位)、perm 等。PATCH /api/users/ 或按实际 API 约定。DELETE /api/users/。具体字段以实际 Swagger/文档为准;部署内可访问 http:// 查看(若已开启)。
4. 调用示例(curl)
凭证从环境变量读取,勿在脚本中写明文密码:
# 从 .env 或环境变量读取(FB_USER、FB_PASSWORD 勿提交到 Git)
BASE="${FB_BASE_URL:-http://127.0.0.1:9888}"
TOKEN=$(curl -s -X POST "$BASE/api/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$FB_USER\",\"password\":\"$FB_PASSWORD\",\"recaptcha\":\"\"}" \
| jq -r '.token')列根目录
curl -s -H "X-Auth: $TOKEN" "$BASE/api/resources?path=/"上传
echo "hello" | curl -s -X POST "$BASE/api/resources/hello.txt?override=true" \
-H "X-Auth: $TOKEN" -H "Content-Type: text/plain" --data-binary @-下载
curl -s -H "X-Auth: $TOKEN" "$BASE/api/raw/hello.txt"
5. 错误与注意
X-Auth 或 token 无效会返回 401。.env(且已加入 .gitignore)传递,不写入代码、不提交、不暴露。更多接口说明见 reference.md。