基于 PicoClaw 的 QNAP QTS 专属 AI 管理助手
以 QPKG 插件形式安装,深度适配 QTS 5.x 非标准 Linux 环境。
QNAP QTS 是 QNAP 基于 Linux 内核深度定制的闭源系统,与标准 Linux 差异显著——没有 apt/yum,没有 systemctl,配置路径不一样,大量 QNAP 专有命令。通用 AI 对 QTS 了解有限,经常给出无效甚至危险的操作建议。
这个项目基于自己多年使用QNAP NAS的经验,从中获取一些积累,最终的代码实现、文档整理设计交给 AI Agent 完成。我们要做的是把控安全策略:要求 Agent 在 QNAP 这种非标准 Linux 环境中,以更安全、更稳定、更克制的方式运行,尽量遵循QNAP NAS系统的特有命令代码。
之前有一次郁闷的经历,曾经因为以为给 AI 足够高的系统权限,它可以更好管理系统。当 AI 获得权限的第一时间,为了测试拦截机制是否生效,执行了 rm -rf /,而那次拦截代码恰好有一个变量失效 —— 7T 数据就此消失,数据恢复历时一周。
这让我想起《三体》里章北海拿到"自然选择号"指挥权的第一时间,下令:前进四!
因此 qnap-agent 的核心目标不是让 AI "什么都能做",而是让 AI 在明确边界内做正确的事。
| 能力 | 说明 |
|---|---|
| 🧠 QTS 专属知识库 | 内置 QNAP 系统知识技能包,理解 QTS 与标准 Linux 的差异 |
| 📁 文件管理 | 共享文件夹的文件搜索、整理、批量操作、权限管理 |
| 🎬 媒体管理 | 影音文件分析、媒体库整理、格式识别、流媒体服务管理 |
| 🐳 Docker 管理 | 容器部署、状态查询、日志分析、Compose 项目管理 |
| ☁️ OpenList 网盘 | 40+ 存储源文件管理、直链获取、分享链接、离线下载、存储挂载 |
| 🔍 系统诊断 | QTS 日志分析、磁盘健康、内存/CPU 监控 |
| 🔒 命令安全沙箱 | 基于正则黑白名单拦截危险命令,防止误操作损坏系统 |
| 🗑️ 安全删除工具 | safe-rm.sh 将文件移至 @Recycle 回收站而非永久删除 |
| 📡 MCP 工具集成 | 通过 QNAP MCP Assistant 无需完整 Shell 权限即可安全操作 NAS |
| 💬 多渠道接入 | Web 界面(18800 端口)/ 微信 / QQ Bot / Telegram Bot |
| ⏰ 定时心跳巡检 | 每 30 分钟自动检查磁盘空间、容器状态、系统日志异常 |
| 🔄 持续学习 | Agent 将操作中学到的新知识自动整理为技能包,持续积累 |
| ♻️ 自升级机制 | 看门狗自动完成二进制升级与回滚,无需手动干预 |
| 项目 | 要求 |
|---|---|
| QNAP QTS 版本 | ≥ 5.0.0 |
| CPU 架构 | x86_64、arm64、armv7(含 arm-x31 / arm-x41) |
| 内存 | 建议 ≥ 2GB 可用 |
| 存储空间 | ≥ 200MB(安装路径) |
| 网络 | 需能访问外部 LLM API |
| 可选依赖 | Container Station(使用 Docker 管理功能时需要) |
.qpkg 文件.qpkg 文件http://NAS-IP:18800配置文件位于 ${QPKG_ROOT}/workspace/config.json,安装时由模板自动生成,填写 API Key 后即可使用。
推荐的 LLM 服务提供商:
| 提供商 | 推荐模型 | api_base |
|---|---|---|
| 火山引擎(豆包) | doubao-seed-1.6、doubao-seed-1.6-flash |
https://ark.cn-beijing.volces.com/api/v3 |
| 通义千问(阿里) | qwen3-max、qwen3-plus、qwen3-flash |
https://dashscope.aliyuncs.com/api/v1 |
| DeepSeek(深度求索) | deepseek-chat、deepseek-reasoner |
https://api.deepseek.com |
| 月之暗面 Kimi | kimi-k2.5、kimi-k2-thinking |
https://platform.moonshot.cn/api/v1 |
| 智谱 GLM | glm-5、glm-4.6、glm-4-flash |
https://open.bigmodel.cn/api/paas/v4 |
| 文心一言(百度) | ernie-4.5、ernie-3.5、ernie-speed |
https://qianfan.baidubce.com/v2 |
| MiniMax | MiniMax-M2.7、abab6.5s-chat |
https://api.minimaxi.com/v1 |
| 腾讯混元 | hunyuan-large、hunyuan-turbo |
https://hunyuan.tencentcloudapi.com/v1 |
| OpenAI | gpt-4o、gpt-4o-mini |
https://api.openai.com/v1 |
| Anthropic Claude(via OpenRouter) | anthropic/claude-sonnet-4-5 |
https://openrouter.ai/api/v1 |
详细配置说明参考 PicoClaw 文档
⚠️ 默认封闭原则:安装即锁,按需开锁
安装完成后,Agent 默认没有系统访问权限:
${QPKG_ROOT}/workspace/ 工作目录(沙箱内)/share/ 共享文件夹、/etc/config/ 系统配置(未授权前)当你需要 Agent 管理共享文件夹时,需要在 config.json 的 custom_allow_patterns 中手动添加对应路径的授权。你也可以直接命令 Agent 开放对应文件夹权限,Agent 会告知你具体需要修改的配置。
这样设计的目的:NAS 上的数据往往不可替代,"默认开放"会让你在还没搞清楚 Agent 能做什么之前,就已经暴露了全部数据。
QNAP 官方推出了 MCP Assistant QPKG,提供基于标准 MCP 协议的 NAS 管理接口。QNAP Agent 已完整集成对 MCP 工具的调用能力。
| 方式 | 权限要求 | 安全性 | 适用场景 |
|---|---|---|---|
| MCP 工具调用 | 只需 Token,无需开放 Shell | ✅ 高,细粒度权限 | 日常查询、文件管理、用户管理 |
| 直接 Shell 命令 | 需要开放沙箱路径 | ⚠️ 取决于配置 | Docker 管理、复杂脚本 |
通过 MCP,Agent 可以在不需要完整 Shell 权限的情况下完成绝大多数日常任务,包括:
在 NAS 的 App Center 中加入 Beta 测试计划,搜索并安装 MCP Assistant
QTS 5.2.0 版本需从官网手动下载
.qpkg后通过 App Center 手动安装。
打开 MCP Assistant → Credentials → Create 创建 Token
qnap-agentSecret Key记录 Token 和 NAS 局域网 IP,直接在对话框中告诉 Agent:
帮我配置 MCP Assistant 连接,NAS IP 是 192.168.x.x,Token 是 xxxx
Agent 会读取内置的 QNAP MCP 技能文档,无需重启 Agent 即可使用。
安全提示: Token 代表完整用户权限,请勿将其写入代码仓库或公开场合。MCP 服务使用 HTTP 明文(8442 端口),建议仅在局域网内使用。
配置完成后,向 Agent 提问即可,指明以后调用QNAP MCP工具操作:
"帮我看看 NAS 目前磁盘用了多少?"
"在 Public 文件夹里有没有叫'发票'的文件?"
"最近有没有系统错误日志?"
"现在哪个进程 CPU 占用最高?"
详细的工具文档和调用规范见
skills/qnap-mcp/SKILL.md
QNAP Agent 已完整集成对 OpenList(AList 社区分支)的 HTTP API 调用能力,通过内置的 qnap-openlist 技能包实现对远程网盘、云盘聚合站点的完整文件管理。
| 方式 | 适用场景 | 优势 |
|---|---|---|
| OpenList API 调用 | 管理网盘聚合站、远程云盘 | ✅ 支持 40+ 存储源(阿里云盘、百度网盘、OneDrive、Google Drive、Quark 等) |
| MCP 工具调用 | 管理 QNAP 本地共享文件夹 | ✅ 细粒度权限、无需开放 Shell |
| 直接 Shell 命令 | 复杂脚本、Docker 管理 | ⚠️ 取决于沙箱配置 |
通过 OpenList,Agent 可以跨多个云盘统一管理文件,包括:
首次使用时,直接告诉 Agent 你的 OpenList 实例信息:
帮我配置 OpenList 连接,地址是 http://192.168.x.x:5244,用户名 admin,密码 xxx
Agent 会执行 login 命令并将凭据保存至 skills/qnap-openlist/openlist-config.json。后续所有操作无需重复认证。
配置完成后,可以直接向 Agent 下达网盘管理指令:
"在阿里云盘里有没有'发票'相关的文件?"
"帮我把 /Quark/report。pdf 复制到 /Backup/ 目录"
"给 /Aliyundrive/photos 目录下的所有 .jpg 文件创建下载直链"
"搜索所有网盘中关键词为'合同'的文件"
详细的命令参考和最佳实践见
skills/qnap-openlist/SKILL.md
执行删除操作时,Agent 优先使用 tools/safe-rm.sh 将文件移至共享文件夹的 @Recycle 回收站,而非永久删除。删除后可通过 File Station 界面恢复文件。
使用安全删除前,需要为共享文件夹开启回收站功能:
控制台 → 共享文件夹 → 编辑每个共享文件夹 → ☑️ 启用回收站
看门狗(watchdog.sh)每 5 分钟检查 update/ 目录:
.tar.gz、.zip)和直接二进制文件两种投放方式memory/ 目录完整保留)默认不开启自动检查更新。 你可以直接让 Agent 检查更新:
"帮我检查一下 qnap-agent 有没有新版本"
Agent 在执行操作前会优先查阅技能库,确保在 QTS 非标准环境中使用正确的命令和安全的操作方式。
| 技能 | 覆盖内容 |
|---|---|
qnap-system |
QTS 与标准 Linux 差异、QNAP 专有命令、路径约定 |
qnap-storage |
存储池、RAID、逻辑卷、磁盘空间分析 |
qnap-raid |
RAID 故障排查、降级恢复、磁盘更换流程 |
qnap-docker |
Container Station、容器管理、Compose 项目 |
qnap-media |
媒体文件分析、Plex/Emby/Jellyfin、Arr 全家桶 |
qnap-network |
网络诊断、端口查询、Windows 11 SMB 兼容性 |
qnap-security |
安全加固、Deadbolt 勒索病毒应急处理 |
qnap-backup |
HBS3、快照策略、3-2-1 备份原则 |
qnap-ssl |
Let's Encrypt 证书申请、stunnel 部署 |
qnap-plugins |
ZeroTier、Tailscale、OpenList、NPS 等第三方插件 |
qnap-mcp |
MCP Assistant 安装配置、24 个工具完整文档 |
qnap-openlist |
OpenList 网盘 API 集成、文件管理、分享、离线下载、存储管理 |
qnap-forbidden |
绝对禁止操作清单,防止误操作损坏系统 |
qnap-learned-* |
Agent 自动积累的使用经验(持续增长) |

