Initial commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { assertLocalRequest } from "@/lib/api/localOnly";
|
||||
import { cancelJob } from "@/lib/whisperjav/queue";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
|
||||
const blocked = assertLocalRequest(req);
|
||||
if (blocked) return blocked;
|
||||
|
||||
const { id } = await ctx.params;
|
||||
const ok = cancelJob(id);
|
||||
if (!ok) return NextResponse.json({ error: "Not found or not cancellable" }, { status: 404 });
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import fs from "node:fs/promises";
|
||||
import { assertLocalRequest } from "@/lib/api/localOnly";
|
||||
import { getJob, estimateRealtimeMultiplier } from "@/lib/whisperjav/db";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const LOG_TAIL_LINES = 50;
|
||||
|
||||
export async function GET(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
|
||||
const blocked = assertLocalRequest(req);
|
||||
if (blocked) return blocked;
|
||||
|
||||
const { id } = await ctx.params;
|
||||
const job = getJob(id);
|
||||
if (!job) return NextResponse.json({ error: "Not found" }, { status: 404 });
|
||||
|
||||
let logTail: string[] = [];
|
||||
try {
|
||||
const raw = await fs.readFile(job.logPath, "utf8");
|
||||
const lines = raw.split(/\r?\n/);
|
||||
logTail = lines.slice(-LOG_TAIL_LINES - 1).filter(Boolean);
|
||||
} catch { /* log may not exist yet */ }
|
||||
|
||||
// ETA: per-mode multiplier from history × video duration − elapsed.
|
||||
// Returns null when we can't compute (no duration / not running yet).
|
||||
let etaSec: number | null = null;
|
||||
if (
|
||||
(job.status === "queued" || job.status === "running") &&
|
||||
job.videoDurationSec && job.videoDurationSec > 0 &&
|
||||
job.mode
|
||||
) {
|
||||
const multiplier = estimateRealtimeMultiplier(job.mode);
|
||||
const totalProjected = job.videoDurationSec * multiplier;
|
||||
const start = job.startedAt ?? job.enqueuedAt;
|
||||
const elapsedSec = (Date.now() - start) / 1000;
|
||||
etaSec = Math.max(0, totalProjected - elapsedSec);
|
||||
}
|
||||
|
||||
return NextResponse.json({ ...job, logTail, etaSec });
|
||||
}
|
||||
Reference in New Issue
Block a user