mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-10 04:19:25 -07:00
Disable character-dictionary features in external profile mode
- Gate character-dictionary runtime, auto-sync, annotations, and CLI generation when `yomitan.externalProfilePath` is set - Return explicit disabled reason for blocked character-dictionary generation in read-only external-profile mode - Fix default config bootstrap to seed `config.jsonc` when config dir exists but config file is missing - Update tests, changelog fragment, and docs to reflect the new behavior
This commit is contained in:
32
src/main.ts
32
src/main.ts
@@ -375,6 +375,10 @@ import { createOverlayVisibilityRuntimeService } from './main/overlay-visibility
|
||||
import { createCharacterDictionaryRuntimeService } from './main/character-dictionary-runtime';
|
||||
import { createCharacterDictionaryAutoSyncRuntimeService } from './main/runtime/character-dictionary-auto-sync';
|
||||
import { notifyCharacterDictionaryAutoSyncStatus } from './main/runtime/character-dictionary-auto-sync-notifications';
|
||||
import {
|
||||
getCharacterDictionaryDisabledReason,
|
||||
isCharacterDictionaryRuntimeEnabled,
|
||||
} from './main/runtime/character-dictionary-availability';
|
||||
import { createCurrentMediaTokenizationGate } from './main/runtime/current-media-tokenization-gate';
|
||||
import { createStartupOsdSequencer } from './main/runtime/startup-osd-sequencer';
|
||||
import { formatSkippedYomitanWriteAction } from './main/runtime/yomitan-read-only-log';
|
||||
@@ -1329,7 +1333,9 @@ const characterDictionaryAutoSyncRuntime = createCharacterDictionaryAutoSyncRunt
|
||||
getConfig: () => {
|
||||
const config = getResolvedConfig().anilist.characterDictionary;
|
||||
return {
|
||||
enabled: config.enabled,
|
||||
enabled:
|
||||
config.enabled &&
|
||||
isCharacterDictionaryRuntimeEnabled(getConfiguredExternalYomitanProfilePath()),
|
||||
maxLoaded: config.maxLoaded,
|
||||
profileScope: config.profileScope,
|
||||
};
|
||||
@@ -2757,6 +2763,9 @@ const {
|
||||
);
|
||||
},
|
||||
scheduleCharacterDictionarySync: () => {
|
||||
if (!isCharacterDictionaryEnabledForCurrentProcess()) {
|
||||
return;
|
||||
}
|
||||
characterDictionaryAutoSyncRuntime.scheduleSync();
|
||||
},
|
||||
updateCurrentMediaTitle: (title) => {
|
||||
@@ -2834,7 +2843,9 @@ const {
|
||||
'subtitle.annotation.jlpt',
|
||||
getResolvedConfig().subtitleStyle.enableJlpt,
|
||||
),
|
||||
getCharacterDictionaryEnabled: () => getResolvedConfig().anilist.characterDictionary.enabled,
|
||||
getCharacterDictionaryEnabled: () =>
|
||||
getResolvedConfig().anilist.characterDictionary.enabled &&
|
||||
isCharacterDictionaryEnabledForCurrentProcess(),
|
||||
getNameMatchEnabled: () => getResolvedConfig().subtitleStyle.nameMatchEnabled,
|
||||
getFrequencyDictionaryEnabled: () =>
|
||||
getRuntimeBooleanOption(
|
||||
@@ -3036,6 +3047,14 @@ function isYomitanExternalReadOnlyMode(): boolean {
|
||||
return getConfiguredExternalYomitanProfilePath().length > 0;
|
||||
}
|
||||
|
||||
function isCharacterDictionaryEnabledForCurrentProcess(): boolean {
|
||||
return isCharacterDictionaryRuntimeEnabled(getConfiguredExternalYomitanProfilePath());
|
||||
}
|
||||
|
||||
function getCharacterDictionaryDisabledReasonForCurrentProcess(): string | null {
|
||||
return getCharacterDictionaryDisabledReason(getConfiguredExternalYomitanProfilePath());
|
||||
}
|
||||
|
||||
function logSkippedYomitanWrite(action: string): void {
|
||||
logger.info(
|
||||
`[yomitan] skipping ${action}: yomitan.externalProfilePath is configured; external profile mode is read-only`,
|
||||
@@ -3547,8 +3566,13 @@ const createCliCommandContextHandler = createCliCommandContextFactory({
|
||||
openJellyfinSetupWindow: () => openJellyfinSetupWindow(),
|
||||
getAnilistQueueStatus: () => anilistStateRuntime.getQueueStatusSnapshot(),
|
||||
processNextAnilistRetryUpdate: () => processNextAnilistRetryUpdate(),
|
||||
generateCharacterDictionary: (targetPath?: string) =>
|
||||
characterDictionaryRuntime.generateForCurrentMedia(targetPath),
|
||||
generateCharacterDictionary: async (targetPath?: string) => {
|
||||
const disabledReason = getCharacterDictionaryDisabledReasonForCurrentProcess();
|
||||
if (disabledReason) {
|
||||
throw new Error(disabledReason);
|
||||
}
|
||||
return await characterDictionaryRuntime.generateForCurrentMedia(targetPath);
|
||||
},
|
||||
runJellyfinCommand: (argsFromCommand: CliArgs) => runJellyfinCommand(argsFromCommand),
|
||||
openYomitanSettings: () => openYomitanSettings(),
|
||||
cycleSecondarySubMode: () => handleCycleSecondarySubMode(),
|
||||
|
||||
@@ -65,7 +65,7 @@ test('ensureDefaultConfigBootstrap creates config dir and default jsonc only whe
|
||||
});
|
||||
});
|
||||
|
||||
test('ensureDefaultConfigBootstrap does not seed default config into an existing config directory', () => {
|
||||
test('ensureDefaultConfigBootstrap seeds default config into an existing config directory when missing', () => {
|
||||
withTempDir((root) => {
|
||||
const configDir = path.join(root, 'SubMiner');
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
@@ -74,10 +74,13 @@ test('ensureDefaultConfigBootstrap does not seed default config into an existing
|
||||
ensureDefaultConfigBootstrap({
|
||||
configDir,
|
||||
configFilePaths: getDefaultConfigFilePaths(configDir),
|
||||
generateTemplate: () => 'should-not-write',
|
||||
generateTemplate: () => '{\n "logging": {}\n}\n',
|
||||
});
|
||||
|
||||
assert.equal(fs.existsSync(path.join(configDir, 'config.jsonc')), false);
|
||||
assert.equal(
|
||||
fs.readFileSync(path.join(configDir, 'config.jsonc'), 'utf8'),
|
||||
'{\n "logging": {}\n}\n',
|
||||
);
|
||||
assert.equal(fs.readFileSync(path.join(configDir, 'existing-user-file.txt'), 'utf8'), 'keep\n');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -208,13 +208,8 @@ export function ensureDefaultConfigBootstrap(options: {
|
||||
const existsSync = options.existsSync ?? fs.existsSync;
|
||||
const mkdirSync = options.mkdirSync ?? fs.mkdirSync;
|
||||
const writeFileSync = options.writeFileSync ?? fs.writeFileSync;
|
||||
const configDirExists = existsSync(options.configDir);
|
||||
|
||||
if (
|
||||
existsSync(options.configFilePaths.jsoncPath) ||
|
||||
existsSync(options.configFilePaths.jsonPath) ||
|
||||
configDirExists
|
||||
) {
|
||||
if (existsSync(options.configFilePaths.jsoncPath) || existsSync(options.configFilePaths.jsonPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user