'use strict'; const fs = require('fs'); const knex = require('../knex'); const args = require('../argv'); async function getStashId(stash, user) { const existingStash = await knex('stashes') .select('id') .where('user_id', user.id) .where((builder) => { if (stash.primary) { builder.where('primary', true); return; } builder.where('slug', stash.slug); }) .first(); if (existingStash) { return existingStash.id; } const [{ id: stashId }] = await knex('stashes') .insert({ user_id: user.id, name: stash.name, slug: stash.slug, public: stash.public, created_at: stash.createdAt, }) .returning('id'); return stashId; } async function importReleases(type, stash, user, filename) { const curatedType = type === 'release' ? 'scene' : type; await stash[`${curatedType}s`].reduce(async (chain, scene) => { await chain; const release = await knex(`${type}s`) .select(`${type}s.id`, 'entities.id as entity_id', 'entities.name as entity_name') .leftJoin('entities', 'entities.id', `${type}s.entity_id`) .where(`${type}s.entry_id`, scene.entryId) .where('entities.slug', scene.entitySlug) .where('entities.type', scene.entityType) .first(); if (!release) { throw new Error(`${curatedType.slice(0, 1).toUpperCase}${curatedType.slice(1)} ${scene.title} in ${scene.entityType} ${scene.entitySlug} does not exist`); } await knex(`stashes_${curatedType}s`) .insert({ stash_id: stash.id, [`${curatedType}_id`]: release.id, comment: `import ${filename}`, created_at: scene.createdAt, }) .onConflict(['stash_id', `${curatedType}_id`]) .ignore(); if (args.logLevel === 'verbose') { console.log(`Imported ${stash.username} stash ${release.entity_name} ${curatedType} "${scene.title}"`); } }, Promise.resolve()); } async function importActors(stash, user, filename) { await stash.actors.reduce(async (chain, actor) => { await chain; const actorEntry = await knex('actors') .select('actors.*') .leftJoin('entities', 'entities.id', 'actors.entity_id') .where('actors.slug', actor.slug) .where((builder) => { if (actor.entitySlug) { builder .where('entities.slug', actor.entitySlug) .where('entities.type', actor.entityType); } }) .first(); if (!actorEntry) { throw new Error(`Actor ${actor.slug} in ${user.username} stash ${stash.name} does not exist`); } await knex('stashes_actors') .insert({ stash_id: stash.id, actor_id: actorEntry.id, comment: `import ${filename}`, created_at: actor.createdAt, }) .onConflict(['stash_id', 'actor_id']) .ignore(); if (args.logLevel === 'verbose') { console.log(`Imported ${stash.username} stash actor "${actorEntry.name}"`); } }, Promise.resolve()); } async function load() { const filename = process.argv[2]; const file = await fs.promises.readFile(filename, 'utf8'); const stashes = file.split('\n') .filter(Boolean) .map((data) => JSON.parse(data)) .filter((stash) => !args.username || stash.username === args.username); await stashes.reduce(async (stashChain, stash, index) => { await stashChain; const user = await knex('users') .select('id') .where('username', stash.username.trim()) .first(); if (!user) { console.warn(`No user '${stash.username}'`); return; } const stashId = await getStashId(stash, user); await importReleases('release', { ...stash, id: stashId }, user, filename); await importReleases('movie', { ...stash, id: stashId }, user, filename); await importActors({ ...stash, id: stashId }, user, filename); console.log(`Imported ${index + 1}/${stashes.length} stash ${stash.name} from ${stash.username}`); }, Promise.resolve()); process.exit(); } load();