118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
import { PrismaClient } from '../generated/prisma';
|
|
import pg from 'pg';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
const v1 = new pg.Pool({
|
|
host: process.env.V1_DB_HOST || 'localhost',
|
|
port: +(process.env.V1_DB_PORT || '5444'),
|
|
user: process.env.V1_DB_USER || 'postgres',
|
|
password: process.env.V1_DB_PASS || 'password',
|
|
database: process.env.V1_DB_NAME || 'restoredb'
|
|
});
|
|
|
|
// Set this to an existing user ID in v2
|
|
const DEFAULT_UPLOADER_ID = process.env.DEFAULT_UPLOADER_ID || 'REPLACE_WITH_V2_USER_ID';
|
|
|
|
async function migrateVtubers() {
|
|
console.log('Migrating vtubers...');
|
|
const res = await v1.query(`SELECT * FROM vtubers`);
|
|
for (const vt of res.rows) {
|
|
await prisma.vtuber.create({
|
|
data: {
|
|
slug: vt.slug,
|
|
image: vt.image,
|
|
displayName: vt.display_name,
|
|
chaturbate: vt.chaturbate,
|
|
twitter: vt.twitter,
|
|
patreon: vt.patreon,
|
|
twitch: vt.twitch,
|
|
tiktok: vt.tiktok,
|
|
onlyfans: vt.onlyfans,
|
|
youtube: vt.youtube,
|
|
linktree: vt.linktree,
|
|
carrd: vt.carrd,
|
|
fansly: vt.fansly,
|
|
pornhub: vt.pornhub,
|
|
discord: vt.discord,
|
|
reddit: vt.reddit,
|
|
throne: vt.throne,
|
|
instagram: vt.instagram,
|
|
facebook: vt.facebook,
|
|
merch: vt.merch,
|
|
description: `${vt.description_1 ?? ''}\n${vt.description_2 ?? ''}`.trim() || null,
|
|
themeColor: vt.theme_color,
|
|
uploaderId: DEFAULT_UPLOADER_ID
|
|
}
|
|
});
|
|
}
|
|
console.log(`Migrated ${res.rows.length} vtubers`);
|
|
}
|
|
|
|
async function migrateVods() {
|
|
console.log('Migrating vods...');
|
|
const vods = await v1.query(`SELECT * FROM vods`);
|
|
|
|
for (const vod of vods.rows) {
|
|
// Get linked vtubers
|
|
const vtuberLinks = await v1.query(
|
|
`SELECT vtuber_id FROM vods_vtuber_links WHERE vod_id = $1`,
|
|
[vod.id]
|
|
);
|
|
|
|
let vtuberSlugs: string[] = [];
|
|
if (vtuberLinks.rows.length > 0) {
|
|
const vtuberRes = await v1.query(
|
|
`SELECT slug FROM vtubers WHERE id = ANY($1)`,
|
|
[vtuberLinks.rows.map(r => r.vtuber_id)]
|
|
);
|
|
vtuberSlugs = vtuberRes.rows.map(v => v.slug).filter(Boolean);
|
|
}
|
|
|
|
// Get thumbnail
|
|
const thumbLink = await v1.query(
|
|
`SELECT b2.cdn_url, b2.url FROM vods_thumbnail_links vtl
|
|
JOIN b2_files b2 ON vtl.b_2_file_id = b2.id
|
|
WHERE vtl.vod_id = $1 LIMIT 1`,
|
|
[vod.id]
|
|
);
|
|
|
|
// Get source video
|
|
const videoSrcLink = await v1.query(
|
|
`SELECT b2.cdn_url, b2.url FROM vods_video_src_b_2_links vsl
|
|
JOIN b2_files b2 ON vsl.b_2_file_id = b2.id
|
|
WHERE vsl.vod_id = $1 LIMIT 1`,
|
|
[vod.id]
|
|
);
|
|
|
|
await prisma.vod.create({
|
|
data: {
|
|
uploaderId: DEFAULT_UPLOADER_ID,
|
|
streamDate: vod.date ?? new Date(),
|
|
notes: vod.note,
|
|
sourceVideo: videoSrcLink.rows[0]?.cdn_url || videoSrcLink.rows[0]?.url || null,
|
|
thumbnail: thumbLink.rows[0]?.cdn_url || thumbLink.rows[0]?.url || null,
|
|
vtubers: {
|
|
connect: vtuberSlugs.map(slug => ({ slug }))
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
console.log(`Migrated ${vods.rows.length} vods`);
|
|
}
|
|
|
|
async function main() {
|
|
try {
|
|
await migrateVtubers();
|
|
await migrateVods();
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
await v1.end();
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|
|
|
|
main();
|