diff --git a/skill-workshop/proposals.json b/skill-workshop/proposals.json index b47c977..7a92b53 100644 --- a/skill-workshop/proposals.json +++ b/skill-workshop/proposals.json @@ -1 +1 @@ -{"schema":"openclaw.skill-workshop.proposals-manifest.v1","updatedAt":"2026-07-06T09:04:18.526Z","proposals":[{"id":"f-download-sorter-20260706-902cc0d5aa","kind":"create","status":"applied","title":"Create f-download-sorter","description":"整理 /mnt/f 下下载的视频文件:扫描→清垃圾→按规则归档到7个大类目录","skillName":"f-download-sorter","skillKey":"f-download-sorter","createdAt":"2026-07-06T09:03:54.941Z","updatedAt":"2026-07-06T09:04:18.513Z","scanState":"clean"},{"id":"jellyfin-nfo-builder-20260701-6434352e0d","kind":"create","status":"pending","title":"Create jellyfin-nfo-builder","description":"为剧集整理统一文件名、生成缺失的 Jellyfin .nfo 剧集元数据","skillName":"jellyfin-nfo-builder","skillKey":"jellyfin-nfo-builder","createdAt":"2026-07-01T23:52:24.406Z","updatedAt":"2026-07-01T23:52:24.406Z","scanState":"clean"},{"id":"weekly-report-g5-20260626-7595273f1d","kind":"create","status":"applied","title":"Create weekly-report-g5","description":"维云智造G5周报生成:整理每日工作→多段邮件(纯文本+HTML含签名图)→存入钉邮草稿箱","skillName":"weekly-report-g5","skillKey":"weekly-report-g5","createdAt":"2026-06-26T00:46:22.478Z","updatedAt":"2026-06-26T00:46:35.812Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-0fc374efd7","kind":"update","status":"pending","title":"Update calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T03:23:27.062Z","updatedAt":"2026-06-24T03:23:27.062Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-cdbeb219a3","kind":"update","status":"applied","title":"Update calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T03:03:28.166Z","updatedAt":"2026-06-24T03:03:30.915Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-a441798af9","kind":"create","status":"applied","title":"Create calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T02:29:02.278Z","updatedAt":"2026-06-24T02:29:27.227Z","scanState":"clean"},{"id":"calibre-title-cleaner-20260624-3760b64e8b","kind":"create","status":"applied","title":"Create calibre-title-cleaner","description":"清洗 Calibre 书库中损坏的 txt 文档书名(HTML标签/长文本/乱码/路径超限修复)","skillName":"calibre-title-cleaner","skillKey":"calibre-title-cleaner","createdAt":"2026-06-24T01:10:56.296Z","updatedAt":"2026-06-24T01:13:39.670Z","scanState":"clean"},{"id":"dianping-review-20260611-d402abec10","kind":"create","status":"pending","title":"Create dianping-review","description":"通过大众点评搜索查询餐厅、老店、美食推荐和评论","skillName":"dianping-review","skillKey":"dianping-review","createdAt":"2026-06-11T23:50:15.731Z","updatedAt":"2026-06-11T23:50:15.731Z","scanState":"clean"}]} +{"schema":"openclaw.skill-workshop.proposals-manifest.v1","updatedAt":"2026-07-07T12:14:43.092Z","proposals":[{"id":"jav-media-sorter-20260707-b1f90c8a4d","kind":"create","status":"pending","title":"Create jav-media-sorter","description":"JAV 视频整理:组装文件、按演员分组、刮削 nfo 元数据与封面图","skillName":"jav-media-sorter","skillKey":"jav-media-sorter","createdAt":"2026-07-07T12:14:43.074Z","updatedAt":"2026-07-07T12:14:43.074Z","scanState":"clean"},{"id":"f-download-sorter-20260706-902cc0d5aa","kind":"create","status":"applied","title":"Create f-download-sorter","description":"整理 /mnt/f 下下载的视频文件:扫描→清垃圾→按规则归档到7个大类目录","skillName":"f-download-sorter","skillKey":"f-download-sorter","createdAt":"2026-07-06T09:03:54.941Z","updatedAt":"2026-07-06T09:04:18.513Z","scanState":"clean"},{"id":"jellyfin-nfo-builder-20260701-6434352e0d","kind":"create","status":"pending","title":"Create jellyfin-nfo-builder","description":"为剧集整理统一文件名、生成缺失的 Jellyfin .nfo 剧集元数据","skillName":"jellyfin-nfo-builder","skillKey":"jellyfin-nfo-builder","createdAt":"2026-07-01T23:52:24.406Z","updatedAt":"2026-07-01T23:52:24.406Z","scanState":"clean"},{"id":"weekly-report-g5-20260626-7595273f1d","kind":"create","status":"applied","title":"Create weekly-report-g5","description":"维云智造G5周报生成:整理每日工作→多段邮件(纯文本+HTML含签名图)→存入钉邮草稿箱","skillName":"weekly-report-g5","skillKey":"weekly-report-g5","createdAt":"2026-06-26T00:46:22.478Z","updatedAt":"2026-06-26T00:46:35.812Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-0fc374efd7","kind":"update","status":"pending","title":"Update calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T03:23:27.062Z","updatedAt":"2026-06-24T03:23:27.062Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-cdbeb219a3","kind":"update","status":"applied","title":"Update calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T03:03:28.166Z","updatedAt":"2026-06-24T03:03:30.915Z","scanState":"clean"},{"id":"calibre-cleaner-20260624-a441798af9","kind":"create","status":"applied","title":"Create calibre-cleaner","description":"清洗 Calibre 书库:修复损坏书名/提取作者/检测编码损坏、小文件的批量删除","skillName":"calibre-cleaner","skillKey":"calibre-cleaner","createdAt":"2026-06-24T02:29:02.278Z","updatedAt":"2026-06-24T02:29:27.227Z","scanState":"clean"},{"id":"calibre-title-cleaner-20260624-3760b64e8b","kind":"create","status":"applied","title":"Create calibre-title-cleaner","description":"清洗 Calibre 书库中损坏的 txt 文档书名(HTML标签/长文本/乱码/路径超限修复)","skillName":"calibre-title-cleaner","skillKey":"calibre-title-cleaner","createdAt":"2026-06-24T01:10:56.296Z","updatedAt":"2026-06-24T01:13:39.670Z","scanState":"clean"},{"id":"dianping-review-20260611-d402abec10","kind":"create","status":"pending","title":"Create dianping-review","description":"通过大众点评搜索查询餐厅、老店、美食推荐和评论","skillName":"dianping-review","skillKey":"dianping-review","createdAt":"2026-06-11T23:50:15.731Z","updatedAt":"2026-06-11T23:50:15.731Z","scanState":"clean"}]} diff --git a/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/PROPOSAL.md b/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/PROPOSAL.md new file mode 100644 index 0000000..789b9c6 --- /dev/null +++ b/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/PROPOSAL.md @@ -0,0 +1,169 @@ +--- +name: "jav-media-sorter" +description: "JAV 视频整理:组装文件、按演员分组、刮削 nfo 元数据与封面图" +status: proposal +version: "v1" +date: "2026-07-07T12:14:43.074Z" +--- + +# JAV 媒体整理与元数据刮削技能 + +将 qbittorrent 下载完成的 JAV 视频( mp4 + srt + nfo )文件整理成 `/mnt/f/av/` 格式,按演员分类,并尝试刮削封面图。 + +## 目录结构规范 + +目标格式(参考 `/mnt/f/av/`): + +``` +/mnt/f/av/ +├── 演员名/ +│ ├── 番号-C 演员名/ ← 如果已有番号-C 目录则保留原名 +│ │ ├── 番号.mp4 +│ │ ├── 番号.chs.srt +│ │ ├── 番号.nfo +│ │ ├── poster.jpg +│ │ └── fanart.jpg +│ └── ... +├── 未知演员/ +│ └── ... +``` + +另一套目录结构(参考 `/mnt/e/01_automated/日本电影/`): + +``` +/mnt/e/01_automated/日本电影/ +├── 演员名/ +│ ├── 番号 演员名/ +│ │ ├── 番号.mp4 +│ │ ├── 番号.nfo +│ │ ├── 番号-poster.jpg +│ │ └── 番号-thumb.jpg +│ └── ... +``` + +## 前置条件 + +- Clash 代理运行在 Docker(端口 7443,认证 `proxy:5gynj20J`) +- FlareSolverr 运行在 Docker(已下线,按需启动) +- Python3(用于 nfo 和整理脚本) +- Docker(FlareSolverr + Clash) + +## 操作流程 + +### 1. 检查下载目录 + +```bash +ls /mnt/f/qbittorrent/failed/ +``` + +通常结构是 `failed/` 目录下平铺所有 mp4、srt(.chs.srt)、nfo 文件。 + +### 2. 按演员创建目标文件夹 + +在 `failed/` 目录内创建 `番号-C 演员名/` 文件夹,方便手动拖到 `/mnt/f/av/` 中对应演员目录。 + +```bash +cd /mnt/f/qbittorrent/failed +mkdir -p "ADN-016-C 明日見未来" +# ... 以此类推 +``` + +### 3. 按演员分组(移动目录到演员子目录) + +若目录直接放在 `/mnt/f/av/` 根目录下,需要移动到对应演员子目录: + +```bash +cd /mnt/f/av +mkdir -p "明日見未来" +mv "ADN-016-C 明日見未来" "明日見未来/" +# ... 以此类推 +``` + +### 4. 读取 nfo 获取演员信息 + +每个作品的 nfo 文件包含元数据,用 Python 解析: + +```python +import xml.etree.ElementTree as ET +tree = ET.parse('番号.nfo') +root = tree.getroot() +actors = [a.find('name').text for a in root.findall('actor')] +dvd_id = root.find('num').text +``` + +### 5. 封面图刮削 + +尝试从以下来源下载封面图: + +#### 5.1 FlareSolverr + Clash 代理(首选) + +```bash +FLARE="http://127.0.0.1:8191/v1" +CLASH_PROXY="http://proxy:***@host.docker.internal:7443" + +# FlareSolverr API 请求格式 +curl -s "$FLARE" -d '{ + "cmd":"request.get", + "url":"https://javdb.com/search?q=番号&f=all", + "maxTimeout":45000, + "proxy":{"url":"'$CLASH_PROXY'"} +}' -H "Content-Type: application/json" +``` + +从返回的 JSON 中提取 `solution.response` 中的 HTML,解析出: + +- 详情页链接 `href="/v/xxx"` +- 详情页中 `class="video-cover"` 的 `src` 属性(封面图片 URL) + +然后通过 Clash 代理下载图片: + +```bash +curl -x "http://proxy:***@127.0.0.1:7443" -s -L -o "poster.jpg" \ + -H "Referer: https://javdb.com/" "$POSTER_URL" +``` + +#### 5.2 备用:Python socks5 直连 + +```python +import socks, socket +socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 7443, + username="proxy", password="***", rdns=True) +socket.socket = socks.socksocket +import urllib.request, re +req = urllib.request.Request("https://javdb.com", headers={ + "User-Agent": "Mozilla/5.0"}) +``` + +#### 5.3 已知限制 + +- JavDB 有 Cloudflare 反爬,Python `requests`/`cloudscraper` 均可能被拦截 +- FlareSolverr 走 HTTP 代理时可能无法完成 Cloudflare JS 挑战 +- FANZA/DMM 图片 CDN 返回小图(~3KB),真实大图需 JS 渲染 +- 最可靠方案:**Windows 端浏览器手动下载** + +### 6. 图片命名规则 + +- `/mnt/f/av/` 格式: `poster.jpg` + `fanart.jpg`(两图相同) +- `/mnt/e/01_automated/日本电影/` 格式: `番号-poster.jpg` + `番号-thumb.jpg` + +## 注意事项 + +- **WSL 操作 /mnt 文件极慢**:大量小文件操作应在 Windows 原生 Python 中执行 +- **代理密码注意 shell 展开**:Clash 密码 `5gynj20J` 在 bash 中写为 `"proxy:*"`(用双引号避免 `***` 展开) +- **FlareSolverr 密码兼容性**:SOCKS5 代理认证不支持通过环境变量传递。HTTP 代理用 `proxy` 参数 +- **Clash 端口**:mixed-port 7443,同时支持 HTTP 和 SOCKS5 +- **删除冗余的字幕目录**:`*-中文字幕/` 目录中的 `.srt` 与 `failed/` 目录中的 `.chs.srt` 多数是重复文件(MD5 一致) + +## 依赖检查 + +```bash +# FlareSolverr +docker ps | grep flaresolverr + +# Clash +docker ps | grep clash + +# Python +python3 --version +pip3 list 2>/dev/null | grep -i cloudscraper +``` \ No newline at end of file diff --git a/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/proposal.json b/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/proposal.json new file mode 100644 index 0000000..a152736 --- /dev/null +++ b/skill-workshop/proposals/jav-media-sorter-20260707-b1f90c8a4d/proposal.json @@ -0,0 +1 @@ +{"schema":"openclaw.skill-workshop.proposal.v1","id":"jav-media-sorter-20260707-b1f90c8a4d","kind":"create","status":"pending","title":"Create jav-media-sorter","description":"JAV 视频整理:组装文件、按演员分组、刮削 nfo 元数据与封面图","createdAt":"2026-07-07T12:14:43.074Z","updatedAt":"2026-07-07T12:14:43.074Z","createdBy":"skill-workshop","origin":{"agentId":"storage","sessionKey":"agent:storage:main","runId":"6bfe1579-7e3c-4bdc-8435-9ee0822885bc","messageId":"6bfe1579-7e3c-4bdc-8435-9ee0822885bc"},"proposedVersion":"v1","draftFile":"PROPOSAL.md","draftHash":"aa0d2afcf8a91294ba24b1df0b7326254b82701baa5ad1c1770f7e19de52834a","target":{"skillName":"jav-media-sorter","skillKey":"jav-media-sorter","skillDir":"/home/yangxuan/.openclaw/workspace/storage/skills/jav-media-sorter","skillFile":"/home/yangxuan/.openclaw/workspace/storage/skills/jav-media-sorter/SKILL.md","source":"openclaw-workspace"},"scan":{"state":"clean","scannedAt":"2026-07-07T12:14:43.075Z","critical":0,"warn":0,"info":0,"findings":[]}} diff --git a/workspace-attestations/b7bc825f1ed54245663ac357564ad4f39678451d147525a2c689c68dd0bb7882.attested b/workspace-attestations/b7bc825f1ed54245663ac357564ad4f39678451d147525a2c689c68dd0bb7882.attested index c71138a..490b61b 100644 --- a/workspace-attestations/b7bc825f1ed54245663ac357564ad4f39678451d147525a2c689c68dd0bb7882.attested +++ b/workspace-attestations/b7bc825f1ed54245663ac357564ad4f39678451d147525a2c689c68dd0bb7882.attested @@ -1,2 +1,2 @@ openclaw-workspace-attestation:v1 -2026-07-07T11:54:28.001Z +2026-07-07T12:50:40.316Z