160 lines
3.9 KiB
TypeScript
160 lines
3.9 KiB
TypeScript
|
|
|
|
import Fastify, { FastifyPluginCallback, FastifyReply, FastifyRequest, FastifyReplyContext, FastifyPluginAsync, FastifyServerOptions } from 'fastify'
|
|
import fastifySwagger from '@fastify/swagger'
|
|
import fastifySwaggerUi from '@fastify/swagger-ui'
|
|
import { readFileSync } from 'node:fs'
|
|
import { fileURLToPath } from 'url'
|
|
import { dirname, join } from 'node:path'
|
|
import { Config } from './config'
|
|
import { VtuberRecord, VtuberResponse, VtuberDataScrape } from './schemas.ts'
|
|
import scrapeVtuberData from './scrapeVtuberData.ts'
|
|
import { getPlaylistUrl } from './ytdlp.ts'
|
|
import { getRandomRoom } from './cb.ts'
|
|
import { getPackageVersion } from '@futureporn/utils/file.ts'
|
|
|
|
|
|
type VtuberDataRequest = FastifyRequest<{
|
|
Querystring: { url: string }
|
|
}>
|
|
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const swaggerDarkCss = readFileSync(join(__dirname, './css/SwaggerDark.css'), { encoding: 'utf-8' })
|
|
const version = getPackageVersion(join(__dirname, '../package.json'))
|
|
|
|
|
|
async function fastifySetup(configs: Config) {
|
|
|
|
const fastify = Fastify({
|
|
logger: true
|
|
})
|
|
|
|
|
|
await fastify.register(fastifySwagger, {
|
|
openapi: {
|
|
info: {
|
|
title: '@futureporn/scout',
|
|
description: 'Vtuber data acquisition API',
|
|
version
|
|
},
|
|
}
|
|
})
|
|
await fastify.register(fastifySwaggerUi, {
|
|
theme: {
|
|
title: '@fp/scout',
|
|
css: [
|
|
{ filename: 'SwaggerDark.css', content: swaggerDarkCss }
|
|
]
|
|
},
|
|
routePrefix: '/',
|
|
uiConfig: {
|
|
docExpansion: 'list',
|
|
deepLinking: true
|
|
},
|
|
uiHooks: {
|
|
onRequest: function (request: FastifyRequest, reply: FastifyReply, next: any) { next() },
|
|
preHandler: function (request: FastifyRequest, reply: FastifyReply, next: any) { next() }
|
|
},
|
|
staticCSP: true,
|
|
transformStaticCSP: (header: any) => header,
|
|
transformSpecification: (swaggerObject: any, request: FastifyRequest, reply: FastifyReply) => { return swaggerObject },
|
|
transformSpecificationClone: true
|
|
})
|
|
|
|
fastify.addSchema(VtuberResponse)
|
|
fastify.addSchema(VtuberRecord)
|
|
fastify.addSchema(VtuberDataScrape)
|
|
|
|
|
|
|
|
fastify.get('/chaturbate/random-room', {
|
|
schema: {
|
|
response: {
|
|
'2xx': {
|
|
type: 'object'
|
|
}
|
|
},
|
|
tags: ['chaturbate']
|
|
}
|
|
}, async (req, reply) => {
|
|
const room = await getRandomRoom()
|
|
console.log(room)
|
|
reply.type('application/json').send(JSON.stringify(room))
|
|
})
|
|
|
|
|
|
|
|
fastify.get('/ytdlp/playlist-url', {
|
|
schema: {
|
|
querystring: {
|
|
type: 'object',
|
|
properties: {
|
|
url: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
response: {
|
|
'2xx': {
|
|
error: { type: 'boolean' },
|
|
message: { type: 'string' },
|
|
data: { type: 'object', properties: {
|
|
url: { type: 'string' }
|
|
}}
|
|
}
|
|
},
|
|
tags: ['yt-dlp']
|
|
}
|
|
}, async (req: VtuberDataRequest, reply) => {
|
|
try {
|
|
const playlistUrl = await getPlaylistUrl(req.query.url)
|
|
console.log(`playlistUrl=${playlistUrl}`)
|
|
reply.type('application/json').send(JSON.stringify({ data: { url: playlistUrl } }))
|
|
} catch (e) {
|
|
reply.type('application/json').send(JSON.stringify({ data: null, error: e }))
|
|
}
|
|
})
|
|
|
|
|
|
|
|
fastify.get('/vtuber/data', {
|
|
schema: {
|
|
querystring: {
|
|
type: 'object',
|
|
properties: {
|
|
url: {
|
|
type: 'string',
|
|
description: 'URL of a vtuber profile on Chaturbate or Fansly. ex: https://chaturbate.com/projektmelody'
|
|
}
|
|
}
|
|
},
|
|
response: {
|
|
'2xx': { $ref: 'VtuberDataScrape' }
|
|
},
|
|
tags: [
|
|
'vtuber'
|
|
]
|
|
}
|
|
}, async (req: VtuberDataRequest, reply) => {
|
|
console.log(`we received a request with url=${req.query.url}`)
|
|
const data = await scrapeVtuberData(req.query.url)
|
|
reply.type('application/json').send(data)
|
|
})
|
|
|
|
|
|
|
|
fastify.listen({ host: '0.0.0.0', port: configs.port }, function (err, address) {
|
|
console.log(`@futureporn/scout listening on ${address}`)
|
|
if (err) {
|
|
fastify.log.error(err)
|
|
process.exit(1)
|
|
}
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
export default fastifySetup
|