mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-02 06:22:42 -08:00
fix(subsync): reopen manual modal on sync errors
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
parseKikuFieldGroupingChoice,
|
||||
parseKikuMergePreviewRequest,
|
||||
} from '../../shared/ipc/validators';
|
||||
import { buildJimakuSubtitleFilenameFromMediaPath } from './jimaku-download-path';
|
||||
|
||||
const logger = createLogger('main:anki-jimaku-ipc');
|
||||
|
||||
@@ -148,10 +149,11 @@ export function registerAnkiJimakuIpcHandlers(
|
||||
if (!safeName) {
|
||||
return { ok: false, error: { error: 'Invalid subtitle filename.' } };
|
||||
}
|
||||
const subtitleFilename = buildJimakuSubtitleFilenameFromMediaPath(currentMediaPath, safeName);
|
||||
|
||||
const ext = path.extname(safeName);
|
||||
const baseName = ext ? safeName.slice(0, -ext.length) : safeName;
|
||||
let targetPath = path.join(mediaDir, safeName);
|
||||
const ext = path.extname(subtitleFilename);
|
||||
const baseName = ext ? subtitleFilename.slice(0, -ext.length) : subtitleFilename;
|
||||
let targetPath = path.join(mediaDir, subtitleFilename);
|
||||
if (fs.existsSync(targetPath)) {
|
||||
targetPath = path.join(mediaDir, `${baseName} (jimaku-${parsedQuery.entryId})${ext}`);
|
||||
let counter = 2;
|
||||
|
||||
28
src/core/services/jimaku-download-path.test.ts
Normal file
28
src/core/services/jimaku-download-path.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { buildJimakuSubtitleFilenameFromMediaPath } from './jimaku-download-path.js';
|
||||
|
||||
test('buildJimakuSubtitleFilenameFromMediaPath uses media basename + ja + subtitle extension', () => {
|
||||
assert.equal(
|
||||
buildJimakuSubtitleFilenameFromMediaPath('/videos/anime.mkv', 'Subs.Release.1080p.srt'),
|
||||
'anime.ja.srt',
|
||||
);
|
||||
});
|
||||
|
||||
test('buildJimakuSubtitleFilenameFromMediaPath falls back to .srt when subtitle name has no extension', () => {
|
||||
assert.equal(
|
||||
buildJimakuSubtitleFilenameFromMediaPath('/videos/anime.mkv', 'Subs Release'),
|
||||
'anime.ja.srt',
|
||||
);
|
||||
});
|
||||
|
||||
test('buildJimakuSubtitleFilenameFromMediaPath supports remote media URLs', () => {
|
||||
assert.equal(
|
||||
buildJimakuSubtitleFilenameFromMediaPath(
|
||||
'https://cdn.example.org/library/Anime%20Episode%2001.mkv?token=abc',
|
||||
'anything.ass',
|
||||
),
|
||||
'Anime Episode 01.ja.ass',
|
||||
);
|
||||
});
|
||||
51
src/core/services/jimaku-download-path.ts
Normal file
51
src/core/services/jimaku-download-path.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import * as path from 'node:path';
|
||||
|
||||
const DEFAULT_JIMAKU_LANGUAGE_SUFFIX = 'ja';
|
||||
const DEFAULT_SUBTITLE_EXTENSION = '.srt';
|
||||
|
||||
function stripFileExtension(name: string): string {
|
||||
const ext = path.extname(name);
|
||||
return ext ? name.slice(0, -ext.length) : name;
|
||||
}
|
||||
|
||||
function sanitizeFilenameSegment(value: string, fallback: string): string {
|
||||
const sanitized = value
|
||||
.replace(/[\\/:*?"<>|]/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
return sanitized || fallback;
|
||||
}
|
||||
|
||||
function resolveMediaFilename(mediaPath: string): string {
|
||||
if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(mediaPath)) {
|
||||
return path.basename(path.resolve(mediaPath));
|
||||
}
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(mediaPath);
|
||||
const decodedPath = decodeURIComponent(parsedUrl.pathname);
|
||||
const fromPath = path.basename(decodedPath);
|
||||
if (fromPath) {
|
||||
return fromPath;
|
||||
}
|
||||
return parsedUrl.hostname.replace(/^www\./, '') || 'subtitle';
|
||||
} catch {
|
||||
return path.basename(mediaPath);
|
||||
}
|
||||
}
|
||||
|
||||
export function buildJimakuSubtitleFilenameFromMediaPath(
|
||||
mediaPath: string,
|
||||
downloadedSubtitleName: string,
|
||||
languageSuffix = DEFAULT_JIMAKU_LANGUAGE_SUFFIX,
|
||||
): string {
|
||||
const mediaFilename = resolveMediaFilename(mediaPath);
|
||||
const mediaBasename = sanitizeFilenameSegment(stripFileExtension(mediaFilename), 'subtitle');
|
||||
const subtitleName = path.basename(downloadedSubtitleName);
|
||||
const subtitleExt = path.extname(subtitleName) || DEFAULT_SUBTITLE_EXTENSION;
|
||||
const normalizedLanguageSuffix = sanitizeFilenameSegment(languageSuffix, 'ja').replace(
|
||||
/\s+/g,
|
||||
'-',
|
||||
);
|
||||
return `${mediaBasename}.${normalizedLanguageSuffix}${subtitleExt}`;
|
||||
}
|
||||
Reference in New Issue
Block a user