Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit e082d44f08184d7b1d5c3199c273033a94b6ed3a
parent a876362bfbc5e25da67265d18f90631a961f6c6e
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 25 Sep 2026 12:38:52 -0400

editor: keepVideosAction — the bulk form of the do-not-clean toggle

Revalidates each marked video and the channel page, and requests the
channel snapshot ONCE per batch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Meditor/app/channels/[slug]/videos/[id]/videoActions.ts | 47+++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+), 0 deletions(-)

diff --git a/editor/app/channels/[slug]/videos/[id]/videoActions.ts b/editor/app/channels/[slug]/videos/[id]/videoActions.ts @@ -29,6 +29,13 @@ import { } from "yt-dlp-transcript-common/lib/queueKeys"; import { readChannelConfig } from "yt-dlp-transcript-common/controller/channels"; import { setDoNotClean } from "yt-dlp-transcript-common/lib/doNotClean-server"; +import { + KeepVideosError, + keepVideosMatching, + type KeepVideosField, + type KeepVideosResult, +} from "yt-dlp-transcript-common/controller/keepVideosMatching"; +import { ChannelMediaUnreachableError } from "yt-dlp-transcript-common/lib/channelMedia"; 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"; @@ -640,6 +647,46 @@ export async function toggleDoNotCleanAction( return { ok: true }; } +// The BULK form of the toggle above: set the do-not-clean marker on every video +// of one channel whose title / description matches `pattern` (the download +// filter's matcher and subject — see common/controller/keepVideosMatching.ts). +// No UI calls it yet; `pnpm ops keep-videos` does. Same revalidation as the +// toggle, per marked video, and ONE snapshot request for the whole batch — the +// snapshot's cleanup buckets exclude kept ids, so it has to be re-derived, but +// once, not once per video. +export async function keepVideosAction(input: { + slug: string; + pattern: string; + fields?: KeepVideosField[]; + note?: string; + dryRun?: boolean; +}): Promise<{ ok: true; result: KeepVideosResult } | { ok: false; error: string }> { + let result: KeepVideosResult; + try { + result = await keepVideosMatching({ + paths: getPaths(), + channelSlug: input.slug, + pattern: input.pattern, + fields: input.fields, + note: input.note, + dryRun: input.dryRun, + }); + } catch (e) { + if (e instanceof KeepVideosError || e instanceof ChannelMediaUnreachableError) { + return { ok: false, error: e.message }; + } + throw e; + } + if (result.marked > 0) { + for (const m of result.matched) { + if (m.marked) revalidatePath(`/channels/${input.slug}/videos/${m.id}`); + } + revalidatePath(`/channels/${input.slug}`); + requestChannelSnapshot(getPaths(), input.slug); + } + return { ok: true, result }; +} + // Opt this video in/out of the truncated/incomplete-transcript check. When // enabled, the snapshot's incompleteTranscript + shortAudio buckets and the // video panel's "looks truncated" banner suppress this id (for videos that