自动缩略图插件审核修改
This commit is contained in:
1 parent
f4e69707c3
commit
d02370d6bd
28 files changed
+2308
-50
No files matched your search
@@ -0,0 +1,197 @@
|
||||
// 复合后缀兼容修改:只生成计划并持久化原值;真正修改 Eagle 字段由插件在用户确认后执行。
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const STORE_VERSION = 1;
|
||||
|
||||
function fullName(name, ext) {
|
||||
return String(name || '') + (ext ? '.' + ext : '');
|
||||
}
|
||||
|
||||
/** 返回需要展示给用户的字段变更;不需要修改或被安全条件阻断时返回 null / blocked。 */
|
||||
function planChange(item, eagleItem, splitCompoundName) {
|
||||
const sourceName = String((item && item.entryName) || '');
|
||||
const currentName = String((eagleItem && eagleItem.name) || '');
|
||||
const currentExt = String((eagleItem && eagleItem.ext) || '');
|
||||
const currentFileName = fullName(currentName, currentExt);
|
||||
if (!sourceName || currentFileName !== sourceName) {
|
||||
return {
|
||||
blocked: true,
|
||||
reason: 'sourceMismatch',
|
||||
sourceName,
|
||||
currentName,
|
||||
currentExt,
|
||||
currentFileName,
|
||||
};
|
||||
}
|
||||
const parts = splitCompoundName(sourceName);
|
||||
if (!parts || (currentName === parts.name && currentExt === parts.ext)) return null;
|
||||
if (fullName(parts.name, parts.ext) !== sourceName) {
|
||||
return {
|
||||
blocked: true,
|
||||
reason: 'sourceMismatch',
|
||||
sourceName,
|
||||
currentName,
|
||||
currentExt,
|
||||
currentFileName,
|
||||
};
|
||||
}
|
||||
return {
|
||||
sourceName,
|
||||
currentName,
|
||||
currentExt,
|
||||
currentFileName,
|
||||
newName: parts.name,
|
||||
newExt: parts.ext,
|
||||
newFileName: fullName(parts.name, parts.ext),
|
||||
};
|
||||
}
|
||||
|
||||
function emptyStore() {
|
||||
return { version: STORE_VERSION, entries: {} };
|
||||
}
|
||||
|
||||
function readStore(file) {
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
if (!data || data.version !== STORE_VERSION || !data.entries || typeof data.entries !== 'object') {
|
||||
throw new Error('备份文件格式不正确');
|
||||
}
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (error && error.code === 'ENOENT') return emptyStore();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function writeStore(file, data) {
|
||||
fs.mkdirSync(path.dirname(file), { recursive: true });
|
||||
const temp = file + '.' + process.pid + '.tmp';
|
||||
fs.writeFileSync(temp, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
||||
fs.renameSync(temp, file);
|
||||
}
|
||||
|
||||
function createStore(userDataPath) {
|
||||
const file = path.join(userDataPath, 'SpineThumbnailGenerateServer', 'compound-name-backups.json');
|
||||
return {
|
||||
file,
|
||||
list() {
|
||||
return Object.values(readStore(file).entries)
|
||||
.sort((left, right) => (right.updatedAt || 0) - (left.updatedAt || 0));
|
||||
},
|
||||
remember(change) {
|
||||
const data = readStore(file);
|
||||
if (!data.entries[change.itemId]) {
|
||||
data.entries[change.itemId] = {
|
||||
itemId: change.itemId,
|
||||
sourceName: change.sourceName,
|
||||
folderPath: change.folderPath || '',
|
||||
originalName: change.currentName,
|
||||
originalExt: change.currentExt,
|
||||
appliedName: change.newName,
|
||||
appliedExt: change.newExt,
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
writeStore(file, data);
|
||||
}
|
||||
return data.entries[change.itemId];
|
||||
},
|
||||
remove(itemId) {
|
||||
const data = readStore(file);
|
||||
if (!data.entries[itemId]) return;
|
||||
delete data.entries[itemId];
|
||||
writeStore(file, data);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 为恢复对话框生成可审计列表,并标出哪些条目允许恢复。
|
||||
* 用户后来亲自改过的字段不会被覆盖。
|
||||
*/
|
||||
async function inspectBackups(store, getItem, sourceExists) {
|
||||
const entries = store.list();
|
||||
const rows = [];
|
||||
for (const entry of entries) {
|
||||
let item = null;
|
||||
try {
|
||||
item = await getItem(entry.itemId);
|
||||
if (!item) {
|
||||
let sourcePresent = false;
|
||||
try {
|
||||
sourcePresent = sourceExists ? await sourceExists(entry) : false;
|
||||
} catch (error) { /* 检查失败时保守按缺失处理 */ }
|
||||
if (sourcePresent) {
|
||||
rows.push({
|
||||
entry,
|
||||
item: null,
|
||||
currentName: entry.appliedName,
|
||||
currentExt: entry.appliedExt,
|
||||
status: 'pluginApplied',
|
||||
});
|
||||
} else {
|
||||
rows.push({ entry, item: null, status: 'missing' });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const currentName = String(item.name || '');
|
||||
const currentExt = String(item.ext || '');
|
||||
if (currentName === entry.originalName && currentExt === entry.originalExt) {
|
||||
rows.push({ entry, item, currentName, currentExt, status: 'alreadyOriginal' });
|
||||
continue;
|
||||
}
|
||||
if (currentName !== entry.appliedName || currentExt !== entry.appliedExt) {
|
||||
rows.push({ entry, item, currentName, currentExt, status: 'changed' });
|
||||
continue;
|
||||
}
|
||||
rows.push({ entry, item, currentName, currentExt, status: 'ready' });
|
||||
} catch (error) {
|
||||
rows.push({ entry, item, status: 'error' });
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
async function restoreBackups(store, selectedItemIds, getItem, saveItem) {
|
||||
const selected = new Set(selectedItemIds || []);
|
||||
const entries = store.list().filter((entry) => selected.has(entry.itemId));
|
||||
const result = { total: entries.length, success: 0, skipped: 0, failed: 0 };
|
||||
for (const entry of entries) {
|
||||
let item = null;
|
||||
try {
|
||||
item = await getItem(entry.itemId);
|
||||
if (!item) {
|
||||
result.skipped += 1;
|
||||
continue;
|
||||
}
|
||||
const currentName = String(item.name || '');
|
||||
const currentExt = String(item.ext || '');
|
||||
if (currentName === entry.originalName && currentExt === entry.originalExt) {
|
||||
store.remove(entry.itemId);
|
||||
result.success += 1;
|
||||
continue;
|
||||
}
|
||||
if (currentName !== entry.appliedName || currentExt !== entry.appliedExt) {
|
||||
result.skipped += 1;
|
||||
continue;
|
||||
}
|
||||
item.name = entry.originalName;
|
||||
item.ext = entry.originalExt;
|
||||
await saveItem(item);
|
||||
store.remove(entry.itemId);
|
||||
result.success += 1;
|
||||
} catch (error) {
|
||||
result.failed += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const api = { fullName, planChange, createStore, inspectBackups, restoreBackups, STORE_VERSION };
|
||||
if (typeof window !== 'undefined') window.SpineThumbCompoundCompat = api;
|
||||
else if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
||||
|
||||
})();
|
||||
Reference in new issue
Block a user