po-file-search
目录
功能介绍
po-file-search 是采购文件搜索 MVP 服务,用于让 OpenClaw 通过对话方式,从群晖 SMB 文件服务器中按文件夹名称和文件名称快速找到文件,并生成可发送给用户的下载链接。
核心链路:
群晖 SMB 共享目录
↓ 挂载到 Linux/macOS
手动或每日定时全量扫描文件名/文件夹名
↓
OpenClaw 服务器本地 SQLite/FTS 索引
↓
OpenClaw/HTTP API 搜索
↓
生成下载 token 和下载链接
↓
通过钉钉等渠道发送给用户重要原则:
- 搜索时查询本地 SQLite/FTS 索引,不依赖群晖搜索。
- 用户每次搜索时不重新扫描群晖。
- 当前暂行同步策略只保留每日低频全量同步和手动全量同步。
- 发送或下载阶段才读取群晖真实文件。
- 下载链接使用可配置的对外 IP/域名和端口,不使用
127.0.0.1发给用户。
当前已实现功能
- 跨平台系统识别:支持 Linux 和 macOS。
- 群晖 SMB 挂载:Linux 使用 CIFS;macOS 可复用 Finder 已挂载 SMB 共享。
- 子目录扫描:支持挂载共享目录后只扫描指定子目录。
- 本地索引:使用 SQLite + FTS5 保存文件元数据和搜索索引。
- 文件搜索:支持 CLI 和 HTTP API。
- 搜索结果数量配置:
max_results = 0表示返回全部。 - 搜索模式配置:支持智能、左包含、右包含、全包含、精准匹配。
- 下载链接:支持生成下载 token 和下载链接。
- 下载有效期配置:
token_ttl_minutes = 0表示永不过期。 - 每日定时全量同步:默认每天
23:23执行一次,可配置。 - 手动全量同步:管理员可随时执行全量同步。
- HTTP 服务:提供健康检查、搜索、生成链接、下载接口。
- 基础审计日志:记录搜索、生成链接、下载事件。
- 钉钉 webhook 骨架:可通过 webhook 发送链接消息。
- Docker 文件:提供
Dockerfile和docker-compose.yml。
运行环境
Linux 生产环境
- Python 3.9+
- SQLite FTS5
cifs-utils- 可访问群晖 SMB 服务
安装 CIFS:
sudo apt-get install -y cifs-utilsmacOS 开发环境
- Python 3.9+
- 系统自带
mount_smbfs - 可通过 Finder 或命令行访问群晖 SMB
macOS 推荐先用 Finder 挂载共享目录,再让程序复用 Finder 挂载路径。
配置文件参数说明
配置文件:
config.json示例:
{
"mounts": [
{
"name": "采购共享",
"server": "192.168.1.26",
"share": "X.artwork2",
"mount_point_linux": "/mnt/synology/purchase",
"mount_point_macos": "/Volumes/采购共享",
"username": "cg-name_search",
"password_env": "searchpassword",
"readonly": true,
"smb_version": "3.0"
}
],
"index_db": "./data/file_index.sqlite",
"scan_roots": [
{
"name": "采购共享/artwork",
"path_from_mount": "采购共享",
"relative_path": "artwork"
}
],
"ignored_dirs": ["@eaDir", "#recycle", ".snapshot"],
"max_results": 10,
"search_mode": "smart",
"server": {
"host": "0.0.0.0",
"port": 18765
},
"download": {
"base_url": "http://192.168.88.20:18765",
"token_ttl_minutes": 30
},
"dingtalk": {
"webhook_env": "DINGTALK_WEBHOOK"
},
"index": {
"auto_full_sync_enabled": true,
"full_sync_time": "23:23",
"full_sync_on_startup": false
},
"logging": {
"failure_log_file": "./logs/po-file-search-error.log"
}
}mounts
| 参数 | 必填 | 说明 |
|---|---|---|
name | 是 | 挂载名称,供 scan_roots[].path_from_mount 引用 |
server | 是 | 群晖 IP、主机名或域名 |
share | 是 | SMB 共享文件夹名,不是子目录 |
mount_point_linux | 是 | Linux 挂载点 |
mount_point_macos | 是 | macOS 挂载点 |
username | 是 | 群晖只读账号 |
password_env | 是 | 密码所在环境变量名,不是密码明文 |
readonly | 否 | 是否只读挂载,建议 true |
smb_version | 否 | SMB 协议版本,默认 3.0 |
scan_roots
| 参数 | 必填 | 说明 |
|---|---|---|
name | 是 | 扫描根名称,写入索引的 root_name |
path_from_mount | 否 | 引用 mounts[].name |
relative_path | 否 | 挂载目录下要扫描的子目录,空字符串表示扫描挂载根目录 |
path | 否 | 直接指定本地路径,用于测试或特殊场景 |
例如真实路径:
\\192.168.1.26\X.artwork2\artwork配置方式:
"share": "X.artwork2",
"relative_path": "artwork"搜索配置
| 参数 | 说明 |
|---|---|
max_results | 默认搜索结果数量;大于 0 表示最多返回 N 条,等于 0 表示返回全部 |
search_mode | 默认搜索模式,可被 CLI --mode 或 HTTP search_mode 覆盖 |
搜索模式:
| 模式 | 中文别名 | 含义 |
|---|---|---|
smart | 智能 | 智能搜索,先 FTS,再 LIKE/中文切片兜底 |
left_contains | 左包含 | 文件名或目录以关键词开头 |
right_contains | 右包含 | 文件名或目录以关键词结尾 |
contains | 全包含 | 文件名或目录包含关键词 |
exact | 精准匹配 / 精确匹配 | 文件名或目录完全等于关键词 |
HTTP 服务配置
| 参数 | 说明 |
|---|---|
server.host | HTTP 服务监听地址,生产建议 0.0.0.0 |
server.port | HTTP 服务监听端口,可配置 |
下载链接配置
| 参数 | 说明 |
|---|---|
download.base_url | 生成给用户访问的对外下载地址,可配置 IP 或域名 |
download.token_ttl_minutes | 下载链接有效期,单位分钟;大于 0 表示 N 分钟过期,等于 0 表示永不过期 |
注意:发给用户的下载链接不要使用 127.0.0.1。
钉钉配置
| 参数 | 说明 |
|---|---|
dingtalk.webhook_env | 钉钉 webhook 地址所在环境变量名 |
失败运行日志配置
当前运行日志只记录失败事件,不记录成功请求。
"logging": {
"failure_log_file": "./logs/po-file-search-error.log"
}会记录的失败事件包括:
- 挂载失败。
- 手动全量同步失败。
- 每日全量同步失败。
- HTTP API 参数错误。
- 生成下载链接失败。
- 下载 token 无效或过期。
- 下载文件不存在。
- 未处理异常。
日志格式为 JSON Lines,每行一条失败记录,包含时间、事件类型、错误类型、错误信息、上下文和异常堆栈。
索引同步配置
| 参数 | 说明 |
|---|---|
index.auto_full_sync_enabled | 是否启用每日定时全量同步 |
index.full_sync_time | 每日全量同步时间,格式 HH:MM,默认 23:23 |
index.full_sync_on_startup | 服务启动后是否立即执行一次全量同步 |
logging.failure_log_file | 失败运行日志文件路径,只记录失败事件 |
当前暂行策略:
- 删除后台增量同步。
- 每天
23:23做一次全量同步。 - 管理员可手动执行全量同步。
如何使用
1. 设置密码环境变量
password_env 填的是环境变量名,不是密码。
例如配置:
"password_env": "searchpassword"运行前设置:
export searchpassword='你的群晖密码'2. macOS 先人工挂载群晖
Finder 中访问:
smb://192.168.1.26/X.artwork2登录成功后,程序会自动复用 Finder 挂载路径。
3. 检测系统
python3 -m po_file_search --config config.json detect-os4. 检查或复用挂载
python3 -m po_file_search --config config.json mount5. 手动全量同步索引
python3 -m po_file_search --config config.json index6. 搜索文件
默认搜索:
python3 -m po_file_search --config config.json search 'DCC1039S.pdf'返回全部匹配:
python3 -m po_file_search --config config.json search 'DCC1039S.pdf' --limit 0指定搜索模式:
python3 -m po_file_search --config config.json search 'DCC1039S.pdf' --mode exact --limit 07. 启动 HTTP 服务
python3 -m po_file_search --config config.json serve后台启动示例:
nohup env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json serve \
> /tmp/po-file-search-server.log 2>&1 &HTTP API 使用
健康检查
curl http://192.168.88.20:18765/health搜索文件
curl -X POST http://192.168.88.20:18765/search_purchase_file \
-H 'Content-Type: application/json' \
-d '{"query":"DCC1039S.pdf","search_mode":"exact","limit":0}'参数:
| 参数 | 必填 | 说明 |
|---|---|---|
query | 是 | 搜索关键词 |
limit | 否 | 返回数量,0 表示全部,不传则使用 max_results |
search_mode | 否 | 搜索模式,不传则使用配置中的 search_mode |
mode | 否 | search_mode 的别名 |
user_id | 否 | 审计用用户 ID |
生成下载链接
curl -X POST http://192.168.88.20:18765/send_purchase_file \
-H 'Content-Type: application/json' \
-d '{"file_id":21559,"channel":"link","user_id":"test-user"}'参数:
| 参数 | 必填 | 说明 |
|---|---|---|
file_id | 是 | 搜索结果中的文件 ID |
channel | 否 | link 仅生成链接;dingtalk 通过 webhook 发送 |
recipient | 否 | 接收人或群 ID,审计用 |
user_id | 否 | 操作用户 ID,审计用 |
下载文件
浏览器打开返回的 download_url 即可下载。
LinuxOS 部署详细步骤
本节说明在 LinuxOS 上部署 po-file-search 的完整步骤。
1. 安装系统依赖
Debian / Ubuntu:
sudo apt-get update
sudo apt-get install -y python3 python3-venv python3-pip cifs-utils curlCentOS / Rocky Linux / RHEL:
sudo yum install -y python3 python3-pip cifs-utils curl说明:
| 依赖 | 用途 |
|---|---|
python3 | 运行程序 |
cifs-utils | 挂载群晖 SMB 共享目录 |
curl | 测试 HTTP API |
| SQLite FTS5 | Python 标准库 sqlite3 通常已包含,用于本地索引 |
检查 Python:
python3 --version2. 准备项目目录
进入项目目录:
cd /opt/po-file-search如果是从当前代码复制到 Linux,确保目录结构类似:
po-file-search/
README.md
config.example.json
po_file_search/
docs/
data/3. 准备配置文件
cp config.example.json config.jsonLinux 重点配置示例:
{
"mounts": [
{
"name": "采购共享",
"server": "192.168.1.26",
"share": "X.artwork2",
"mount_point_linux": "/mnt/synology/purchase",
"mount_point_macos": "/Volumes/采购共享",
"username": "cg-name_search",
"password_env": "searchpassword",
"readonly": true,
"smb_version": "3.0"
}
],
"scan_roots": [
{
"name": "采购共享/artwork",
"path_from_mount": "采购共享",
"relative_path": "artwork"
}
],
"server": {
"host": "0.0.0.0",
"port": 18765
},
"download": {
"base_url": "http://Linux服务器IP或域名:18765",
"token_ttl_minutes": 30
},
"index": {
"auto_full_sync_enabled": true,
"full_sync_time": "23:23",
"full_sync_on_startup": false
},
"logging": {
"failure_log_file": "./logs/po-file-search-error.log"
}
}注意:
share是 SMB 共享文件夹名,不是子目录。- 如果真实路径是
\192.168.1.26\X.artwork2rtwork,则: share = X.artwork2relative_path = artworkdownload.base_url必须配置为用户能访问的 Linux 服务器 IP 或域名,不要用127.0.0.1。
4. 设置群晖密码环境变量
如果配置里是:
"password_env": "searchpassword"则 Linux 上执行:
export searchpassword='你的群晖密码'如果使用 systemd 部署,建议放到环境文件,例如:
sudo mkdir -p /etc/po-file-search
sudo tee /etc/po-file-search/env >/dev/null <<'EOF'
searchpassword=你的群晖密码
EOF
sudo chmod 600 /etc/po-file-search/env5. 挂载群晖 SMB
方式 A:程序执行挂载,适合测试
预览挂载命令:
python3 -m po_file_search --config config.json mount --dry-run执行挂载通常需要 root 权限:
sudo -E python3 -m po_file_search --config config.json mount-E 用于保留 searchpassword 环境变量。
方式 B:系统负责挂载,推荐生产
生产环境更推荐用 /etc/fstab 或 systemd mount 先挂载群晖,然后程序只读访问挂载目录。
示例凭证文件:
sudo tee /etc/synology-credential >/dev/null <<'EOF'
username=cg-name_search
password=你的群晖密码
EOF
sudo chmod 600 /etc/synology-credential手动测试挂载:
sudo mkdir -p /mnt/synology/purchase
sudo mount -t cifs //192.168.1.26/X.artwork2 /mnt/synology/purchase -o credentials=/etc/synology-credential,ro,vers=3.0,iocharset=utf8检查挂载:
mountpoint -q /mnt/synology/purchase && echo mounted
ls -la /mnt/synology/purchase
ls -la /mnt/synology/purchase/artwork/etc/fstab 示例:
//192.168.1.26/X.artwork2 /mnt/synology/purchase cifs credentials=/etc/synology-credential,ro,vers=3.0,iocharset=utf8,_netdev,nofail 0 0加载 fstab:
sudo mount -a6. 手动全量同步索引
首次部署后建议先手动全量同步一次:
python3 -m po_file_search --config config.json index成功后输出类似:
{"indexed": 92108}7. 启动 HTTP 服务
前台启动:
python3 -m po_file_search --config config.json serve后台启动:
nohup env searchpassword='你的群晖密码' python3 -m po_file_search --config config.json serve > /tmp/po-file-search-server.log 2>&1 &健康检查:
curl http://Linux服务器IP或域名:18765/health预期返回:
{"ok": true}8. 搜索测试
CLI 搜索:
python3 -m po_file_search --config config.json search 'DCC1039S.pdf' --mode exact --limit 0HTTP 搜索:
curl -X POST http://Linux服务器IP或域名:18765/search_purchase_file -H 'Content-Type: application/json' -d '{"query":"DCC1039S.pdf","search_mode":"exact","limit":0}'9. 生成下载链接测试
将 file_id 替换为搜索结果中的 ID:
curl -X POST http://Linux服务器IP或域名:18765/send_purchase_file -H 'Content-Type: application/json' -d '{"file_id":21559,"channel":"link","user_id":"linux-test"}'然后用返回的 download_url 在浏览器中下载。
10. systemd 服务示例
创建服务文件:
sudo tee /etc/systemd/system/po-file-search.service >/dev/null <<'EOF'
[Unit]
Description=PO File Search Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/po-file-search
EnvironmentFile=/etc/po-file-search/env
ExecStart=/usr/bin/python3 -m po_file_search --config config.json serve
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF启动:
sudo systemctl daemon-reload
sudo systemctl enable po-file-search
sudo systemctl start po-file-search查看状态:
sudo systemctl status po-file-search
journalctl -u po-file-search -f停止:
sudo systemctl stop po-file-search11. Linux 部署常见问题
| 问题 | 可能原因 | 处理方式 |
|---|---|---|
mount: bad usage 或找不到 cifs | 未安装 cifs-utils | 安装 cifs-utils |
Permission denied | 挂载需要 root 权限 | 使用 sudo -E 或系统挂载 |
| 环境变量未设置 | password_env 指定的环境变量不存在 | export searchpassword=... 或 systemd EnvironmentFile |
| 下载链接打不开 | download.base_url 配成了 127.0.0.1 或防火墙未放行 | 改为服务器 IP/域名,开放端口 |
| 搜索不到新文件 | 本地索引未同步 | 手动执行 python3 -m po_file_search --config config.json index 或等待每日全量同步 |
| 容器内挂载失败 | Docker 默认无挂载权限 | 推荐宿主机挂载后 volume 只读映射 |
程序部署方式
方式一:本机直接运行
适合开发和 MVP 验证。
cp config.example.json config.json
export searchpassword='你的群晖密码'
python3 -m po_file_search --config config.json mount
python3 -m po_file_search --config config.json index
python3 -m po_file_search --config config.json serve方式二:后台运行
nohup env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json serve \
> /tmp/po-file-search-server.log 2>&1 &停止:
pkill -f 'python3 -m po_file_search --config config.json serve'方式三:Docker 部署
docker compose up -d --build推荐生产方式:宿主机挂载群晖 SMB,容器通过只读 volume 读取挂载目录。
方式四:Linux 生产建议
- 使用只读群晖账号。
- 使用 systemd/fstab 或运维脚本完成 SMB 挂载。
- 使用本服务运行 HTTP API。
- 通过
index.auto_full_sync_enabled和index.full_sync_time控制每日全量同步。 download.base_url配置为内网可访问 IP 或 HTTPS 域名。
索引同步策略
当前暂行方案:
每天 23:23 全量同步一次,可配置
不做后台增量同步
支持管理员手动全量同步原因:当前 92,108 个文件实测:
| 同步类型 | 耗时 |
|---|---|
| 全量同步 | 约 289 秒 |
| 无变化目录级增量同步 | 约 291 秒 |
结论:瓶颈主要是 SMB 目录遍历/扫描,不是 SQLite 写入。因此后台增量同步暂时删除,避免白天频繁压 NAS。
手动全量同步:
python3 -m po_file_search --config config.json index调整每日同步时间:
"index": {
"auto_full_sync_enabled": true,
"full_sync_time": "23:23",
"full_sync_on_startup": false
}关闭每日同步:
"index": {
"auto_full_sync_enabled": false,
"full_sync_time": "23:23",
"full_sync_on_startup": false
}常用命令
# 语法检查
python3 -m compileall po_file_search tests
# 检测系统
python3 -m po_file_search --config config.json detect-os
# 预览挂载命令
python3 -m po_file_search --config config.json mount --dry-run
# 确保挂载或复用已有挂载
python3 -m po_file_search --config config.json mount
# 手动全量同步索引
python3 -m po_file_search --config config.json index
# 搜索文件
python3 -m po_file_search --config config.json search '关键词'
# 搜索并返回全部结果
python3 -m po_file_search --config config.json search '关键词' --limit 0
# 指定搜索模式
python3 -m po_file_search --config config.json search '关键词' --mode exact
# 启动 HTTP API 服务
python3 -m po_file_search --config config.json serve
# 查看失败运行日志
tail -f logs/po-file-search-error.log
# Docker 启动
docker compose up -d --build项目结构
po-file-search/
README.md
AGENTS.md
config.example.json
requirements.txt
Dockerfile
docker-compose.yml
data/
.gitkeep
docs/
PRD.md
DatabaseSchema.md
po_file_search/
__init__.py
__main__.py
audit.py
cli.py
config.py
downloads.py
indexer.py
mounter.py
platforms.py
scheduler.py
searcher.py
sender.py
server.py
tests/
test_basic.py文档
- 产品需求文档:docs/PRD.md
- 数据库说明文档:docs/DatabaseSchema.md
注意事项
share必须是 SMB 共享文件夹名,不是子目录。- 如果要扫描共享文件夹下的子目录,用
scan_roots[].relative_path。 password_env是环境变量名,不是密码明文。- 下载链接发给用户时不要使用
127.0.0.1。 - macOS 本地调试推荐先用 Finder 挂载 SMB。
- 搜索结果中的真实
full_path只用于服务内部,不应直接暴露给普通用户。 - 当前钉钉能力是 webhook 消息骨架,不是完整钉钉内部应用文件上传。
- 当前不做后台增量同步。
后续增强
- 群晖 File Station API / Universal Search PoC,减少 SMB 扫描。
- 手动刷新指定目录。
- 业务上传事件触发局部刷新。
- 企业级权限系统接入。
- 钉钉内部应用文件上传/单聊发送。
- 文件正文搜索。
共享文件范围变更操作指南
当需要调整本服务允许搜索的群晖目录范围时,通常只需要修改 config.json 中的 scan_roots,不需要修改 server 和 share。
例如要从原范围:
\\192.168.1.26\X.artwork2\artwork变更为新范围:
\\192.168.1.26\X.artwork2\1.包材印刷品\01-包装印刷品对应关系是:
server = 192.168.1.26
share = X.artwork2
relative_path = 1.包材印刷品/01-包装印刷品注意:
share仍然是 SMB 共享文件夹名X.artwork2。- 子目录写到
scan_roots[].relative_path。 - Windows 路径中的
\在 JSON 配置里建议写成/。
推荐变更步骤
1. 修改 config.json
把原配置:
"scan_roots": [
{
"name": "采购共享/artwork",
"path_from_mount": "采购共享",
"relative_path": "artwork"
}
]改成:
"scan_roots": [
{
"name": "采购共享/包装印刷品",
"path_from_mount": "采购共享",
"relative_path": "1.包材印刷品/01-包装印刷品"
}
]不要把 share 改成完整路径。下面这种写法是错误的:
"share": "X.artwork2/1.包材印刷品/01-包装印刷品"2. 确认新目录存在
macOS:
ls -la "/Volumes/X.artwork2/1.包材印刷品/01-包装印刷品"LinuxOS:
ls -la "/mnt/synology/purchase/1.包材印刷品/01-包装印刷品"3. 清空旧索引
因为 scan_roots[].name 从 采购共享/artwork 改成了 采购共享/包装印刷品,旧 root_name 下的索引不会被新同步自动清理。
为了保证索引范围干净,推荐直接删除旧索引库:
rm -f data/file_index.sqlite data/file_index.sqlite-*4. 重新全量同步索引
python3 -m po_file_search --config config.json index成功后会输出类似:
{"indexed": 12345}5. 重启服务
如果使用 systemd:
sudo systemctl restart po-file-search如果手动后台运行:
pkill -f 'python3 -m po_file_search --config config.json serve'
nohup env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json serve \
> /tmp/po-file-search-server.log 2>&1 &6. 验证服务和搜索
健康检查:
curl http://你的服务器IP或域名:18765/health搜索验证:
python3 -m po_file_search --config config.json search '新目录中的文件关键词' --limit 10HTTP 搜索验证:
curl -X POST http://你的服务器IP或域名:18765/search_purchase_file \
-H 'Content-Type: application/json' \
-d '{"query":"新目录中的文件关键词","limit":10}'共享文件范围变更:macOS 与 LinuxOS 差异说明
本节补充实际变更共享范围时,macOS 和 LinuxOS 的操作差异。推荐在执行范围变更前先停止服务,避免 SQLite 索引库被运行中的服务进程占用。
通用变更流程
不论 macOS 还是 LinuxOS,推荐流程都是:
1. 停止 po-file-search 服务
2. 确认新目录在挂载路径下可访问
3. 修改 config.json 的 scan_roots
4. 清空旧 SQLite 索引文件
5. 手动执行一次全量同步
6. 启动服务
7. 健康检查、搜索验证、下载验证为什么要先停止服务
如果服务还在运行,可能持有旧的 SQLite 数据库文件。此时删除或重建索引,可能出现:
sqlite3.OperationalError: attempt to write a readonly database
sqlite3.OperationalError: disk I/O error因此变更范围前建议先停止服务。
macOS 操作步骤
1. 停止服务
如果是手动后台运行:
if [ -f /tmp/po-file-search-server.pid ]; then
kill $(cat /tmp/po-file-search-server.pid) 2>/dev/null || true
fi
pkill -f 'python3 -m po_file_search --config config.json serve' || true2. 确认 Finder/SMB 挂载
macOS 推荐先在 Finder 里连接:
smb://192.168.1.26/X.artwork2程序会复用 Finder 挂载路径,例如:
/Volumes/X.artwork2检查新目录:
ls -la "/Volumes/X.artwork2/1.包材印刷品/01-包装印刷品"如果刚调整过群晖权限但命令行看不到目录,请在 Finder 中断开 X.artwork2 后重新连接,再重试。
3. 修改 config.json
"scan_roots": [
{
"name": "采购共享/包装印刷品",
"path_from_mount": "采购共享",
"relative_path": "1.包材印刷品/01-包装印刷品"
}
]4. 清空旧索引
macOS 默认 zsh 对不存在的通配符会报错,所以推荐用 Python 删除:
python3 - <<'PY'
from pathlib import Path
for p in Path('data').glob('file_index.sqlite*'):
print('remove', p)
p.unlink()
PY不要使用不安全的通配符命令依赖,例如在 zsh 中直接执行:
rm -f data/file_index.sqlite data/file_index.sqlite-*当通配符没有匹配时可能报错。
5. 重新全量同步
/usr/bin/time -p env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json index示例结果:
{"indexed": 27471}
real 48.056. 启动服务
nohup env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json serve \
> /tmp/po-file-search-server.log 2>&1 &
echo $! > /tmp/po-file-search-server.pid7. 验证
健康检查:
curl http://192.168.88.20:18765/health搜索验证:
python3 -m po_file_search --config config.json search 'Thumbs.db' --mode exact --limit 5生成下载链接:
curl -X POST http://192.168.88.20:18765/send_purchase_file \
-H 'Content-Type: application/json' \
-d '{"file_id":8,"channel":"link","user_id":"scope-change-test"}'下载验证:
curl -L -o /tmp/test-download.pdf '返回的 download_url'
file /tmp/test-download.pdfLinuxOS 操作步骤
LinuxOS 的核心区别是:通常不依赖 Finder,而是由系统或程序挂载 SMB 到 mount_point_linux。
1. 停止服务
如果使用 systemd:
sudo systemctl stop po-file-search如果手动后台运行:
pkill -f 'python3 -m po_file_search --config config.json serve' || true2. 确认 SMB 已挂载
假设 Linux 挂载点为:
/mnt/synology/purchase检查挂载:
mountpoint -q /mnt/synology/purchase && echo mounted如果未挂载,可用系统挂载或程序挂载:
sudo -E python3 -m po_file_search --config config.json mount3. 确认新目录存在
ls -la "/mnt/synology/purchase/1.包材印刷品/01-包装印刷品"如果目录不存在,请检查:
- 群晖权限是否给到 Linux 使用的账号。
mounts[].share是否仍为X.artwork2。relative_path是否写错。- Linux 是否挂载了正确的群晖共享。
4. 修改 config.json
同 macOS:
"scan_roots": [
{
"name": "采购共享/包装印刷品",
"path_from_mount": "采购共享",
"relative_path": "1.包材印刷品/01-包装印刷品"
}
]5. 清空旧索引
Linux bash 下可以执行:
rm -f data/file_index.sqlite data/file_index.sqlite-*也可以使用跨平台 Python 方式:
python3 - <<'PY'
from pathlib import Path
for p in Path('data').glob('file_index.sqlite*'):
print('remove', p)
p.unlink()
PY6. 重新全量同步
/usr/bin/time -p env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json index7. 启动服务
systemd:
sudo systemctl start po-file-search或手动:
nohup env searchpassword='你的群晖密码' \
python3 -m po_file_search --config config.json serve \
> /tmp/po-file-search-server.log 2>&1 &8. 验证
健康检查:
curl http://Linux服务器IP或域名:18765/health搜索验证:
curl -X POST http://Linux服务器IP或域名:18765/search_purchase_file \
-H 'Content-Type: application/json' \
-d '{"query":"新目录中的文件关键词","limit":10}'生成下载链接验证:
curl -X POST http://Linux服务器IP或域名:18765/send_purchase_file \
-H 'Content-Type: application/json' \
-d '{"file_id":实际文件ID,"channel":"link","user_id":"scope-change-test"}'本次实际变更结果示例
本次从:
\\192.168.1.26\X.artwork2\artwork变更为:
\\192.168.1.26\X.artwork2\1.包材印刷品\01-包装印刷品最终配置:
"scan_roots": [
{
"name": "采购共享/包装印刷品",
"path_from_mount": "采购共享",
"relative_path": "1.包材印刷品/01-包装印刷品"
}
]重新索引结果:
indexed: 27471
耗时: 约 48 秒服务验证:
{"ok": true}下载链路验证:
HTTP/1.0 200 OK
Content-Type: application/pdf