import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { env } from '../config/env' import { constants } from '../config/constants' import { type CS3Asset, type S3, uploadFile } from '../utils/s3' import { S3Client } from '@aws-sdk/client-s3' import { isModerator } from '../utils/privs' import { PrismaClient } from '../../generated/prisma' import { withAccelerate } from "@prisma/extension-accelerate" const prisma = new PrismaClient().$extends(withAccelerate()) const s3Resource: S3 = { useSSL: true, port: 443, bucket: env.S3_BUCKET, region: env.S3_REGION, endPoint: env.S3_ENDPOINT, accessKey: env.S3_KEY_ID, pathStyle: env.S3_FORCE_PATH_STYLE, secretKey: env.S3_APPLICATION_KEY } export default async function vodsRoutes( fastify: FastifyInstance, ): Promise { fastify.get('/vods', async function (request, reply) { const userId = request.session.get('userId'); let user = null if (userId !== undefined) { user = await prisma.user.findUnique({ where: { id: userId }, include: { roles: true } }) } const { cursor: cursorRaw, search = '' } = request.query as { cursor?: string; search?: string; }; const cursor = cursorRaw ? parseInt(cursorRaw, 10) : undefined; if (cursorRaw && isNaN(cursor)) { return reply.status(400).send({ error: 'Invalid cursor value' }); } const vods = await prisma.vod.findMany({ where: { status: { in: ['approved', 'processed', 'processing'], }, }, orderBy: { createdAt: 'desc' }, include: { vtubers: true, stream: true, }, }); return reply.viewAsync('vods.hbs', { user, vods, site: constants.site, }, { layout: 'layouts/main.hbs' }); }); fastify.get('/vods/:id', async function (request, reply) { const { id } = request.params as { id: string }; const userId = request.session.get('userId') let user = await prisma.user.findFirst({ where: { id: userId }, include: { roles: true } }) if (!id) { return reply.status(400).send({ error: 'Invalid VOD ID' }); } const vod = await prisma.vod.findUnique({ where: { id }, include: { vtubers: true, stream: true, }, }); if (!vod) { return reply.status(404).send({ error: 'VOD not found' }); } return reply.viewAsync('vod.hbs', { vod, site: constants.site, user, }, { layout: 'layouts/main.hbs' }); }); fastify.post('/vods/:id/process', async function (request, reply) { const { id: vodId } = request.params as { id: string }; const userId = request.session.get('userId') let user = await prisma.user.findFirstOrThrow({ where: { id: userId }, include: { roles: true } }) if (!isModerator(user)) { reply.status(401).send('This endpoint is for moderators only.'); } fastify.graphileWorker.addJob('scheduleVodProcessing', { vodId }) reply.flash const vod = await prisma.vod.findFirstOrThrow({ where: { id: vodId }, include: { stream: true } }) return reply.viewAsync('vod.hbs', { vod, site: constants.site, user, message: 'Successfully scheduled vod processing.' }, { layout: 'layouts/main.hbs' }); }) }