Go语言开发的定时任务集中调度和管理系统, 用于替代Linux-crontab
conf\gocron.db,新版本数据库在安装目录下data\gocron.db⚡️ 高性能:基于 Go 语言开发,性能卓越,资源占用低
🎯 易于使用:Web 界面管理,简单直观,无需复杂配置
🔐 安全可靠:支持双因素认证(2FA)和 TLS 双向认证
📊 日志管理:完善的任务执行日志,支持自动清理和归档
🌐 分布式:支持多节点部署,任务分发执行
🔔 通知提醒:任务执行失败时支持多种方式通知

在QNAP系统,通过App Center手动安装 .qpkg 后辍程序。
QuMagie 版本 v2.4.0 支持了人脸识别元数据的备份和恢复,但目前每次备份仍需通过网页端手动操作。
为了简化这一过程,我编写了一个基于 QuMagie 备份程序代码的自定义备份命令工具。这款工具能够自动化备份操作,不再需要每次都手动进行备份。
此命令工具是基于QuMagie安装目录的CLI文件 qumagie/v2.4.0/cli/qm_export 提取的相关运行命令,不会对原文件进行更改。
在之前的文章中,我介绍过通过备份 MySQL 相册数据 S01 库来实现人脸识别数据的备份。在 QTS 旧版本中,这种方法能够正常导入和识别。然而,在 QTS 5.0 及以上版本的更新,系统会自动重新索引数据,导致已导入的数据丢失,并且人脸识别数据被重新识别。
这次 QuMagie 新发布的版本采用了新的备份原理:将每张图片或视频的元数据保存为 JSON 文件。每次备份时,系统会生成一个对应的 JSON 文件,并将其存储在照片文件夹下的隐藏目录 . @__thumb 中,文件名与照片或视频文件名一致,后缀为 .json。这个 JSON 文件包含了照片和视频的详细元数据、相册 ID、人脸识别信息等重要数据。
每个备份的 JSON 文件都包含了与图片或视频相关的所有元数据。以下是一个 JSON 文件的示例:
{
"MediaType": "photo",
"Path": "/share/Photo/全家福/01.jpg",
"Title": "01 (17)",
"Comment": "null",
"Keywords": "null",
"ColorLevel": "0",
"Longitude": "null",
"Latitude": "null",
"Time": "2022-07-15 18:30:56",
"Favorite": "0",
"Rating": "0",
"Objects": [
{
"object": {
"id": "k2jlff",
"name": "Wedding"
}
},
{
"object": {
"id": "GtGVc0",
"name": "Person"
}
},
{
"object": {
"id": "tCyPUP",
"name": "Clothing"
}
},
{
"object": {
"id": "kwg2xK",
"name": "Wedding dress"
}
},
{
"object": {
"id": "bdoUmX",
"name": "Bride"
}
}
],
"Faces": [
{
"face": {
"name": "爸爸",
"FaceId": "HmPbzl",
"X": "201",
"Y": "105",
"Width": "136",
"Height": "152",
"GroupId": "cTinsP",
"iFaceCover": "M92WZX"
}
},
{
"face": {
"name": "妈妈",
"FaceId": "tu1TsA",
"X": "295",
"Y": "285",
"Width": "121",
"Height": "160",
"GroupId": "TGcDVc",
"iFaceCover": "t0Ys2S"
}
}
],
"Albums": [],
"Qtag": "32febe21201f4fbfb94d02b58d15b3972ec9d78803e5",
"DataVersion": "1.0"
}
将qumagie-backup.sh文件上传到你的 QNAP 设备中,并赋予0755系统权限。
编辑qumagie-backup.sh代码,填入相关的备份用户名以及保存地址。
关键数据是第10-13行
export_type="metadata"
可选:metadata ,仅元数据。表示从帐户导出元数据(例如相册、标签、人物等)
可选:full,文件和元数据。从帐户导出媒体文件和元数据(例如相册、标签、人物等)
target_folder="备份/照片备份/QuMagie"
备份路径,是在/share/目录下的文件夹,所以前戳不需要再加/share/路径
uname="admin"
当前用户名,如果是最高权限管理员,可以备份其他用户的数据。
password=""
可选密码。为空则密码为系统默认`qnapqnap`,如果这里设置为`123456`,则密码为`qanpqnap123456`
[阿里云盘] https://www.alipan.com/s/T1LGsXY4P4d


