59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import "server-only";
|
|
import path from "node:path";
|
|
import { rawDb } from "@/lib/db/client";
|
|
|
|
export interface ManualSubtitle {
|
|
code: string;
|
|
partIdx: number;
|
|
absPath: string;
|
|
attachedAt: number;
|
|
}
|
|
|
|
interface ManualSubtitleRow {
|
|
code: string;
|
|
part_idx: number;
|
|
abs_path: string;
|
|
attached_at: number;
|
|
}
|
|
|
|
function rowToEntry(r: ManualSubtitleRow): ManualSubtitle {
|
|
return { code: r.code, partIdx: r.part_idx, absPath: r.abs_path, attachedAt: r.attached_at };
|
|
}
|
|
|
|
export function listManualSubtitlesForVariant(code: string, partIdx: number): ManualSubtitle[] {
|
|
const rows = rawDb.prepare(`
|
|
SELECT code, part_idx, abs_path, attached_at FROM manual_subtitles
|
|
WHERE code = ? AND part_idx = ?
|
|
ORDER BY attached_at DESC
|
|
`).all(code, partIdx) as ManualSubtitleRow[];
|
|
return rows.map(rowToEntry);
|
|
}
|
|
|
|
/** True iff this exact abs path is recorded against any (code, part). */
|
|
export function isManualSubtitlePath(abs: string): boolean {
|
|
const resolved = path.resolve(abs);
|
|
// Windows paths are case-insensitive on disk but stored as-typed.
|
|
// Compare with a case-insensitive LIKE on Windows, exact on POSIX.
|
|
if (process.platform === "win32") {
|
|
const row = rawDb.prepare(`
|
|
SELECT 1 FROM manual_subtitles WHERE LOWER(abs_path) = LOWER(?) LIMIT 1
|
|
`).get(resolved);
|
|
return !!row;
|
|
}
|
|
const row = rawDb.prepare(`SELECT 1 FROM manual_subtitles WHERE abs_path = ? LIMIT 1`).get(resolved);
|
|
return !!row;
|
|
}
|
|
|
|
export function attachManualSubtitle(code: string, partIdx: number, absPath: string): void {
|
|
rawDb.prepare(`
|
|
INSERT OR REPLACE INTO manual_subtitles (code, part_idx, abs_path, attached_at)
|
|
VALUES (?, ?, ?, ?)
|
|
`).run(code, partIdx, path.resolve(absPath), Date.now());
|
|
}
|
|
|
|
export function detachManualSubtitle(code: string, partIdx: number, absPath: string): void {
|
|
rawDb.prepare(`
|
|
DELETE FROM manual_subtitles WHERE code = ? AND part_idx = ? AND abs_path = ?
|
|
`).run(code, partIdx, path.resolve(absPath));
|
|
}
|