Integrated Manticore sync, assuming responsibility from traxxx core/legacy.

This commit is contained in:
2026-06-08 05:18:11 +02:00
parent a048970be6
commit 1bc7dd3a43
15 changed files with 776 additions and 7 deletions

43
tools/manticore-actors.js Normal file
View File

@@ -0,0 +1,43 @@
import argv from '../src/argv.js';
import { knexOwner as knex } from '../src/knex.js';
import { utilsApi } from '../src/manticore.js';
import { syncManticoreActors } from '../src/sync.js';
async function init() {
if (argv.update) {
await utilsApi.sql('drop table if exists actors');
await utilsApi.sql(`create table actors(
id int,
name text,
slug string,
entity_id int,
gender string,
date_of_birth timestamp,
country string,
has_avatar bool,
mass int,
height int,
cup string,
natural_boobs int,
penis_length int,
penis_girth int,
stashed int,
scenes int
) min_prefix_len = '3'`);
console.log('Recreated actors table, syncing actors...');
const data = await syncManticoreActors();
console.log('data', data);
knex.destroy();
return;
}
knex.destroy();
}
init();

45
tools/manticore-movies.js Normal file
View File

@@ -0,0 +1,45 @@
import argv from '../src/argv.js';
import { knexOwner as knex } from '../src/knex.js';
import { utilsApi } from '../src/manticore.js';
import { syncManticoreMovies } from '../src/sync.js';
async function init() {
if (argv.update) {
await utilsApi.sql('drop table if exists movies');
await utilsApi.sql(`create table movies (
id int,
title text,
title_filtered text,
channel_id int,
channel_name text,
channel_slug text,
network_id int,
network_name text,
network_slug text,
entity_ids multi,
actor_ids multi,
actors text,
tag_ids multi,
tags text,
meta text,
date timestamp,
has_cover bool,
created_at timestamp,
effective_date timestamp,
stashed int,
stashed_scenes int,
stashed_total int,
dupe_index int
)`);
console.log('Recreated movies tables, syncing movies...');
const data = await syncManticoreMovies();
console.log('data', data);
}
knex.destroy();
}
init();

59
tools/manticore-scenes.js Normal file
View File

@@ -0,0 +1,59 @@
import argv from '../src/argv.js';
import { knexOwner as knex } from '../src/knex.js';
import { utilsApi } from '../src/manticore.js';
import { syncManticoreScenes } from '../src/sync.js';
async function init() {
if (argv.update) {
await utilsApi.sql('drop table if exists scenes');
await utilsApi.sql(`create table scenes (
id int,
title text,
title_filtered text,
entry_id text,
shoot_id text,
channel_id int,
channel_name text,
channel_slug text,
network_id int,
network_name text,
network_slug text,
studio_id int,
studio_name text,
studio_slug text,
entity_ids multi,
actor_ids multi,
actors text,
tag_ids multi,
tags text,
movie_ids multi,
movies text,
serie_ids multi,
series text,
meta text,
date timestamp,
fingerprints text,
is_showcased bool,
created_at timestamp,
effective_date timestamp,
stashed int,
dupe_index int
)`);
await utilsApi.sql('drop table if exists scenes_tags');
await utilsApi.sql(`create table scenes_tags (
id int,
scene_id int,
tag_id int,
actor_id int
)`);
console.log('Recreated scenes tables, syncing scenes...');
await syncManticoreScenes();
}
knex.destroy();
}
init();

View File

@@ -0,0 +1,42 @@
import { knexOwner as knex } from '../src/knex.js';
import { utilsApi } from '../src/manticore.js';
import { syncStashes } from '../src/sync.js';
async function init() {
await utilsApi.sql('drop table if exists scenes_stashed');
await utilsApi.sql(`create table if not exists scenes_stashed (
scene_id int,
stash_id int,
user_id int,
created_at timestamp
)`);
await utilsApi.sql('drop table if exists movies_stashed');
await utilsApi.sql(`create table if not exists movies_stashed (
movie_id int,
stash_id int,
user_id int,
created_at timestamp
)`);
await utilsApi.sql('drop table if exists actors_stashed');
await utilsApi.sql(`create table if not exists actors_stashed (
actor_id int,
stash_id int,
user_id int,
created_at timestamp
)`);
console.log('Recreated stash tables, syncing stashes...');
await syncStashes('scene');
await syncStashes('actor');
await syncStashes('movie');
knex.destroy();
}
init();

View File

@@ -0,0 +1,80 @@
import { MerkleJson } from 'merkle-json';
import knex from '../knex.js';
const mj = new MerkleJson();
function curateTag(tag) {
if (Object.hasOwn(tag, 'actorId')) {
return {
id: tag.id,
actorId: tag.actorId,
};
}
if (typeof tag === 'number') {
return {
id: tag,
// can't restore actorId, don't set to null to hint at missing data
};
}
throw new Error(`Unrecognized tag delta: ${JSON.stringify(tag)}`);
}
async function init() {
const revisions = await knex('scenes_revisions');
// console.log(revisions);
const fixedRevisions = revisions.map((revision) => {
if (revision.base.tags.length === 0 && !revision.deltas.some((delta) => delta.key === 'tags')) {
return null;
}
const newDeltas = revision.deltas.map((delta) => {
if (delta.key !== 'tags') {
return delta;
}
return {
...delta,
value: delta.value.map((tag) => curateTag(tag)),
};
});
const newBase = {
...revision.base,
tags: revision.base.tags.map((tag) => curateTag(tag)),
};
return {
...revision,
deltas: newDeltas,
base: newBase,
};
}).filter(Boolean);
const entries = fixedRevisions.map((revision) => ({
id: revision.id,
base: JSON.stringify(revision.base),
deltas: JSON.stringify(revision.deltas),
hash: mj.hash({
base: revision.base,
deltas: revision.deltas,
}),
}));
console.log(entries);
await knex('scenes_revisions')
.insert(entries)
.onConflict('id')
.merge(['base', 'deltas', 'hash']);
console.log(`Fixed ${entries.length} revisions`);
await knex.destroy();
}
init();

32
tools/slugify-test.js Normal file
View File

@@ -0,0 +1,32 @@
import slugify from '../utils/slugify.js';
function init() {
const cases = [
'Brave, New World',
'Jœrgenbahn Straße',
'Partêrre',
'Ápres ski.',
'very 😀 true 😃',
'a véééry long piece of text that should not result in a very long slug, even for $100',
'don\'t you, forget about me',
'Pneumonoultramicroscopicsilicovolcanoconiosis',
'this (old) spicemen[sic]',
'contact@example.com',
'!@#$%',
'',
' ',
['this is', '2026-01-01', 'an array', '', ' ', 'test'],
];
cases.forEach((item) => console.log(item, '-->', slugify(item, '-', { limit: 20 })));
cases.forEach((item) => console.log(item, '-->', slugify(item, '-', {
lower: true,
accents: false,
punctuation: false,
symbols: 'split',
limit: 50,
})));
}
init();