QuFirewall 是 QNAP NAS 设备上的防火墙功能,用于管理网络流量、控制数据包的流向和访问权限。在启用 QuFirewall 防火墙时,默认不会存在开放所有端口的规则,以提高网络安全性。
☑️ - 接口[ALL] - 服务端口[任何] - 协议[任何] - 来源[任何] - 权限[允许]
因为这样的规则将导致防火墙不再限制任何端口的流量,仅进行一些基础的安全防护。例如,在指定时段内多次尝试登录失败时,系统将自动阻止恶意 IP 地址,提高对 SSH、FTP、HTTP/HTTPS 等服务的破解抵抗能力。
在大局域网中,NAS 设备相对较为安全。但在公网环境下,用户可能希望开放部分服务端口以供外部访问,同时又需要限制不必要的 IP 段的扫描。这时可以配置 QuFirewall 仅允许来自中国的流量,以有效保护免受互联网上的恶意扫描攻击。
当用户使用 ZeroTier、Tailscale 等服务时,它们通常会创建虚拟网络设备。由于 QNAP 防火墙无法识别第三方创建的虚拟网络设备,导致流量无法通过这些设备进入 NAS,只能从 NAS 流出。这可能导致 NAS 可以 ping 通其他设备,但其他设备无法 ping 通 NAS 的 IP。
QNAP 无法识别虚拟网络设备的情况下,可能导致 NAS 无法建立到虚拟网络的双向通信。这是因为防火墙默认不会包含虚拟设备的规则,导致进入 NAS 的流量被阻止,仅有流出的权限。
为了解决虚拟网络设备流量无法进入 NAS 的问题,可以使用 Linux 系统命令 iptables 手动配置防火墙规则。当启用 QuFirewall 防火墙时,系统会自动创建一个名为 QUFIREWALL 的链,用于配置防火墙策略。通过运行命令 可以查看当前防火墙规则。iptables -L QUFIREWALL -v
首先要查看虚拟网络设备名,ZeroTier 创建的设备名是 ztfp6pggry
当ZeroTier加入第二个Network ID后,会新增加类似ztrf2u52bz的名字,以zt开头的设备,这时就存在多个虚拟网络设备。
第二个命令可以查找以zt开头的设备名字
ip link show
ip link show | awk -F'[[:space:]]|:' '/zt/ && NF>2 {print $3}'
要手动添加虚拟网络设备,可以使用以下命令:
iptables -I QUFIREWALL 1 -i ztfp6pggry -j ACCEPT
也可以使用下面代码,避免多次运行导致规则列表中出现冗余的重复规则
iptables --check QUFIREWALL -i ztfp6pggry -j ACCEPT || iptables -I QUFIREWALL 1 -i ztfp6pggry -j ACCEPT
这将允许虚拟网络设备 ztfp6pggry 的所有流量通过QUFIREWALL防火墙。
运行可以查看数字部分(如 pkts bytes),表示有多少数据包和字节数通过该规则,如果这个数值不断变大,表示该设备有流量通过,证明我们说的这个设备已经被系统防火墙接纳。 iptables -L QUFIREWALL -v
以下是运行 的示例输出:iptables -L QUFIREWALL -v
Chain QUFIREWALL (1 references)
pkts bytes target prot opt in out source destination
250 85642 ACCEPT all -- ztfp6pggry any anywhere anywhere
0 0 ACCEPT all -- docker0 any anywhere anywhere
0 0 ACCEPT all -- lxdbr0 any anywhere anywhere
0 0 NFLOG all -- !lo any anywhere anywhere match-set PSIRT.ipv4 src nflog-prefix "RULE=4 ACT=DROP"
48 21272 ACCEPT all -- br0 any 192.168.1.0/24 anywhere
9 456 ACCEPT all -- !lo any anywhere anywhere -m geoip --source-country CN
18 5684 NFLOG all -- !lo any anywhere anywhere nflog-prefix "RULE=15 ACT=DROP"
18 5684 NFLOG all -- !lo any anywhere anywhere nflog-prefix "RULE=15 ACT=DROP" nflog-group 1
18 5684 DROP all -- !lo any anywhere anywhere
如果需要删除已添加的虚拟网络设备,可以使用以下命令:
iptables -D QUFIREWALL -i ztfp6pggry -j ACCEPT
ZeroTier是一款异地组网工具,能够将多个网络设备连接到一个虚拟网络中,通过局域网IP即可轻松访问所有服务。
ZeroTier builds modern, secure multi-point virtual networks, connecting peer-to-peer networks and multi-cloud mesh infrastructure.
在QNAP系统,通过App Center手动安装 .qpkg 后辍程序。

