临时文件兜底
This commit is contained in:
1 parent
08456f26cf
commit
be058c6c80
3 files changed
+52
-3
No files matched your search
@@ -16,6 +16,24 @@ const QUIET_MS = 1000;
|
||||
// fs.watch 在网络盘/外置盘上可能漏事件,用低频兜底扫描补上。
|
||||
const FALLBACK_MS = 30000;
|
||||
|
||||
/** 删除指定目录中超过保留时间的本插件临时文件。 */
|
||||
function cleanupStaleFiles(directory, prefix, maxAgeMs, now = Date.now()) {
|
||||
let names;
|
||||
try { names = fs.readdirSync(directory); } catch (error) { return 0; }
|
||||
let removed = 0;
|
||||
for (const name of names) {
|
||||
if (!name.startsWith(prefix)) continue;
|
||||
const file = path.join(directory, name);
|
||||
try {
|
||||
const stat = fs.lstatSync(file);
|
||||
if (!stat.isFile() || now - stat.mtimeMs < maxAgeMs) continue;
|
||||
fs.unlinkSync(file);
|
||||
removed += 1;
|
||||
} catch (error) { /* 单个文件失败不影响其余清理和监听 */ }
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
function createLibraryWatcher(options) {
|
||||
const onBatch = options.onBatch || (() => {});
|
||||
const onLog = options.onLog || (() => {});
|
||||
@@ -94,7 +112,7 @@ function createLibraryWatcher(options) {
|
||||
|
||||
// 同时支持两种加载方式:Node 里用 require(跑测试),插件页面里用 <script> 标签。
|
||||
// service 插件页面的 require 解析基准不是插件目录,所以页面里必须走 script 标签。
|
||||
const libraryWatcherApi = { createLibraryWatcher, QUIET_MS, FALLBACK_MS };
|
||||
const libraryWatcherApi = { createLibraryWatcher, cleanupStaleFiles, QUIET_MS, FALLBACK_MS };
|
||||
// 优先挂 window:Eagle 插件页面里也存在 module 对象(它有 Node 模块系统),
|
||||
// 先判断 module 会让页面拿到模块却取不到 window 上的名字。Node 里没有 window,自然走 require 分支。
|
||||
if (typeof window !== 'undefined') window.SpineThumbLibraryWatcher = libraryWatcherApi;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// 每次改动递增。Eagle 里的 service 插件是启动时加载并常驻的,改完代码必须重新加载插件
|
||||
// 才会生效;状态栏会显示这个版本号,方便确认加载的到底是不是最新代码。
|
||||
const VERSION = 'v60';
|
||||
const VERSION = 'v61';
|
||||
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
@@ -19,7 +19,7 @@ if (missing.length) {
|
||||
document.getElementById('status').textContent = '本地模块未加载:' + missing.join(', ');
|
||||
throw new Error('本地模块未加载,请检查 index.html 里 script 的顺序:' + missing.join(', '));
|
||||
}
|
||||
const { createLibraryWatcher } = window.SpineThumbLibraryWatcher;
|
||||
const { createLibraryWatcher, cleanupStaleFiles } = window.SpineThumbLibraryWatcher;
|
||||
const { scanSpineItems } = window.SpineThumbSpineAssets;
|
||||
const { renderThumbnailAuto, withTimeout } = window.SpineThumbRenderer;
|
||||
const settingsStore = window.SpineThumbSettings;
|
||||
@@ -42,6 +42,7 @@ const stats = { batches: 0, added: 0, spine: 0, complete: 0, generated: 0, skipp
|
||||
const PROGRESS_MIN_DYNAMIC = 10;
|
||||
// 弹窗上的「停止」按钮会把动作写进这个文件,宿主读回来执行暂停/继续/取消。
|
||||
const CONTROL_FILE = path.join(os.tmpdir(), 'spine-thumbnail-progress-control.json');
|
||||
const STALE_TEMP_AGE_MS = 24 * 60 * 60 * 1000;
|
||||
let settings = { ...settingsStore.DEFAULTS };
|
||||
let libraryPath = null;
|
||||
let imagesDir = null;
|
||||
@@ -290,6 +291,7 @@ async function processQueue() {
|
||||
runStats = null;
|
||||
runShowsProgress = false;
|
||||
if (run && showsProgress) finishRun(run);
|
||||
cleanupStaleFiles(os.tmpdir(), 'spine-thumb-', STALE_TEMP_AGE_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,6 +494,7 @@ filtersEl.addEventListener('click', (event) => {
|
||||
|
||||
// 先确认脚本本身执行到了这里,再谈 Eagle 事件有没有来。
|
||||
document.getElementById('status').textContent = '脚本已加载 ' + VERSION + ',等待 Eagle 事件…';
|
||||
cleanupStaleFiles(os.tmpdir(), 'spine-thumb-', STALE_TEMP_AGE_MS);
|
||||
|
||||
if (typeof eagle === 'undefined') {
|
||||
setStatus('eagle API 未注入');
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { cleanupStaleFiles } = require('../js/library-watcher.js');
|
||||
|
||||
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'spine-thumb-cleanup-'));
|
||||
const now = Date.now();
|
||||
const old = path.join(directory, 'spine-thumb-old.webp');
|
||||
const fresh = path.join(directory, 'spine-thumb-fresh.webp');
|
||||
const unrelated = path.join(directory, 'other-old.webp');
|
||||
|
||||
try {
|
||||
for (const file of [old, fresh, unrelated]) fs.writeFileSync(file, 'x');
|
||||
const oldTime = new Date(now - 25 * 60 * 60 * 1000);
|
||||
fs.utimesSync(old, oldTime, oldTime);
|
||||
fs.utimesSync(unrelated, oldTime, oldTime);
|
||||
|
||||
assert.equal(cleanupStaleFiles(directory, 'spine-thumb-', 24 * 60 * 60 * 1000, now), 1);
|
||||
assert.equal(fs.existsSync(old), false);
|
||||
assert.equal(fs.existsSync(fresh), true);
|
||||
assert.equal(fs.existsSync(unrelated), true);
|
||||
console.log('PASS: 只清理超过 24 小时的本插件临时文件');
|
||||
} finally {
|
||||
fs.rmSync(directory, { recursive: true, force: true });
|
||||
}
|
||||
Reference in new issue
Block a user