mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-06 19:57:26 -08:00
fix(anki): force Yomitan proxy server sync for card auto-enhancement
This commit is contained in:
@@ -41,6 +41,8 @@ test('syncYomitanDefaultAnkiServer updates default profile server when script re
|
|||||||
assert.equal(updated, true);
|
assert.equal(updated, true);
|
||||||
assert.match(scriptValue, /optionsGetFull/);
|
assert.match(scriptValue, /optionsGetFull/);
|
||||||
assert.match(scriptValue, /setAllSettings/);
|
assert.match(scriptValue, /setAllSettings/);
|
||||||
|
assert.match(scriptValue, /profileCurrent/);
|
||||||
|
assert.match(scriptValue, /forceOverride = false/);
|
||||||
assert.equal(infoLogs.length, 1);
|
assert.equal(infoLogs.length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -59,6 +61,45 @@ test('syncYomitanDefaultAnkiServer returns true when script reports no change',
|
|||||||
assert.equal(infoLogCount, 0);
|
assert.equal(infoLogCount, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('syncYomitanDefaultAnkiServer returns false when existing non-default server blocks update', async () => {
|
||||||
|
const deps = createDeps(async () => ({
|
||||||
|
updated: false,
|
||||||
|
matched: false,
|
||||||
|
reason: 'blocked-existing-server',
|
||||||
|
}));
|
||||||
|
const infoLogs: string[] = [];
|
||||||
|
|
||||||
|
const synced = await syncYomitanDefaultAnkiServer('http://127.0.0.1:8766', deps, {
|
||||||
|
error: () => undefined,
|
||||||
|
info: (message) => infoLogs.push(message),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(synced, false);
|
||||||
|
assert.equal(infoLogs.length, 1);
|
||||||
|
assert.match(infoLogs[0] ?? '', /blocked-existing-server/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('syncYomitanDefaultAnkiServer injects force override when enabled', async () => {
|
||||||
|
let scriptValue = '';
|
||||||
|
const deps = createDeps(async (script) => {
|
||||||
|
scriptValue = script;
|
||||||
|
return { updated: false, matched: true };
|
||||||
|
});
|
||||||
|
|
||||||
|
const synced = await syncYomitanDefaultAnkiServer(
|
||||||
|
'http://127.0.0.1:8766',
|
||||||
|
deps,
|
||||||
|
{
|
||||||
|
error: () => undefined,
|
||||||
|
info: () => undefined,
|
||||||
|
},
|
||||||
|
{ forceOverride: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(synced, true);
|
||||||
|
assert.match(scriptValue, /forceOverride = true/);
|
||||||
|
});
|
||||||
|
|
||||||
test('syncYomitanDefaultAnkiServer logs and returns false on script failure', async () => {
|
test('syncYomitanDefaultAnkiServer logs and returns false on script failure', async () => {
|
||||||
const deps = createDeps(async () => {
|
const deps = createDeps(async () => {
|
||||||
throw new Error('execute failed');
|
throw new Error('execute failed');
|
||||||
|
|||||||
@@ -848,11 +848,15 @@ export async function syncYomitanDefaultAnkiServer(
|
|||||||
serverUrl: string,
|
serverUrl: string,
|
||||||
deps: YomitanParserRuntimeDeps,
|
deps: YomitanParserRuntimeDeps,
|
||||||
logger: LoggerLike,
|
logger: LoggerLike,
|
||||||
|
options?: {
|
||||||
|
forceOverride?: boolean;
|
||||||
|
},
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const normalizedTargetServer = serverUrl.trim();
|
const normalizedTargetServer = serverUrl.trim();
|
||||||
if (!normalizedTargetServer) {
|
if (!normalizedTargetServer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const forceOverride = options?.forceOverride === true;
|
||||||
|
|
||||||
const isReady = await ensureYomitanParserWindow(deps, logger);
|
const isReady = await ensureYomitanParserWindow(deps, logger);
|
||||||
const parserWindow = deps.getYomitanParserWindow();
|
const parserWindow = deps.getYomitanParserWindow();
|
||||||
@@ -882,35 +886,42 @@ export async function syncYomitanDefaultAnkiServer(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const targetServer = ${JSON.stringify(normalizedTargetServer)};
|
const targetServer = ${JSON.stringify(normalizedTargetServer)};
|
||||||
|
const forceOverride = ${forceOverride ? 'true' : 'false'};
|
||||||
const optionsFull = await invoke("optionsGetFull", undefined);
|
const optionsFull = await invoke("optionsGetFull", undefined);
|
||||||
const profiles = Array.isArray(optionsFull.profiles) ? optionsFull.profiles : [];
|
const profiles = Array.isArray(optionsFull.profiles) ? optionsFull.profiles : [];
|
||||||
if (profiles.length === 0) {
|
if (profiles.length === 0) {
|
||||||
return { updated: false, reason: "no-profiles" };
|
return { updated: false, reason: "no-profiles" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultProfile = profiles[0];
|
const profileCurrent = Number.isInteger(optionsFull.profileCurrent)
|
||||||
if (!defaultProfile || typeof defaultProfile !== "object") {
|
? optionsFull.profileCurrent
|
||||||
|
: 0;
|
||||||
|
const targetProfile = profiles[profileCurrent];
|
||||||
|
if (!targetProfile || typeof targetProfile !== "object") {
|
||||||
return { updated: false, reason: "invalid-default-profile" };
|
return { updated: false, reason: "invalid-default-profile" };
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultProfile.options = defaultProfile.options && typeof defaultProfile.options === "object"
|
targetProfile.options = targetProfile.options && typeof targetProfile.options === "object"
|
||||||
? defaultProfile.options
|
? targetProfile.options
|
||||||
: {};
|
: {};
|
||||||
defaultProfile.options.anki = defaultProfile.options.anki && typeof defaultProfile.options.anki === "object"
|
targetProfile.options.anki = targetProfile.options.anki && typeof targetProfile.options.anki === "object"
|
||||||
? defaultProfile.options.anki
|
? targetProfile.options.anki
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
const currentServerRaw = defaultProfile.options.anki.server;
|
const currentServerRaw = targetProfile.options.anki.server;
|
||||||
const currentServer = typeof currentServerRaw === "string" ? currentServerRaw.trim() : "";
|
const currentServer = typeof currentServerRaw === "string" ? currentServerRaw.trim() : "";
|
||||||
const canReplaceDefault =
|
if (currentServer === targetServer) {
|
||||||
currentServer.length === 0 || currentServer === "http://127.0.0.1:8765";
|
return { updated: false, matched: true, reason: "already-target", currentServer, targetServer };
|
||||||
if (!canReplaceDefault || currentServer === targetServer) {
|
}
|
||||||
return { updated: false, reason: "no-change", currentServer, targetServer };
|
const canReplaceCurrent =
|
||||||
|
forceOverride || currentServer.length === 0 || currentServer === "http://127.0.0.1:8765";
|
||||||
|
if (!canReplaceCurrent) {
|
||||||
|
return { updated: false, matched: false, reason: "blocked-existing-server", currentServer, targetServer };
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultProfile.options.anki.server = targetServer;
|
targetProfile.options.anki.server = targetServer;
|
||||||
await invoke("setAllSettings", { value: optionsFull, source: "subminer" });
|
await invoke("setAllSettings", { value: optionsFull, source: "subminer" });
|
||||||
return { updated: true, currentServer, targetServer };
|
return { updated: true, matched: true, currentServer, targetServer };
|
||||||
})();
|
})();
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -924,6 +935,24 @@ export async function syncYomitanDefaultAnkiServer(
|
|||||||
logger.info?.(`Updated Yomitan default profile Anki server to ${normalizedTargetServer}`);
|
logger.info?.(`Updated Yomitan default profile Anki server to ${normalizedTargetServer}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
const matchedWithoutUpdate =
|
||||||
|
isObject(result) &&
|
||||||
|
result.updated === false &&
|
||||||
|
(result as { matched?: unknown }).matched === true;
|
||||||
|
if (matchedWithoutUpdate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const blockedByExistingServer =
|
||||||
|
isObject(result) &&
|
||||||
|
result.updated === false &&
|
||||||
|
(result as { matched?: unknown }).matched === false &&
|
||||||
|
typeof (result as { reason?: unknown }).reason === 'string';
|
||||||
|
if (blockedByExistingServer) {
|
||||||
|
logger.info?.(
|
||||||
|
`Skipped syncing Yomitan Anki server (reason=${String((result as { reason: string }).reason)})`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const checkedWithoutUpdate =
|
const checkedWithoutUpdate =
|
||||||
typeof result === 'object' &&
|
typeof result === 'object' &&
|
||||||
result !== null &&
|
result !== null &&
|
||||||
|
|||||||
@@ -2663,6 +2663,9 @@ async function syncYomitanDefaultProfileAnkiServer(): Promise<void> {
|
|||||||
logger.info(message, ...args);
|
logger.info(message, ...args);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
forceOverride: getResolvedConfig().ankiConnect.proxy?.enabled === true,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (synced) {
|
if (synced) {
|
||||||
|
|||||||
Reference in New Issue
Block a user