stop caching transcriptions and OCR
Both endpoints kept a copy under cache/ and returned it on the next call, and also short-circuited when the sibling .md already existed. So a re-run never re-ran: a bad transcription stayed bad, and there was no way to ask for a fresh one. Every caller passes saveNextTo, so the cache-path return was dead code anyway. Both now always do the work and overwrite the sibling. CACHE_PREFIXES drops the two prefixes, since /save-result has nothing left to promote for them; the tts and audio caches are untouched. Also fixes the task runner output being unreadable in light mode. The panel is a fixed dark terminal, but stdout lines were classed text-foreground, which follows the app theme and renders black on the dark background. They now inherit the pre's own colour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1263a4f851
commit
d6b4b900ff
@@ -602,7 +602,7 @@ router.get('/probe-folder', async (ctx) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Save a cached result (ocr/tts/transcriptions/audio) next to the original file
|
// Save a cached result (ocr/tts/transcriptions/audio) next to the original file
|
||||||
const CACHE_PREFIXES = ['cache/ocr/', 'cache/tts/', 'cache/transcriptions/', 'cache/audio/'];
|
const CACHE_PREFIXES = ['cache/tts/', 'cache/audio/'];
|
||||||
|
|
||||||
router.post('/save-result', async (ctx) => {
|
router.post('/save-result', async (ctx) => {
|
||||||
const user = ctx.get('user');
|
const user = ctx.get('user');
|
||||||
@@ -775,31 +775,8 @@ router.post('/ocr', async (ctx) => {
|
|||||||
const s = await stat(absPath);
|
const s = await stat(absPath);
|
||||||
if (s.isDirectory()) throw errors.BAD_REQUEST('Cannot OCR a directory');
|
if (s.isDirectory()) throw errors.BAD_REQUEST('Cannot OCR a directory');
|
||||||
|
|
||||||
const userDataDir = getUserDataDir(user.email);
|
// No caching: OCR is always run fresh and overwrites any previous result.
|
||||||
const { dir, name } = parsePath(filePath.replace(/^\/+/, ''));
|
const { dir, name } = parsePath(filePath.replace(/^\/+/, ''));
|
||||||
const cacheRel = dir ? `cache/ocr/${dir}/${name}.md` : `cache/ocr/${name}.md`;
|
|
||||||
const cacheAbs = resolve(userDataDir, cacheRel);
|
|
||||||
|
|
||||||
// When saving next to file, check if the sibling .md already exists
|
|
||||||
if (saveNextTo) {
|
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
|
||||||
if (existsSync(siblingAbs)) {
|
|
||||||
return ctx.json({ ocrPath: `/${siblingRel}`, ocrRoot: root ?? 'home', cached: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existsSync(cacheAbs)) {
|
|
||||||
if (saveNextTo) {
|
|
||||||
const text = await readFile(cacheAbs, 'utf-8');
|
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
|
||||||
await Bun.write(siblingAbs, text);
|
|
||||||
return ctx.json({ ocrPath: `/${siblingRel}`, ocrRoot: root ?? 'home', cached: true });
|
|
||||||
}
|
|
||||||
const text = await readFile(cacheAbs, 'utf-8');
|
|
||||||
return ctx.json({ text, ocrPath: cacheRel, ocrRoot: 'user-data', cached: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const ocrConfig = await readOcrConfig();
|
const ocrConfig = await readOcrConfig();
|
||||||
if (!ocrConfig) throw errors.BAD_REQUEST('OCR not configured — set it up in Settings → OCR');
|
if (!ocrConfig) throw errors.BAD_REQUEST('OCR not configured — set it up in Settings → OCR');
|
||||||
@@ -851,9 +828,6 @@ router.post('/ocr', async (ctx) => {
|
|||||||
const json = (await res.json()) as { choices: { message: { content: string } }[] };
|
const json = (await res.json()) as { choices: { message: { content: string } }[] };
|
||||||
const text = json.choices[0]?.message?.content ?? '';
|
const text = json.choices[0]?.message?.content ?? '';
|
||||||
|
|
||||||
await mkdir(dirname(cacheAbs), { recursive: true });
|
|
||||||
await Bun.write(cacheAbs, text);
|
|
||||||
|
|
||||||
if (saveNextTo) {
|
if (saveNextTo) {
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
||||||
@@ -861,7 +835,7 @@ router.post('/ocr', async (ctx) => {
|
|||||||
return ctx.json({ ocrPath: `/${siblingRel}`, ocrRoot: root ?? 'home', cached: false });
|
return ctx.json({ ocrPath: `/${siblingRel}`, ocrRoot: root ?? 'home', cached: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.json({ text, ocrPath: cacheRel, ocrRoot: 'user-data', cached: false });
|
return ctx.json({ text, cached: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Extract audio from video via ffmpeg with caching
|
// Extract audio from video via ffmpeg with caching
|
||||||
@@ -999,29 +973,8 @@ router.post('/transcribe', async (ctx) => {
|
|||||||
const s = await stat(absPath);
|
const s = await stat(absPath);
|
||||||
if (s.isDirectory()) throw errors.BAD_REQUEST('Cannot transcribe a directory');
|
if (s.isDirectory()) throw errors.BAD_REQUEST('Cannot transcribe a directory');
|
||||||
|
|
||||||
const userDataDir = getUserDataDir(user.email);
|
// No caching: a transcription is always produced fresh and overwrites any previous one.
|
||||||
const { dir, name } = parsePath(filePath.replace(/^\/+/, ''));
|
const { dir, name } = parsePath(filePath.replace(/^\/+/, ''));
|
||||||
const cacheRel = dir ? `cache/transcriptions/${dir}/${name}.md` : `cache/transcriptions/${name}.md`;
|
|
||||||
const cacheAbs = resolve(userDataDir, cacheRel);
|
|
||||||
|
|
||||||
if (saveNextTo) {
|
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
|
||||||
if (existsSync(siblingAbs)) {
|
|
||||||
return ctx.json({ transcriptionPath: `/${siblingRel}`, transcriptionRoot: root ?? 'home', cached: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existsSync(cacheAbs)) {
|
|
||||||
if (saveNextTo) {
|
|
||||||
const text = await readFile(cacheAbs, 'utf-8');
|
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
|
||||||
await Bun.write(siblingAbs, text);
|
|
||||||
return ctx.json({ transcriptionPath: `/${siblingRel}`, transcriptionRoot: root ?? 'home', cached: true });
|
|
||||||
}
|
|
||||||
return ctx.json({ transcriptionPath: cacheRel, transcriptionRoot: 'user-data', cached: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sttConfig = await readSttConfig();
|
const sttConfig = await readSttConfig();
|
||||||
const whisperUrl = sttConfig?.url;
|
const whisperUrl = sttConfig?.url;
|
||||||
@@ -1038,9 +991,6 @@ router.post('/transcribe', async (ctx) => {
|
|||||||
throw errors.BAD_REQUEST(err instanceof Error ? err.message : 'Transcription failed');
|
throw errors.BAD_REQUEST(err instanceof Error ? err.message : 'Transcription failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
await mkdir(dirname(cacheAbs), { recursive: true });
|
|
||||||
await Bun.write(cacheAbs, text);
|
|
||||||
|
|
||||||
if (saveNextTo) {
|
if (saveNextTo) {
|
||||||
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
const siblingRel = dir ? `${dir}/${name}.md` : `${name}.md`;
|
||||||
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
const siblingAbs = resolveUserPath(rootDir, siblingRel);
|
||||||
@@ -1048,7 +998,7 @@ router.post('/transcribe', async (ctx) => {
|
|||||||
return ctx.json({ transcriptionPath: `/${siblingRel}`, transcriptionRoot: root ?? 'home', cached: false });
|
return ctx.json({ transcriptionPath: `/${siblingRel}`, transcriptionRoot: root ?? 'home', cached: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.json({ transcriptionPath: cacheRel, transcriptionRoot: 'user-data', cached: false });
|
return ctx.json({ text, cached: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Search files by name
|
// Search files by name
|
||||||
|
|||||||
+4
-1
@@ -1228,12 +1228,15 @@ const ScriptRunner = ({
|
|||||||
{runner.output.map((line, i) => (
|
{runner.output.map((line, i) => (
|
||||||
<span
|
<span
|
||||||
key={i}
|
key={i}
|
||||||
|
// The panel is a fixed dark terminal, so stdout must inherit the <pre>'s light
|
||||||
|
// colour. `text-foreground` follows the app theme and rendered black-on-black in
|
||||||
|
// light mode.
|
||||||
className={
|
className={
|
||||||
line.stream === 'stderr'
|
line.stream === 'stderr'
|
||||||
? 'text-red-400'
|
? 'text-red-400'
|
||||||
: line.stream === 'system'
|
: line.stream === 'system'
|
||||||
? 'text-duck-teal/70'
|
? 'text-duck-teal/70'
|
||||||
: 'text-foreground'
|
: undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{line.text}
|
{line.text}
|
||||||
|
|||||||
Reference in New Issue
Block a user