Delete the Live Photo MOV file that corresponds to a non-existent Live photo.
#!/bin/bash
DIR_PATH="/share/Photo/手机相册备份/"
FFPROBE_PATH="/share/CACHEDEV1_DATA/.qpkg/MediaSignPlayer/CodexPackExt/static/bin/ffprobe"
SHORT_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/find-5s-mov.short_videos.txt"
ERROR_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/find-5s-mov.ERROR_videos.txt"
PROCESSED_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/processed_videos.txt"
GREEN='\033[32m' # 设置绿色文本颜色
RED='\033[31m' # 设置红色文本颜色
NC='\033[0m' # 恢复默认文本颜色
# 创建 processed_videos.txt 文件如果不存在
touch "$PROCESSED_VIDEOS_FILE"
# 设置是否已跳过检测文件的标志
is_skipped=false
# 使用 while read 读取 find 命令的输出,并用双引号包裹变量,以处理含有空格的文件名和路径
find "$DIR_PATH" \( -iname "*.mov" -o -iname "*.mp4" \) ! -path "*/@Recycle/*" ! -path "*/.@__thumb/*" -print0 | while IFS= read -r -d '' mov_file; do
if grep -Fxq "$mov_file" "$PROCESSED_VIDEOS_FILE"; then
# 视频文件已经处理过,跳过检测并提示
if ! $is_skipped; then
echo "正在跳过已检测文件..."
is_skipped=true
fi
continue
fi
if [ ! -f "${mov_file%.*}.JPG" ] && [ ! -f "${mov_file%.*}.jpg" ] && [ ! -f "${mov_file%.*}.HEIC" ] && [ ! -f "${mov_file%.*}.heic" ]; then
output="$("$FFPROBE_PATH" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$mov_file" 2>&1)"
# 逐行检查输出内容,找到有效的时长信息
duration=""
while IFS= read -r line; do
# 判断该行是否为数字(时长信息)
if [[ "$line" =~ ^[0-9]+\.[0-9]+$ ]]; then
duration="$line"
break
fi
done <<< "$output"
# 判断是否成功获取到时长信息
if [[ -n "$duration" ]]; then
if [ "$(echo "$duration < 5" | busybox bc)" -eq 1 ]; then
echo -e "${GREEN}$mov_file - $duration${NC}" # 符合条件,显示绿色
echo "rm \"$mov_file\"" >> "$SHORT_VIDEOS_FILE"
else
echo "$mov_file - $duration" # 不符合条件,显示正常颜色
fi
else
echo -e "${RED}$mov_file - 错误的视频文件${NC}" # 无法获取时长的视频,显示红色
echo "rm \"$mov_file\"" >> "$ERROR_VIDEOS_FILE"
fi
# 将处理过的视频文件路径添加到 processed_videos.txt 中
echo "$mov_file" >> "$PROCESSED_VIDEOS_FILE"
fi
done
echo -e "\033[32m完成!\033[0m"
iPhone的Live Photo照片由一张照片+一个小于5秒的MOV视频组成。
通过工具或者手机App将iPhone照片上传到QNAP里,会自动分解成2个文件。
当在QNAP中,通过QuMagie AI相册删除Live Photo照片,系统仅仅删除了照片文件本身,配套的Live Photo MOV文件还保留。
这个脚本的目的是搜索同名的图片是否存在Live Photo MOV文件,如果存在,则跳过检测,因为Live Photo通常包含一个MOV视频文件和一个同名的JPG或HEIC图像文件。如果只有视频文件而没有图片文件,则检测视频的时长是否小于5秒,小于5秒则表示这个视频不是必须的,可以删除。
具体来说,这段代码的执行过程如下:
将目录路径"/share/Photo/手机相册备份/"和ffprobe程序路径"/share/CACHEDEV1_DATA/.qpkg/MediaSignPlayer/CodexPackExt/static/bin/ffprobe"分别赋值给变量DIR_PATH和FFPROBE_PATH。
将空字符串的内容写入名为"short_videos.txt"的文件。
使用"find"命令在指定目录下查找所有扩展名为.mov的文件,同时使用"! -path"参数排除掉包含字符串"@Recycle"和".@__thumb"的文件夹。然后使用一个for循环遍历所有查找到的视频文件。
使用if条件语句判断视频文件是否存在与其同名的JPG或HEIC格式的图片文件。如果不存在,则执行以下步骤:
使用ffprobe程序获取视频文件的时长。
判断视频时长是否小于5秒,如果小于5秒,则将该视频文件记录到输出文件find-5s-mov.shshort_videos.txt中,并标记为绿色。
对于无法获取时长的视频文件(例如由于文件格式错误等原因),将其记录到输出文件find-5s-mov.ERROR_videos.txt中,并标记为红色。
用这个代码的前提是已经安装CAYIN MediaSign Player,并且购买了11.9USD的H.265授权。
其中文件short_videos.txt里面是搜索到的MOV文件绝对路径,为了安全起见,可以手动查看生成的文件列表是否正确,查看对应MOV文件是否有同名的JPG/HEIC照片,如果没有,证明生成的文件是正确的。
对于无法获取时长/损坏/不可识别的视频文件,会在窗口显示红色文字,并且输出到find-5s-mov.ERROR_videos.txt中,可以手动查看该文件或删除。
脚本会保存已经检测过的视频文件名,下次运行会跳过这些文件,检测新的文件。
之后在shell里运行 short_videos.txt 里面的代码即可删除对应MOV文件。
A file list program that supports multiple storage, powered by Gin and Solidjs.
一款支持多种网络存储、挂载本地存储、阿里云盘、百度网盘、OneDrive、Google Drive 等,支持网页浏览和 WebDAV 的文件列表程序。
| 文件名 | 对应内核 |
|---|---|
| x86_64 | linux-amd64 & x86_64 |
| arm_64 | linux-arm64 |
| arm-x41 | linux-musl-amd64 |
在QNAP系统,通过App Center手动安装 .qpkg 后辍程序。
| 存储类型 | 列出文件 / 文件夹 | 下载文件 / 创建目录 / 重命名 / 移动 | 复制 | 上传文件/文件夹 |
|---|---|---|---|---|
| 本地存储 | ✅ | ✅ | ✅ | ✅ |
| 阿里云盘 | ✅ | ✅ | ✅ | ✅ |
| Onedrive | ✅ | ✅ | ✅ | ✅ |
| 天翼云盘 | ✅ | ✅ | ✅ | ✅ |
| GoogleDrive | ✅ | ✅ | ❌ | ✅ |
| 123pan | ✅ | ✅ | ❌ | ✅ |
| FTP | ✅ | ✅ | ❌ | ✅ |
| SFTP | ✅ | ✅ | ❌ | ✅ |
| PikPak | ✅ | ✅ | ✅ | ✅ |
| S3 | ✅ | ✅ | ✅ | ✅ |
| USS | ✅ | ✅ | ✅ | ✅ |
| WebDAV | ✅ | ✅ | ✅ | ✅ |
| Teambition | ✅ | ✅ | ✅ | ✅ |
| 分秒帧 | ✅ | ✅ | ✅ | ✅ |
| 和彩云 | ✅ | ✅ | ✅ | ✅ |
| YandexDisk | ✅ | ✅ | ✅ | ✅ |
| 百度网盘 | ✅ | ✅ | ✅ | ✅ |
| 夸克网盘 | ✅ | ✅ | ✅ | ✅ |
| 类型 | 配置 |
|---|---|
| 默认用户名 | admin |
| 默认密码 | 123456 |
| 访问Url | http[s]://localhost:5244 |
| webdav 用户名 | 同上 |
| webdav 密码 | 同上 |
| webdav Url | http[s]://localhost:5244/dav/ |

