use buttplug svg
This commit is contained in:
parent
3ffbcbab8e
commit
e0e10fd926
@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
echo(" * Remux the .ts to .mp4 using `ffmpeg -i 2025-08-25T00-12-24Z.ts -c copy projektmelody-chaturbate-2025-08-24.mp4")
|
||||
echo(" If multiple files, use `ffmpeg -f concat -safe 0 -i ./files.txt -c copy ./projektmelody-chaturbate-2025-08-24.mp4`")
|
||||
echo(" [Press Enter When Complete...]")
|
||||
_ = stdin()
|
||||
|
||||
|
@ -57,7 +57,7 @@ RUN npm run build
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
# Install torrentfile & other python deps
|
||||
# Install python deps
|
||||
RUN ./venv/bin/pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Expose the port
|
||||
|
30
services/our/build.mjs
Normal file
30
services/our/build.mjs
Normal file
@ -0,0 +1,30 @@
|
||||
// build.mjs
|
||||
import esbuild from "esbuild";
|
||||
import copyStaticFiles from "esbuild-copy-static-files";
|
||||
|
||||
const build = async () => {
|
||||
console.log("🏗️ Building...");
|
||||
await esbuild.build({
|
||||
entryPoints: ["./src/client/index.js", './src/client/vod.js'],
|
||||
outdir: "./dist/client",
|
||||
bundle: true,
|
||||
minify: true,
|
||||
sourcemap: true,
|
||||
platform: "browser",
|
||||
target: "es2020",
|
||||
logLevel: "info",
|
||||
color: true,
|
||||
plugins: [
|
||||
copyStaticFiles({
|
||||
src: "./src/assets",
|
||||
dest: "./dist/client",
|
||||
recursive: true,
|
||||
})
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
build().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
1306
services/our/package-lock.json
generated
1306
services/our/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -4,11 +4,13 @@
|
||||
"version": "2.5.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently npm:dev:serve npm:dev:build npm:dev:worker npm:dev:compose npm:dev:sftp",
|
||||
"dev": "concurrently npm:dev:serve npm:dev:build:server npm:dev:build:client npm:dev:worker npm:dev:compose npm:dev:sftp",
|
||||
"dev:serve": "npx @dotenvx/dotenvx run -f ../../.env.development.local -- tsx watch ./src/index.ts",
|
||||
"dev:compose": "docker compose -f compose.development.yaml up",
|
||||
"dev:worker": "npx @dotenvx/dotenvx run -e GRAPHILE_LOGGER_DEBUG=1 -f ../../.env.development.local -- tsx watch ./src/worker.ts",
|
||||
"dev:build": "chokidar 'src/**/*.{js,ts}' -c tsup --clean",
|
||||
"dev:build": "echo please use either dev:build:server or dev:build:client",
|
||||
"dev:build:server": "chokidar 'src/**/*.{js,ts}' --ignore 'src/client/**' -c tsup --clean",
|
||||
"dev:build:client": "chokidar 'src/client/**/*.{js,css}' -c 'node build.mjs'",
|
||||
"dev:sftp": "docker run -p 2222:22 --rm atmoz/sftp user:pass:::watch",
|
||||
"start": "echo please use either start:server or start:worker; exit 1",
|
||||
"start:server": "tsx ./src/index.ts",
|
||||
@ -24,6 +26,9 @@
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.3.1",
|
||||
"@eslint/js": "^9.31.0",
|
||||
"chokidar": "^4.0.3",
|
||||
"esbuild": "^0.25.9",
|
||||
"esbuild-copy-static-files": "^0.1.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-plugin-svelte": "^3.10.1",
|
||||
"globals": "^16.3.0",
|
||||
@ -31,7 +36,11 @@
|
||||
"prisma": "6.8.2",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.36.0",
|
||||
"vitest": "^3.2.4"
|
||||
"video.js": "^8.23.4",
|
||||
"videojs-contrib-quality-levels": "^4.1.0",
|
||||
"videojs-hls-quality-selector": "^2.0.0",
|
||||
"vitest": "^3.2.4",
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
@ -58,6 +67,7 @@
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@prisma/client": "6.8.2",
|
||||
"@prisma/extension-accelerate": "^1.3.0",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^22.16.3",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"cache-manager": "^7.0.1",
|
||||
@ -67,10 +77,11 @@
|
||||
"create-torrent": "^6.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"fastify": "^5.4.0",
|
||||
"fastify-favicon": "^5.0.0",
|
||||
"fastify-plugin": "^5.0.1",
|
||||
"fastify-sse-v2": "^4.2.1",
|
||||
"form-data": "^4.0.3",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fs-extra": "^11.3.1",
|
||||
"graphile-worker": "^0.16.6",
|
||||
"handlebars": "4.7.8",
|
||||
"jdenticon": "^3.3.0",
|
||||
@ -84,8 +95,6 @@
|
||||
"onnxruntime-node": "1.22.0-rev",
|
||||
"pino": "^9.7.0",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"pnpm": "^10.14.0",
|
||||
"protobufjs": "^7.5.3",
|
||||
"rate-limiter-flexible": "^7.1.1",
|
||||
"rimraf": "6.0.1",
|
||||
"sharp": "^0.34.3",
|
||||
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Vod" ADD COLUMN "sourceVideoDuration" INTEGER;
|
@ -0,0 +1,4 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Vod" ADD COLUMN "sourceAudioCodec" TEXT,
|
||||
ADD COLUMN "sourceVideoCodec" TEXT,
|
||||
ADD COLUMN "sourceVideoFps" DOUBLE PRECISION;
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `funscript` on the `Vod` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Vod" DROP COLUMN "funscript",
|
||||
ADD COLUMN "funscriptThrust" TEXT,
|
||||
ADD COLUMN "funscriptVibrate" TEXT;
|
@ -71,21 +71,26 @@ model Vod {
|
||||
uploaderId String // previously in Upload
|
||||
uploader User @relation(fields: [uploaderId], references: [id])
|
||||
|
||||
streamDate DateTime
|
||||
notes String?
|
||||
segmentKeys Json?
|
||||
sourceVideo String?
|
||||
hlsPlaylist String?
|
||||
thumbnail String?
|
||||
asrVttKey String?
|
||||
slvttSheetKeys Json?
|
||||
slvttVTTKey String?
|
||||
magnetLink String?
|
||||
streamDate DateTime
|
||||
notes String?
|
||||
segmentKeys Json?
|
||||
sourceVideo String?
|
||||
sourceVideoDuration Int? // milliseconds
|
||||
sourceVideoCodec String?
|
||||
sourceAudioCodec String?
|
||||
sourceVideoFps Float?
|
||||
hlsPlaylist String?
|
||||
thumbnail String?
|
||||
asrVttKey String?
|
||||
slvttSheetKeys Json?
|
||||
slvttVTTKey String?
|
||||
magnetLink String?
|
||||
|
||||
status VodStatus @default(pending)
|
||||
sha256sum String?
|
||||
cidv1 String?
|
||||
funscript String?
|
||||
status VodStatus @default(pending)
|
||||
sha256sum String?
|
||||
cidv1 String?
|
||||
funscriptVibrate String?
|
||||
funscriptThrust String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
@ -10,7 +10,7 @@ import adminRoutes from './plugins/admin'
|
||||
import hls from './plugins/hls.ts'
|
||||
import fastifyStatic from '@fastify/static'
|
||||
import fastifySecureSession from '@fastify/secure-session'
|
||||
import path, { basename } from 'node:path'
|
||||
import path, { basename, resolve } from 'node:path'
|
||||
import fastifyFormbody from '@fastify/formbody'
|
||||
import fastifyView from "@fastify/view"
|
||||
import { env } from './config/env'
|
||||
@ -21,102 +21,19 @@ import graphileWorker from './plugins/graphileWorker'
|
||||
import fastifySwagger from "@fastify/swagger"
|
||||
import fastifySwaggerUi from "@fastify/swagger-ui"
|
||||
import { join } from 'node:path'
|
||||
import { format } from 'date-fns'
|
||||
import * as jdenticon from 'jdenticon'
|
||||
import { Role } from '../generated/prisma'
|
||||
import fastifyFlash from '@fastify/flash'
|
||||
import { isModerator, hasRole } from './utils/privs'
|
||||
import { signUrl } from './utils/cdn'
|
||||
import { extractBasePath } from './utils/filesystem'
|
||||
import { truncate } from './utils/formatters.ts'
|
||||
import { icons } from './utils/icons.ts'
|
||||
import logger from './utils/logger.ts'
|
||||
import fastifyCaching from '@fastify/caching'
|
||||
import { registerHbsHelpers } from './utils/hbsHelpers.ts'
|
||||
import fastifyFavicon from 'fastify-favicon'
|
||||
|
||||
export function buildApp() {
|
||||
const __dirname = import.meta.dirname;
|
||||
|
||||
export async function buildApp() {
|
||||
const app = Fastify()
|
||||
|
||||
Handlebars.registerHelper('formatDate', function (dateString) {
|
||||
if (!dateString) return ''
|
||||
return format(new Date(dateString), 'yyyy-MM-dd')
|
||||
})
|
||||
Handlebars.registerHelper('identicon', function (str, size = 48) {
|
||||
return jdenticon.toSvg(str, size)
|
||||
})
|
||||
Handlebars.registerHelper('safeJson', function (context) {
|
||||
return new Handlebars.SafeString(JSON.stringify(context));
|
||||
});
|
||||
Handlebars.registerHelper('json', function (context) {
|
||||
return JSON.stringify(context)
|
||||
})
|
||||
Handlebars.registerHelper('patron', function (user) {
|
||||
if (!user.roles) {
|
||||
throw new Error(
|
||||
'patron hbs helper was called without roles. This usually means you forgot to include roles relationship in the query.'
|
||||
);
|
||||
}
|
||||
return user.roles.some((r: Role) => r.name.startsWith('supporter'));
|
||||
});
|
||||
Handlebars.registerHelper('notEqual', function (a, b) {
|
||||
return a !== b;
|
||||
});
|
||||
Handlebars.registerHelper('isEqual', function (a, b) {
|
||||
logger.trace(`isEqual a=${a} b=${b}`)
|
||||
return a == b
|
||||
});
|
||||
Handlebars.registerHelper('isModerator', function (user) {
|
||||
return isModerator(user)
|
||||
})
|
||||
Handlebars.registerHelper('hasRole', hasRole)
|
||||
Handlebars.registerHelper('breaklines', function (text) {
|
||||
text = Handlebars.Utils.escapeExpression(text);
|
||||
text = text.replace(/(\r\n|\n|\r)/gm, '<br>');
|
||||
return new Handlebars.SafeString(text);
|
||||
});
|
||||
Handlebars.registerHelper('getCdnUrl', function (s3Key) {
|
||||
// Before you remove this log, find a way to memoize this function!
|
||||
logger.info(`getCdnUrl called with CDN_ORIGIN=${env.CDN_ORIGIN} and CDN_TOKEN_SECRET=${env.CDN_TOKEN_SECRET}`)
|
||||
return signUrl(`${env.CDN_ORIGIN}/${s3Key}`, {
|
||||
securityKey: env.CDN_TOKEN_SECRET,
|
||||
expirationTime: constants.timeUnits.sevenDaysInSeconds,
|
||||
})
|
||||
})
|
||||
/**
|
||||
* @see https://github.com/video-dev/hls.js/issues/2152
|
||||
*/
|
||||
Handlebars.registerHelper('signedHlsUrl', function (s3Key) {
|
||||
if (!s3Key) throw new Error(`signedHlsUrl called with falsy s3Key=${s3Key}`);
|
||||
const pathAllowed = extractBasePath(s3Key)
|
||||
const url = signUrl(`${env.CDN_ORIGIN}/${s3Key}`, {
|
||||
securityKey: env.CDN_TOKEN_SECRET,
|
||||
pathAllowed,
|
||||
isDirectory: true,
|
||||
expirationTime: constants.timeUnits.sevenDaysInSeconds,
|
||||
})
|
||||
logger.debug(`pathAllowed=${pathAllowed} url=${url}`)
|
||||
return url
|
||||
})
|
||||
Handlebars.registerHelper('basename', function (url: string) {
|
||||
return basename(url)
|
||||
})
|
||||
Handlebars.registerHelper('trunc', function (str, length = 6) {
|
||||
return truncate(str, length)
|
||||
});
|
||||
Handlebars.registerHelper('icon', function (name: string, size = 20) {
|
||||
const svg = icons[name];
|
||||
registerHbsHelpers(Handlebars)
|
||||
|
||||
if (!svg) {
|
||||
return new Handlebars.SafeString(`<!-- icon "${name}" not found -->`);
|
||||
}
|
||||
|
||||
// Inject width/height if not already set
|
||||
const sizedSvg = svg
|
||||
.replace(/<svg([^>]*)>/, `<svg$1 width="${size}" height="${size}">`);
|
||||
|
||||
return new Handlebars.SafeString(sizedSvg);
|
||||
});
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
const swaggerOptions = {
|
||||
swagger: {
|
||||
info: {
|
||||
@ -136,12 +53,18 @@ export function buildApp() {
|
||||
exposeRoute: true,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
app.register(fastifySwagger, swaggerOptions);
|
||||
app.register(fastifySwaggerUi, swaggerUiOptions);
|
||||
|
||||
|
||||
|
||||
app.register(fastifyFavicon, { path: path.join(__dirname, '..', 'dist', 'client'), name: 'favicon.ico', maxAge: 3600 })
|
||||
app.register(fastifyStatic, {
|
||||
root: path.join(__dirname, 'assets'),
|
||||
prefix: '/', // optional: default '/'
|
||||
root: path.join(__dirname, '..', 'dist', 'client'),
|
||||
prefix: '/assets', // optional: default '/'
|
||||
constraints: {} // optional: default {}
|
||||
})
|
||||
app.register(fastifyFormbody)
|
||||
@ -192,6 +115,8 @@ export function buildApp() {
|
||||
app.register(hls)
|
||||
app.register(vodsRoutes)
|
||||
|
||||
|
||||
|
||||
app.register(streamsRoutes)
|
||||
app.register(vtubersRoutes)
|
||||
app.register(uploadsRoutes)
|
||||
@ -200,5 +125,6 @@ export function buildApp() {
|
||||
app.register(adminRoutes)
|
||||
app.register(authRoutes)
|
||||
|
||||
|
||||
return app
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user