commit 883021c38238c72c4c1f41b740064f07dfbcebd1
parent d1d249ff285ed7b678d2ba4b34ad690620d38d99
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Fri, 2 Oct 2026 01:30:55 -0400
editor: review N7, N8 — the drive is chosen by the link, and a 503 means a drive
The file route and the file delete treat a file as on the media tier only
when it is a link with a tierable name (source-media.* is never tiered); a
dangling link answers 503 only when the channel's media is relocated
(mediaDir) — on an in-place media/ it is a missing file, 404, and the delete
removes the dangling link.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
3 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/editor/app/api/channels/[slug]/videos/[id]/files/[name]/route.ts b/editor/app/api/channels/[slug]/videos/[id]/files/[name]/route.ts
@@ -9,7 +9,7 @@ import {
channelMediaStall,
channelTextStall,
} from "yt-dlp-transcript-common/lib/channelMedia";
-import { classifyEntry } from "yt-dlp-transcript-common/lib/mediaTier";
+import { isTierable } from "yt-dlp-transcript-common/lib/mediaTier";
import {
NOT_ANSWERING,
isDriveNotAnswering,
@@ -143,35 +143,39 @@ export async function GET(
{ error: `Media not read: ${NOT_ANSWERING}.` },
{ status: 503, headers: { "retry-after": "15" } },
);
- // THE DRIVE IS CHOSEN BY THE FILE'S KIND (release 17). A media file (the
- // audio, the raw live chat, a container) is on the media tier's drive —
- // `mediaDir`, reached through its relative link — so its stat goes through
- // that drive's watchdog and a stalled media drive refuses it. A text file is
- // on the corpus disk and is read directly: a stalled media drive never holds
- // a transcript. (A legacy channel's text is on its retired `dataDir`.)
+ // THE DRIVE IS CHOSEN BY WHERE THE FILE IS (release 17). A TIERED file — a
+ // link (the `lstat` says so, on the corpus disk) with a tierable name — is on
+ // the media tier's drive, `mediaDir`, so its stat goes through that drive's
+ // watchdog and a stalled media drive refuses it. Everything else — the text,
+ // and a real file the tier never takes (`source-media.*`, a partial) — is on
+ // the corpus disk and is read directly: a stalled media drive never holds a
+ // transcript. (A legacy channel's whole `data/` is on its retired `dataDir`.)
const channelConfig = await readChannelConfig(paths, slug);
- const isMedia = classifyEntry(name) === "media";
- if (isMedia ? channelMediaStall(channelConfig) : channelTextStall(channelConfig)) {
+ const isLink = await lstat(fullPath)
+ .then((l) => l.isSymbolicLink())
+ .catch(() => false);
+ const onMediaTier = isLink && isTierable(name);
+ if (
+ onMediaTier ? channelMediaStall(channelConfig) : channelTextStall(channelConfig)
+ ) {
return notAnswering();
}
+ const mediaDir = channelConfig?.mediaDir?.trim() || undefined;
const legacyDrive = channelConfig?.dataDir?.trim() || undefined;
- const drive = isMedia
- ? channelConfig?.mediaDir?.trim() || legacyDrive
- : legacyDrive;
+ const drive = onMediaTier ? mediaDir || legacyDrive : legacyDrive;
let stats;
try {
stats = await (drive ? onDrive(drive, () => stat(fullPath)) : stat(fullPath));
} catch (err) {
if (isDriveNotAnswering(err)) return notAnswering();
- // A LINK WHOSE TARGET IS NOT THERE is a tiered file on a media drive that
- // is unmounted (or renamed away): the file exists, its bytes are not
- // reachable now. 503 with a retry, never 404 — a 404 tells a player, and
- // an operator, that there is no such file.
- const isLink = await lstat(fullPath)
- .then((l) => l.isSymbolicLink())
- .catch(() => false);
- if (isLink) {
+ // A LINK WHOSE TARGET IS NOT THERE, on a channel whose media is on
+ // another drive, is a tiered file on a drive that is unmounted (or renamed
+ // away): the file exists, its bytes are not reachable now. 503 with a
+ // retry, never 404 — a 404 tells a player, and an operator, that there is
+ // no such file. On an in-place `media/` (no `mediaDir`) a dangling link is
+ // a file that is gone, and that IS a 404 (review N8).
+ if (onMediaTier && mediaDir) {
return NextResponse.json(
{
error:
diff --git a/editor/app/channels/[slug]/lib/videoDirFiles.ts b/editor/app/channels/[slug]/lib/videoDirFiles.ts
@@ -1,7 +1,7 @@
import path from "node:path";
import { lstat, readdir, stat } from "node:fs/promises";
import type { Dirent } from "node:fs";
-import { classifyEntry } from "yt-dlp-transcript-common/lib/mediaTier";
+import { isTierable } from "yt-dlp-transcript-common/lib/mediaTier";
import { onDrive } from "yt-dlp-transcript-common/lib/storageHealth";
import type { VideoFile } from "../videos/[id]/components/cards/videoFiles";
@@ -52,7 +52,7 @@ export async function loadVideoDirFiles(
const sizes = new Map<string, number>();
const statLinks = async (kind: "media" | "other") => {
for (const e of links) {
- const isMedia = classifyEntry(e.name) === "media";
+ const isMedia = isTierable(e.name);
if ((kind === "media") !== isMedia) continue;
const s = await stat(path.join(videoDir, e.name)).catch(() => null);
if (s?.isFile()) sizes.set(e.name, s.size);
diff --git a/editor/app/channels/[slug]/videos/[id]/videoActions.ts b/editor/app/channels/[slug]/videos/[id]/videoActions.ts
@@ -41,7 +41,7 @@ import {
inspectChannelMedia,
} from "yt-dlp-transcript-common/lib/channelMedia";
import { onDrive } from "yt-dlp-transcript-common/lib/storageHealth";
-import { classifyEntry } from "yt-dlp-transcript-common/lib/mediaTier";
+import { isTierable } from "yt-dlp-transcript-common/lib/mediaTier";
import { setExcludedFromTruncatedCheck } from "yt-dlp-transcript-common/lib/excludeTruncatedCheck-server";
import { pruneFailedTranscriptions } from "yt-dlp-transcript-common/controller/failedTranscriptions";
import { transcodeAudio } from "yt-dlp-transcript-common/controller/transcode";
@@ -499,10 +499,14 @@ export async function deleteVideoFileAction(
if (!target) {
return { ok: false, error: `Refusing to delete suspicious filename "${filename}"` };
}
- // A media file's stat is asked of the media tier's drive, through its
- // watchdog (release 17: the file may be a link onto a relocated drive).
+ // A TIERED file's stat — a link (the `lstat`) with a tierable name — is
+ // asked of the media tier's drive, through its watchdog (release 17); a
+ // real file, `source-media.*` included, is on the corpus disk (review N7).
+ const linked = await lstat(target)
+ .then((l) => l.isSymbolicLink())
+ .catch(() => false);
const mediaDrive =
- classifyEntry(path.basename(target)) === "media"
+ linked && isTierable(path.basename(target))
? (await readChannelConfig(getPaths(), slug))?.mediaDir?.trim()
: undefined;
let s;
@@ -513,10 +517,7 @@ export async function deleteVideoFileAction(
} catch {
// A TIERED FILE WHOSE DRIVE IS NOT THERE: removing the link alone would
// orphan its bytes on that drive, so nothing is removed.
- const isLink = await lstat(target)
- .then((l) => l.isSymbolicLink())
- .catch(() => false);
- if (isLink) {
+ if (linked && mediaDrive) {
return {
ok: false,
error:
@@ -524,6 +525,14 @@ export async function deleteVideoFileAction(
`or not answering — nothing was deleted.`,
};
}
+ // A dangling link on an in-place `media/`: its bytes are already gone, so
+ // the link is all there is to remove (review N8).
+ if (linked) {
+ await removeMediaFile(videoDir, path.basename(target));
+ revalidatePath(`/channels/${slug}/videos/${videoId}`);
+ requestChannelSnapshot(getPaths(), slug);
+ return { ok: true };
+ }
return { ok: false, error: `File not found: ${filename}` };
}
if (!s.isFile()) {