$comment 评论结构
$post_name 被评论的文章
$bark_key bark token
$bark_icon bark 推送图标
$bark_group bark 群组
$bark_goto_url bark 文章链接
$bark_sound bark 推送声音
$bark_archive bark 保存信息 1-启用 0-停用 启用后客户端自动保存推送信息
$isMyself 检测作者ID 1-启用 0-停用 启用后当评论者为 $customName 时不通知
$customName 作者评论ID 如果此值为空,则停用检测
$bark_key = ""里面
编辑主题目录下的functions.php,在最后一行加入以下内容:
/**
* WordPress Bark 推送评论通知
* Comment to Bark for WordPress
* 作者bbis
* 版本1.0
* 博客 https://cheen.cn
*
* $comment 评论结构
* $post_name 被评论的文章
* $bark_key bark token
* $bark_icon bark 推送图标
* $bark_group bark 群组
* $bark_goto_url bark 文章链接
* $bark_sound bark 推送声音
* $bark_archive bark 保存信息 1-启用 0-停用 启用后客户端自动保存推送信息
* $isMyself 检测作者ID 1-启用 0-停用 启用后当评论者为 $customName 时不通知
* $customName 作者评论ID 如果此值为空,则停用检测
*
**/
function bark_push_msg($comment, $post_name)
{
$bark = "https://api.day.app/";
$bark_key = "********";
$bark_icon = "";
$bark_group = "Blog";
$bark_goto_url = get_permalink( $comment->comment_post_ID );
$bark_sound = "gotosleep";
$bark_archive = "1";
$isMyself = "1";
$customName = "admin";
if($isMyself == '1') {
if (!empty($customName)) {
if ($comment->comment_author == $customName) {
return $comment;
}
} elseif ($comment->comment_author == 1) {
return $comment;
}
}
$title = "博客收到了新的评论";
$message = $comment->comment_author . "在『 $post_name 』评论:\n" . $comment->comment_content;
$postdata = array(
'title' => $title,
'body' => $message
);
!empty($bark_icon) ? $postdata["icon"] = $bark_icon : "";
!empty($bark_group) ? $postdata["group"] = $bark_group : "";
!empty($bark_archive) ? $postdata["isArchive"] = $bark_archive : "";
!empty($bark_sound) ? $postdata["sound"] = $bark_sound : "";
!empty($bark_goto_url) ? $postdata["url"] = $bark_goto_url : "";
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($postdata)
),
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false
)
);
$context = stream_context_create($opts);
$result = file_get_contents($bark.$bark_key, false, $context);
return $comment;
}
add_action('comment_post', 'comment_bark_notify');
function comment_bark_notify($comment_id)
{
$comment = get_comment($comment_id);
bark_push_msg($comment, get_the_title($comment->comment_post_ID));
}
]]>