dsh-bili-watch 0.2.17 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/client.js +20 -0
- package/index.js +62 -3
- package/package.json +1 -1
- package/tools/look.mjs +2 -1
package/README.md
CHANGED
|
@@ -54,6 +54,7 @@ dsh plugin --profile web remove dsh-bili-watch
|
|
|
54
54
|
- **删除**:面板按实际路径判断——装在插件目录里的(yt-dlp、转写模型、登录凭证)可直接删;装在插件目录外的(比如复用系统 ffmpeg 或已有的 Python 环境)按钮置灰,旁边标出它实际在哪。
|
|
55
55
|
- **批量**:标题行的「批量下载 / 批量清理」打开勾选清单,默认勾上所有可操作的项,删除前会再确认一次。
|
|
56
56
|
- **抽帧缓存**:显示当前占用与文件数,「立即清除」一键清空;不点则会按规则自动清理——保留天数(默认 7 天)与总量上限(默认 2048 MB),超过则从最旧的删起。规则存在 `deps/cache-config.json`,插件启动和打开面板时各检查一次。
|
|
57
|
+
- **缓存位置**:默认在系统临时目录(`tmpdir()/bili-watch`)。要换位置就设环境变量 `BILI_WATCH_CACHE`,或在 `deps/deps-config.json` 里写 `"cache": "D:\\你想要的目录"`;改完重启 DSH 生效,面板「抽帧缓存 → 位置」会显示当前实际路径。
|
|
57
58
|
- **最近一次调用**:显示命令、时间、成败,用来判断上一次看视频是否卡住。
|
|
58
59
|
|
|
59
60
|
装完第一次重启 DSH,面板才会出现。
|
package/client.js
CHANGED
|
@@ -379,6 +379,26 @@ window.__ModuleLoader__.load({
|
|
|
379
379
|
h('span', { 'data-bl-name': '' }, '当前占用'),
|
|
380
380
|
h('span', { 'data-bl-detail': '' }, `${fmtBytes(cache.bytes)} / ${cache.files} 个文件`),
|
|
381
381
|
h('button', { 'data-bl-btn': '', onClick: saveCache }, '立即清除')),
|
|
382
|
+
h('div', { 'data-bl-row': '' },
|
|
383
|
+
h('span', { 'data-bl-name': '' }, '位置'),
|
|
384
|
+
h('span', { 'data-bl-detail': '' }, cache.dir || '(系统临时目录)'),
|
|
385
|
+
h('button', {
|
|
386
|
+
'data-bl-btn': '',
|
|
387
|
+
onClick: async () => {
|
|
388
|
+
setSaveErr('')
|
|
389
|
+
try {
|
|
390
|
+
const r = await jpost('/cache/pick', {})
|
|
391
|
+
if (r.ok && r.data?.dir) setMsg(`已选择:${r.data.dir}(重启 DSH 生效)`)
|
|
392
|
+
else if (r.ok === false) setMsg(r.why || '已取消')
|
|
393
|
+
else setMsg('选择失败')
|
|
394
|
+
} catch (e) { setSaveErr(`选择目录失败:${String(e?.message || e)}`) }
|
|
395
|
+
},
|
|
396
|
+
}, '选择目录…')),
|
|
397
|
+
h('div', { 'data-bl-row': '' },
|
|
398
|
+
h('span', { 'data-bl-name': '' }, '改位置'),
|
|
399
|
+
h('span', { 'data-bl-detail': '' }, '或用环境变量 BILI_WATCH_CACHE / deps/deps-config.json 的 "cache";改完重启 DSH 生效。'),
|
|
400
|
+
null),
|
|
401
|
+
msg ? h('div', { 'data-bl-note': '' }, msg) : null,
|
|
382
402
|
h('div', { 'data-bl-row': '' },
|
|
383
403
|
h('span', { 'data-bl-name': '' }, '自动清理规则'),
|
|
384
404
|
h('span', { 'data-bl-detail': '' },
|
package/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* 只读、匿名,不改任何业务状态。
|
|
11
11
|
*/
|
|
12
12
|
import { spawn } from 'node:child_process'
|
|
13
|
-
import { appendFileSync, existsSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs'
|
|
13
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs'
|
|
14
14
|
import { tmpdir } from 'node:os'
|
|
15
15
|
import { dirname, join } from 'node:path'
|
|
16
16
|
import { fileURLToPath } from 'node:url'
|
|
@@ -57,7 +57,25 @@ function depsCfg() {
|
|
|
57
57
|
function projDir() { return process.env.BILI_WATCH_PROJ || depsCfg().proj || DEPS }
|
|
58
58
|
const CRED_FILE = join(DEPS, 'credential.json')
|
|
59
59
|
const LAST_RUN = join(DEPS, 'last-run.json')
|
|
60
|
-
|
|
60
|
+
// 缓存位置:env BILI_WATCH_CACHE > deps\deps-config.json 的 cache > 系统临时目录。发布版不含本机路径。
|
|
61
|
+
// 自定义目录不可写时不让功能哑掉:回退到临时目录,并把原因挂进 /status.warnings。
|
|
62
|
+
function pickCacheDir() {
|
|
63
|
+
const want = process.env.BILI_WATCH_CACHE || depsCfg().cache || join(tmpdir(), 'bili-watch')
|
|
64
|
+
try {
|
|
65
|
+
mkdirSync(want, { recursive: true })
|
|
66
|
+
const probe = join(want, `.write-test-${process.pid}`)
|
|
67
|
+
writeFileSync(probe, 'ok')
|
|
68
|
+
rmSync(probe, { force: true })
|
|
69
|
+
return { dir: want, fallback: null }
|
|
70
|
+
} catch (e) {
|
|
71
|
+
const fb = join(tmpdir(), 'bili-watch')
|
|
72
|
+
try { mkdirSync(fb, { recursive: true }) } catch {}
|
|
73
|
+
return { dir: fb, fallback: String(e?.message || e) }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const cachePick = pickCacheDir()
|
|
77
|
+
const CACHE = cachePick.dir
|
|
78
|
+
if (cachePick.fallback) cfgWarning = `缓存目录不可写,已回退到 ${CACHE}:${cachePick.fallback}`
|
|
61
79
|
const PY_DIR = process.platform === 'win32' ? 'Scripts' : 'bin'
|
|
62
80
|
const PY_EXE = process.platform === 'win32' ? 'python.exe' : 'python'
|
|
63
81
|
function venvAsr() { const p = projDir(); return [join(DEPS, '.venv-asr', PY_DIR, PY_EXE), join(p, '.venv-asr', PY_DIR, PY_EXE)] }
|
|
@@ -328,6 +346,37 @@ function writeCacheCfg(days, maxMb) {
|
|
|
328
346
|
} catch {}
|
|
329
347
|
}
|
|
330
348
|
|
|
349
|
+
/** 合并写 deps\deps-config.json(只动指定字段,保留用户原有配置)。 */
|
|
350
|
+
function writeDepsCfg(patch) {
|
|
351
|
+
const p = join(DEPS, 'deps-config.json')
|
|
352
|
+
let cur = {}
|
|
353
|
+
try { cur = JSON.parse(readFileSync(p, 'utf8')) } catch {}
|
|
354
|
+
const next = { ...cur, ...patch }
|
|
355
|
+
writeFileSync(p, JSON.stringify(next, null, 2), 'utf8')
|
|
356
|
+
return next
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* 弹原生选目录框(Windows)。脚本里只用 ASCII,避免 PS 5.1 按 ANSI 解码中文变乱。
|
|
361
|
+
* 取消返回 null;非 Windows 直接报错,让面板提示手填。
|
|
362
|
+
*/
|
|
363
|
+
function pickFolderDialog() {
|
|
364
|
+
return new Promise((resolve, reject) => {
|
|
365
|
+
if (process.platform !== 'win32') return reject(new Error('folder picker is Windows only; set the path manually'))
|
|
366
|
+
const script = 'Add-Type -AssemblyName System.Windows.Forms; $d = New-Object System.Windows.Forms.FolderBrowserDialog; $d.Description = "bili-watch cache folder"; if ($d.ShowDialog() -eq "OK") { [Console]::Out.Write($d.SelectedPath) }'
|
|
367
|
+
const ps = spawn('powershell.exe', ['-NoProfile', '-STA', '-Command', script], { windowsHide: false })
|
|
368
|
+
let out = ''
|
|
369
|
+
let err = ''
|
|
370
|
+
ps.stdout.on('data', (c) => { out += c })
|
|
371
|
+
ps.stderr.on('data', (c) => { err += c })
|
|
372
|
+
ps.on('close', (code) => {
|
|
373
|
+
if (code !== 0) return reject(new Error(err.trim() || ('powershell exit ' + code)))
|
|
374
|
+
resolve(out.trim() || null)
|
|
375
|
+
})
|
|
376
|
+
ps.on('error', reject)
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
|
|
331
380
|
/**
|
|
332
381
|
* 缓存自动清理:先按天数删过期文件,再按总量从最旧删到阈值内。
|
|
333
382
|
* 返回被删统计,供面板显示。
|
|
@@ -836,13 +885,23 @@ function apply(ctx) {
|
|
|
836
885
|
data: {
|
|
837
886
|
credential: credState(),
|
|
838
887
|
deps: depRows(),
|
|
839
|
-
cache: { ...dirStat(CACHE), ...cacheCfg(), lastAutoClean: cleaned },
|
|
888
|
+
cache: { ...dirStat(CACHE), ...cacheCfg(), dir: CACHE, lastAutoClean: cleaned },
|
|
840
889
|
lastRun: readLastRun(),
|
|
841
890
|
ui: uiCfg(),
|
|
842
891
|
warnings: cfgWarning ? [cfgWarning] : [],
|
|
843
892
|
},
|
|
844
893
|
})
|
|
845
894
|
}
|
|
895
|
+
if (req.method === 'POST' && url.pathname === '/api/bili-watch/cache/pick') {
|
|
896
|
+
try {
|
|
897
|
+
const dir = await pickFolderDialog()
|
|
898
|
+
if (!dir) return sendJson(res, 200, { ok: false, why: '已取消' })
|
|
899
|
+
writeDepsCfg({ cache: dir })
|
|
900
|
+
return sendJson(res, 200, { ok: true, data: { dir, restart: true } })
|
|
901
|
+
} catch (e) {
|
|
902
|
+
return sendJson(res, 500, { ok: false, why: String(e?.message || e) })
|
|
903
|
+
}
|
|
904
|
+
}
|
|
846
905
|
if (req.method === 'POST' && url.pathname === '/api/bili-watch/cache/clear') {
|
|
847
906
|
const body = await readJsonBody(req)
|
|
848
907
|
if (Number.isFinite(body?.days) || Number.isFinite(body?.maxMb)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bili-watch",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reads Bilibili (and generic URLs via yt-dlp) into text for DSH agents: search, hot, metadata, comments, danmaku, AI subtitles, local ASR, frame OCR.",
|
|
6
6
|
"type": "module",
|
package/tools/look.mjs
CHANGED
|
@@ -59,7 +59,8 @@ const FFMPEG_CAND = process.env.BILI_WATCH_FFMPEG || depsCfg.ffmpeg || ''
|
|
|
59
59
|
// 缺 ffmpeg 时的统一指路(一键脚本 / 环境变量 / --ffmpeg 三条出路)
|
|
60
60
|
const FFMPEG_HINT =
|
|
61
61
|
'跑 scripts/fetch-deps.ps1 -Target ffmpeg(macOS/Linux:bash scripts/fetch-deps.sh 或系统包管理器装),或设 BILI_WATCH_FFMPEG,或用 --ffmpeg 传路径'
|
|
62
|
-
|
|
62
|
+
// 缓存位置:env BILI_WATCH_CACHE > deps\deps-config.json 的 cache > 系统临时目录(与 index.js 同一口径)。
|
|
63
|
+
const CACHE = process.env.BILI_WATCH_CACHE || depsCfg.cache || join(tmpdir(), 'bili-watch')
|
|
63
64
|
const require = createRequire(import.meta.url)
|
|
64
65
|
const CRED_FILE = join(DEPS, 'credential.json')
|
|
65
66
|
const LOGIN_KEY_FILE = join(DEPS, 'login-key.json')
|