Initial commit

This commit is contained in:
CallMeVerity
2026-06-03 00:44:48 +01:00
commit eb56ad5183
36 changed files with 3419 additions and 0 deletions
+367
View File
@@ -0,0 +1,367 @@
import { Elysia, status } from "elysia";
import {
getAllVideos,
getVideoById,
deleteVideoById,
insertVideo,
updateThumbnailKey,
updateTier,
getVideoByMapAndPlayer,
updateVideoPB,
} from "../services/db";
import {
uploadObject,
deleteObject,
getObjectUrl,
getPresignedUploadUrl,
} from "../services/rustfs";
import { parseMtvFile } from "../services/mtv-parser";
import { getMapInfo } from "../services/momentum-api";
import type { VideoEntry, PreviousPB } from "../types/video";
const ADMIN_TOKEN = process.env.ADMIN_TOKEN;
if (!ADMIN_TOKEN) {
console.error(
"ADMIN_TOKEN environment variable is required. Set it to secure upload/delete endpoints.",
);
process.exit(1);
}
function sanitizeFileName(name: string): string {
return name
.replace(/\s+/g, "_")
.replace(/[^a-zA-Z0-9_.\-]/g, "")
.toLowerCase();
}
export const videoRoutes = new Elysia({ prefix: "/api/videos" })
.guard({
beforeHandle: ({ request }) => {
const isWrite =
request.method !== "GET" &&
request.method !== "HEAD" &&
request.method !== "OPTIONS";
if (isWrite) {
const auth = request.headers.get("authorization");
const token = auth?.startsWith("Bearer ")
? auth.slice(7)
: null;
if (!token || token !== ADMIN_TOKEN)
return status(401, "Unauthorized");
}
},
})
.get("/", () => {
const videos = getAllVideos();
return videos.map((v) => ({
...v,
thumbnailUrl: v.thumbnailUrl
? getObjectUrl(v.thumbnailUrl)
: undefined,
}));
})
.post("/upload-url", async ({ request }) => {
let formData: FormData;
try {
formData = await request.formData();
} catch {
return status(400, { error: "Failed to parse form data" });
}
const mtv = formData.get("mtv") as File | null;
const videoFileName = formData.get("videoFileName") as string | null;
const videoContentType =
(formData.get("videoContentType") as string | null) || "video/webm";
const runDate = formData.get("runDate") as string | null;
if (!mtv || !videoFileName) {
return status(400, {
error: "mtv file and videoFileName are required",
});
}
const mtvBuffer = await mtv.arrayBuffer();
const metadata = parseMtvFile(mtvBuffer);
if (!metadata) {
return status(400, {
error: "Invalid .mtv file: could not parse header",
});
}
const existing = getVideoByMapAndPlayer(
metadata.mapName,
metadata.steamId,
);
if (existing) {
if (existing.runTime <= metadata.runTime) {
return status(409, {
error: `PB not improved. Your current PB on ${metadata.mapName} is ${existing.runTime}, this run is ${metadata.runTime}`,
});
}
const deletes = [
deleteObject(existing.videoKey),
deleteObject(existing.mtvKey),
];
if (existing.thumbnailKey)
deletes.push(deleteObject(existing.thumbnailKey));
await Promise.all(deletes);
const previousPbs: PreviousPB[] = [
{ runTime: existing.runTime, createdAt: existing.createdAt },
...(existing.previousPbs ?? []),
];
const id = existing.id;
const createdAt =
runDate && !isNaN(Date.parse(runDate))
? new Date(runDate).toISOString()
: new Date().toISOString();
const sanitizedVideoName = sanitizeFileName(videoFileName);
const videoKey = `videos/${id}/${sanitizedVideoName}`;
const mtvKey = `videos/${id}/${sanitizeFileName(mtv.name)}`;
await uploadObject(
mtvKey,
Buffer.from(mtvBuffer),
"application/octet-stream",
);
let tier: number | null | undefined;
let mapId: number | null | undefined;
let thumbnailKey: string | undefined;
const mapInfo = await getMapInfo(metadata.mapName);
mapId = mapInfo.mapId ?? undefined;
tier = mapInfo.tier;
if (mapInfo.thumbnailUrl) {
thumbnailKey = `videos/${id}/thumbnail.jpg`;
try {
const imgRes = await fetch(mapInfo.thumbnailUrl);
if (imgRes.ok) {
const imgBuf = Buffer.from(await imgRes.arrayBuffer());
await uploadObject(thumbnailKey, imgBuf, "image/jpeg");
} else {
thumbnailKey = undefined;
}
} catch {
thumbnailKey = undefined;
}
}
const title = `${metadata.mapName} - ${metadata.playerName}`;
const entry: VideoEntry = {
id,
title,
description: "",
mapName: metadata.mapName,
playerName: metadata.playerName,
steamId: metadata.steamId,
runTime: metadata.runTime,
totalTicks: metadata.totalTicks,
tickInterval: metadata.tickInterval,
videoKey,
mtvKey,
thumbnailKey,
tier,
mapId,
jsonStats: metadata.jsonStats,
createdAt,
previousPbs,
};
updateVideoPB(id, entry, previousPbs);
const presignedUrls = {
video: await getPresignedUploadUrl(videoKey, videoContentType),
};
return {
...entry,
presignedUrls,
videoUrl: getObjectUrl(videoKey),
mtvUrl: getObjectUrl(mtvKey),
thumbnailUrl: thumbnailKey
? getObjectUrl(thumbnailKey)
: undefined,
};
}
const id = crypto.randomUUID();
const createdAt =
runDate && !isNaN(Date.parse(runDate))
? new Date(runDate).toISOString()
: new Date().toISOString();
const sanitizedVideoName = sanitizeFileName(videoFileName);
const videoKey = `videos/${id}/${sanitizedVideoName}`;
const mtvKey = `videos/${id}/${sanitizeFileName(mtv.name)}`;
await uploadObject(
mtvKey,
Buffer.from(mtvBuffer),
"application/octet-stream",
);
let tier: number | null | undefined;
let mapId: number | null | undefined;
let thumbnailKey: string | undefined;
const mapInfo = await getMapInfo(metadata.mapName);
mapId = mapInfo.mapId ?? undefined;
tier = mapInfo.tier;
if (mapInfo.thumbnailUrl) {
thumbnailKey = `videos/${id}/thumbnail.jpg`;
try {
const imgRes = await fetch(mapInfo.thumbnailUrl);
if (imgRes.ok) {
const imgBuf = Buffer.from(await imgRes.arrayBuffer());
await uploadObject(thumbnailKey, imgBuf, "image/jpeg");
} else {
thumbnailKey = undefined;
}
} catch {
thumbnailKey = undefined;
}
}
const title = `${metadata.mapName} - ${metadata.playerName}`;
const entry: VideoEntry = {
id,
title,
description: "",
mapName: metadata.mapName,
playerName: metadata.playerName,
steamId: metadata.steamId,
runTime: metadata.runTime,
totalTicks: metadata.totalTicks,
tickInterval: metadata.tickInterval,
videoKey,
mtvKey,
thumbnailKey,
tier,
mapId,
jsonStats: metadata.jsonStats,
createdAt,
};
insertVideo(entry);
const presignedUrls = {
video: await getPresignedUploadUrl(videoKey, videoContentType),
};
return {
...entry,
presignedUrls,
videoUrl: getObjectUrl(videoKey),
mtvUrl: getObjectUrl(mtvKey),
thumbnailUrl: thumbnailKey ? getObjectUrl(thumbnailKey) : undefined,
};
})
.post("/:id/complete", async ({ params: { id } }) => {
const video = getVideoById(id);
if (!video) return status(404, { error: "Not found" });
return {
...video,
videoUrl: getObjectUrl(video.videoKey),
mtvUrl: getObjectUrl(video.mtvKey),
thumbnailUrl: video.thumbnailKey
? getObjectUrl(video.thumbnailKey)
: undefined,
};
})
.get("/:id", ({ params: { id } }) => {
const video = getVideoById(id);
if (!video) return status(404, { error: "Not found" });
return {
...video,
videoUrl: getObjectUrl(video.videoKey),
mtvUrl: getObjectUrl(video.mtvKey),
thumbnailUrl: video.thumbnailKey
? getObjectUrl(video.thumbnailKey)
: undefined,
};
})
.post("/:id/refresh-info", async ({ params: { id } }) => {
const video = getVideoById(id);
if (!video) return status(404, { error: "Not found" });
const mapInfo = await getMapInfo(video.mapName);
let thumbnailKey = video.thumbnailKey;
if (!thumbnailKey && mapInfo.thumbnailUrl) {
thumbnailKey = `videos/${video.id}/thumbnail.jpg`;
try {
const imgRes = await fetch(mapInfo.thumbnailUrl);
if (imgRes.ok) {
const imgBuf = Buffer.from(await imgRes.arrayBuffer());
await uploadObject(thumbnailKey, imgBuf, "image/jpeg");
updateThumbnailKey(id, thumbnailKey);
} else {
thumbnailKey = undefined;
}
} catch {
thumbnailKey = undefined;
}
}
updateTier(id, mapInfo.tier);
return {
success: true,
tier: mapInfo.tier,
thumbnailUrl: thumbnailKey ? getObjectUrl(thumbnailKey) : undefined,
};
})
.post("/:id/refresh-thumbnail", async ({ params: { id } }) => {
const video = getVideoById(id);
if (!video) return status(404, { error: "Not found" });
const mapInfo = await getMapInfo(video.mapName);
if (!mapInfo.thumbnailUrl) {
return status(404, {
error: `No thumbnail found on Momentum Mod for ${video.mapName}`,
});
}
const thumbnailKey = `videos/${video.id}/thumbnail.jpg`;
try {
const imgRes = await fetch(mapInfo.thumbnailUrl);
if (!imgRes.ok)
return status(502, { error: "Failed to download thumbnail" });
const imgBuf = Buffer.from(await imgRes.arrayBuffer());
await uploadObject(thumbnailKey, imgBuf, "image/jpeg");
} catch {
return status(502, { error: "Failed to download thumbnail" });
}
updateThumbnailKey(id, thumbnailKey);
updateTier(id, mapInfo.tier);
return { success: true, thumbnailUrl: getObjectUrl(thumbnailKey) };
})
.delete("/:id", async ({ params: { id } }) => {
const video = getVideoById(id);
if (!video) return status(404, { error: "Not found" });
const deletes = [
deleteObject(video.videoKey),
deleteObject(video.mtvKey),
];
if (video.thumbnailKey) deletes.push(deleteObject(video.thumbnailKey));
await Promise.all(deletes);
deleteVideoById(id);
return { success: true };
});