Files
chatpapers/src/modules/lecture/infrastructure/storage/paths.ts
T
2026-08-30 09:02:11 +08:00

99 lines
2.7 KiB
TypeScript

import { getPref } from "../../../../utils/prefs";
import { getString } from "../../../../utils/locale";
import {
joinPath,
normalizeStoragePath,
sanitizePathSegment,
} from "../platform/paths";
function resolveProfileDir(): string {
const dir = (Zotero as any).Profile?.dir;
if (typeof dir === "string" && dir.trim()) {
return dir.trim();
}
throw new Error("Cannot resolve Zotero profile directory");
}
function customLectureDataDir(): string {
return String(getPref("lectureDataDir") || "").trim();
}
/** Map logical cacheKey (may contain `|`) to a filesystem-safe directory/file stem. */
export function cacheKeyDirName(cacheKey: string): string {
return sanitizePathSegment(cacheKey, 100);
}
/** Resolved voice-lecture data root (custom pref or `{Profile}/chatpapers/lecture/`). */
export function lectureDataRoot(): string {
const custom = customLectureDataDir();
if (custom) {
return normalizeStoragePath(custom);
}
return joinPath(resolveProfileDir(), "chatpapers", "lecture");
}
export function lectureDbPath(): string {
return joinPath(lectureDataRoot(), "lecture.db");
}
/** Interim JSON index until SQLite POC lands */
export function lectureIndexPath(): string {
return joinPath(lectureDataRoot(), "cache-index.json");
}
export function lectureDataFilePath(cacheKey: string): string {
return joinPath(lectureDataRoot(), "data", `${cacheKeyDirName(cacheKey)}.json`);
}
export function audioRootDir(): string {
return joinPath(lectureDataRoot(), "audio");
}
export function audioDirForPaper(cacheKey: string): string {
return joinPath(audioRootDir(), cacheKeyDirName(cacheKey));
}
export function audioFilePath(
cacheKey: string,
unitId: string,
ext: "wav" | "mp3" = "wav",
): string {
return joinPath(
audioDirForPaper(cacheKey),
`${sanitizePathSegment(unitId, 80)}.${ext}`,
);
}
export function lectureSamplePath(name: string): string {
return joinPath(lectureDataRoot(), "samples", sanitizePathSegment(name, 80));
}
export async function ensureSampleDir(): Promise<string> {
const dir = joinPath(lectureDataRoot(), "samples");
await ensureDir(dir);
return dir;
}
async function ensureDir(path: string): Promise<void> {
await IOUtils.makeDirectory(path, {
createAncestors: true,
ignoreExisting: true,
});
}
export async function ensureLectureDirs(): Promise<void> {
const root = lectureDataRoot();
try {
await ensureDir(root);
await ensureDir(joinPath(root, "data"));
await ensureDir(audioRootDir());
} catch (e) {
const detail = e instanceof Error ? e.message : String(e);
throw new Error(
getString("lecture-storage-write-failed", {
args: { path: root, detail },
}),
);
}
}