Compare commits
No commits in common. "4fd262dc6001f4a2a3d9c7deb91cea10f63cca96" and "cdc963c42c2e67cfc68255d77a40e1f557e09144" have entirely different histories.
4fd262dc60
...
cdc963c42c
|
@ -1,16 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="children">
|
<div class="children">
|
||||||
<div
|
<EntityTile
|
||||||
v-for="child in entity.children"
|
v-for="child in entity.children"
|
||||||
:key="`child-${child.id}`"
|
:key="`child-${child.id}`"
|
||||||
class="tile-container"
|
|
||||||
>
|
|
||||||
<EntityTile
|
|
||||||
:entity="child"
|
:entity="child"
|
||||||
@load="(event) => $emit('load', event)"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -20,7 +15,6 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
EntityTile,
|
EntityTile,
|
||||||
},
|
},
|
||||||
emits: ['load'],
|
|
||||||
props: {
|
props: {
|
||||||
entity: {
|
entity: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -39,14 +33,13 @@ export default {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin: 0 1rem 0 0;
|
margin: 0 1rem 0 0;
|
||||||
border-bottom: solid 1px var(--darken-hint);
|
border-bottom: solid 1px var(--darken-hint);
|
||||||
|
overflow-x: auto;
|
||||||
.tile-container {
|
scroll-behavior: smooth;
|
||||||
display: inline-block;
|
scrollbar-width: none;
|
||||||
padding: 0 1rem 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tile {
|
.tile {
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
|
margin: 0 1rem 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.expanded {
|
&.expanded {
|
||||||
|
@ -59,6 +52,10 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint0) {
|
@media(max-width: $breakpoint0) {
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
>
|
>
|
||||||
<Scroll
|
<Scroll
|
||||||
v-if="entity.children.length > 0"
|
v-if="entity.children.length > 0"
|
||||||
v-slot="scroll"
|
|
||||||
:expanded="expanded"
|
:expanded="expanded"
|
||||||
class="scroll-dark"
|
class="scroll-dark"
|
||||||
@expand="(state) => expanded = state"
|
@expand="(state) => expanded = state"
|
||||||
|
@ -89,7 +88,6 @@
|
||||||
<Children
|
<Children
|
||||||
:entity="entity"
|
:entity="entity"
|
||||||
:class="{ expanded }"
|
:class="{ expanded }"
|
||||||
@load="scroll.loaded"
|
|
||||||
/>
|
/>
|
||||||
</Scroll>
|
</Scroll>
|
||||||
|
|
||||||
|
@ -236,10 +234,6 @@ export default {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll {
|
|
||||||
background: var(--profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
.releases {
|
.releases {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,21 @@
|
||||||
v-if="entity.type === 'network' || entity.independent"
|
v-if="entity.type === 'network' || entity.independent"
|
||||||
:src="`/img/logos/${entity.slug}/thumbs/network.png`"
|
:src="`/img/logos/${entity.slug}/thumbs/network.png`"
|
||||||
:alt="entity.name"
|
:alt="entity.name"
|
||||||
loading="lazy"
|
|
||||||
class="logo"
|
class="logo"
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-else-if="entity.parent"
|
v-else-if="entity.parent"
|
||||||
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
|
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
|
||||||
:alt="entity.name"
|
:alt="entity.name"
|
||||||
loading="lazy"
|
|
||||||
class="logo"
|
class="logo"
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`"
|
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`"
|
||||||
:alt="entity.name"
|
:alt="entity.name"
|
||||||
loading="lazy"
|
|
||||||
class="logo"
|
class="logo"
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -48,7 +42,6 @@ export default {
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['load'],
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ function curateActor(actor, release) {
|
||||||
updatedAt: new Date(actor.updatedAt),
|
updatedAt: new Date(actor.updatedAt),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (actor.profiles) {
|
if (actor.profiles && actor.profiles.length > 0) {
|
||||||
const photos = actor.profiles
|
const photos = actor.profiles
|
||||||
.map(profile => ({ entity: profile.entity, ...profile.avatar }))
|
.map(profile => ({ entity: profile.entity, ...profile.avatar }))
|
||||||
.filter(avatar => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash));
|
.filter(avatar => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash));
|
||||||
|
|
|
@ -240,6 +240,8 @@ exports.up = knex => Promise.resolve()
|
||||||
table.text('slug', 32)
|
table.text('slug', 32)
|
||||||
.notNullable();
|
.notNullable();
|
||||||
|
|
||||||
|
table.text('real_name');
|
||||||
|
|
||||||
table.integer('entity_id', 12)
|
table.integer('entity_id', 12)
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('entities');
|
.inTable('entities');
|
||||||
|
@ -250,8 +252,6 @@ exports.up = knex => Promise.resolve()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('actors');
|
.inTable('actors');
|
||||||
|
|
||||||
table.text('real_name');
|
|
||||||
|
|
||||||
table.date('date_of_birth');
|
table.date('date_of_birth');
|
||||||
table.date('date_of_death');
|
table.date('date_of_death');
|
||||||
table.integer('age', 3);
|
table.integer('age', 3);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.151.0",
|
"version": "1.150.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -8156,24 +8156,6 @@
|
||||||
"make-iterator": "^1.0.0"
|
"make-iterator": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"object.omit": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==",
|
|
||||||
"requires": {
|
|
||||||
"is-extendable": "^1.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"is-extendable": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
|
||||||
"requires": {
|
|
||||||
"is-plain-object": "^2.0.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"object.pick": {
|
"object.pick": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.151.0",
|
"version": "1.150.1",
|
||||||
"description": "All the latest porn releases in one place",
|
"description": "All the latest porn releases in one place",
|
||||||
"main": "src/app.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -111,7 +111,6 @@
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"nanoid": "^2.1.11",
|
"nanoid": "^2.1.11",
|
||||||
"object-merge-advanced": "^10.12.1",
|
"object-merge-advanced": "^10.12.1",
|
||||||
"object.omit": "^3.0.0",
|
|
||||||
"opn": "^5.5.0",
|
"opn": "^5.5.0",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
"postgraphile": "^4.10.0",
|
"postgraphile": "^4.10.0",
|
||||||
|
|
|
@ -7,7 +7,6 @@ const moment = require('moment');
|
||||||
const blake2 = require('blake2');
|
const blake2 = require('blake2');
|
||||||
const DOMPurify = require('dompurify');
|
const DOMPurify = require('dompurify');
|
||||||
const { JSDOM } = require('jsdom');
|
const { JSDOM } = require('jsdom');
|
||||||
const omit = require('object.omit');
|
|
||||||
|
|
||||||
const { window } = new JSDOM('');
|
const { window } = new JSDOM('');
|
||||||
const domPurify = DOMPurify(window);
|
const domPurify = DOMPurify(window);
|
||||||
|
@ -22,8 +21,7 @@ const bulkInsert = require('./utils/bulk-insert');
|
||||||
const logger = require('./logger')(__filename);
|
const logger = require('./logger')(__filename);
|
||||||
|
|
||||||
const { toBaseReleases } = require('./deep');
|
const { toBaseReleases } = require('./deep');
|
||||||
const { associateAvatars, flushOrphanedMedia } = require('./media');
|
const { associateAvatars } = require('./media');
|
||||||
const { deleteScenes } = require('./releases');
|
|
||||||
|
|
||||||
const slugify = require('./utils/slugify');
|
const slugify = require('./utils/slugify');
|
||||||
const capitalize = require('./utils/capitalize');
|
const capitalize = require('./utils/capitalize');
|
||||||
|
@ -438,26 +436,18 @@ async function curateProfile(profile, actor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchProfiles(actorIdsOrNames) {
|
async function interpolateProfiles(actorIdsOrNames) {
|
||||||
return knex('actors_profiles')
|
const profiles = await knex('actors_profiles')
|
||||||
.select(knex.raw('actors_profiles.*, row_to_json(actors) as actor, row_to_json(media) as avatar'))
|
.select('actors_profiles.*', knex.raw('row_to_json(media) as avatar'))
|
||||||
.leftJoin('actors', 'actors.id', 'actors_profiles.actor_id')
|
.leftJoin('actors', 'actors.id', 'actors_profiles.actor_id')
|
||||||
.modify((query) => {
|
.modify((query) => {
|
||||||
if (actorIdsOrNames) {
|
if (actorIdsOrNames?.length > 0) {
|
||||||
query
|
query
|
||||||
.whereIn('actor_id', actorIdsOrNames.filter(idOrName => typeof idOrName === 'number'))
|
.whereIn('actor_id', actorIdsOrNames.filter(idOrName => typeof idOrName === 'number'))
|
||||||
.orWhere((builder) => {
|
.orWhereIn('actors.name', actorIdsOrNames.filter(idOrName => typeof idOrName === 'string'));
|
||||||
builder
|
|
||||||
.whereIn('actors.name', actorIdsOrNames.filter(idOrName => typeof idOrName === 'string'))
|
|
||||||
.whereNull('actors.entity_id');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.leftJoin('media', 'actors_profiles.avatar_media_id', 'media.id');
|
.leftJoin('media', 'actors_profiles.avatar_media_id', 'media.id');
|
||||||
}
|
|
||||||
|
|
||||||
async function interpolateProfiles(actorIdsOrNames) {
|
|
||||||
const profiles = await fetchProfiles(actorIdsOrNames);
|
|
||||||
|
|
||||||
const profilesByActorId = profiles.reduce((acc, profile) => ({
|
const profilesByActorId = profiles.reduce((acc, profile) => ({
|
||||||
...acc,
|
...acc,
|
||||||
|
@ -555,27 +545,6 @@ async function interpolateProfiles(actorIdsOrNames) {
|
||||||
|
|
||||||
const transaction = await knex.transaction();
|
const transaction = await knex.transaction();
|
||||||
|
|
||||||
// clear existing interpolated data
|
|
||||||
const emptyProfile = Object
|
|
||||||
.keys(omit(curateProfileEntry({ id: 1 }), ['id', 'actor_id', 'entity_id', 'url', 'description_hash']))
|
|
||||||
.reduce((acc, key) => ({ ...acc, [key]: null }), {});
|
|
||||||
|
|
||||||
await knex('actors')
|
|
||||||
.modify((modifyBuilder) => {
|
|
||||||
if (actorIdsOrNames) {
|
|
||||||
modifyBuilder
|
|
||||||
.whereIn('id', actorIdsOrNames.filter(idOrName => typeof idOrName === 'number'))
|
|
||||||
.orWhere((whereBuilder) => {
|
|
||||||
whereBuilder
|
|
||||||
.whereIn('name', actorIdsOrNames.filter(idOrName => typeof idOrName === 'string'))
|
|
||||||
.whereNull('entity_id');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.update(emptyProfile)
|
|
||||||
.transacting(transaction);
|
|
||||||
|
|
||||||
// insert new interpolated data
|
|
||||||
const queries = interpolatedProfiles.map(profile => knex('actors')
|
const queries = interpolatedProfiles.map(profile => knex('actors')
|
||||||
.where('id', profile.id)
|
.where('id', profile.id)
|
||||||
.update(profile)
|
.update(profile)
|
||||||
|
@ -933,62 +902,11 @@ async function searchActors(query) {
|
||||||
return actors.map(actor => curateActor(actor));
|
return actors.map(actor => curateActor(actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flushProfiles(actorIdsOrNames) {
|
|
||||||
const profiles = await fetchProfiles(actorIdsOrNames);
|
|
||||||
const actorNames = Array.from(new Set(profiles.map(profile => profile.actor.name)));
|
|
||||||
|
|
||||||
const deleteCount = await knex('actors_profiles')
|
|
||||||
.whereIn('id', profiles.map(profile => profile.id))
|
|
||||||
.delete();
|
|
||||||
|
|
||||||
await interpolateProfiles(actorIdsOrNames);
|
|
||||||
await flushOrphanedMedia(); // don't flush until main avatar is detached by re-interpolating
|
|
||||||
|
|
||||||
if (actorNames.length > 20) {
|
|
||||||
logger.info(`Removed ${deleteCount} profiles for ${actorNames.length} actors`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleteCount > 0) {
|
|
||||||
logger.info(`Removed ${deleteCount} profiles for ${actorNames.join(', ')}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(`Removed ${deleteCount} profiles`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function flushActors(actorIdsOrNames) {
|
|
||||||
const actors = await knex('actors')
|
|
||||||
.whereIn('id', actorIdsOrNames.filter(idOrName => typeof idOrName === 'number'))
|
|
||||||
.orWhereIn('name', actorIdsOrNames.filter(idOrName => typeof idOrName === 'string'));
|
|
||||||
|
|
||||||
const actorIds = actors.map(actor => actor.id);
|
|
||||||
|
|
||||||
const sceneIds = await knex('releases_actors')
|
|
||||||
.select('releases.id')
|
|
||||||
.whereIn('actor_id', actorIds)
|
|
||||||
.leftJoin('releases', 'releases.id', 'releases_actors.release_id')
|
|
||||||
.pluck('id');
|
|
||||||
|
|
||||||
const [deletedScenesCount, deletedActorsCount] = await Promise.all([
|
|
||||||
deleteScenes(sceneIds),
|
|
||||||
knex('actors')
|
|
||||||
.whereIn('id', actorIds)
|
|
||||||
.delete(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await flushOrphanedMedia();
|
|
||||||
|
|
||||||
logger.info(`Removed ${deletedActorsCount} actors with ${deletedScenesCount} scenes`);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
associateActors,
|
associateActors,
|
||||||
fetchActor,
|
fetchActor,
|
||||||
flushActors,
|
|
||||||
flushProfiles,
|
|
||||||
interpolateProfiles,
|
|
||||||
scrapeActors,
|
scrapeActors,
|
||||||
searchActors,
|
searchActors,
|
||||||
toBaseActors,
|
toBaseActors,
|
||||||
|
interpolateProfiles,
|
||||||
};
|
};
|
||||||
|
|
12
src/app.js
12
src/app.js
|
@ -9,7 +9,7 @@ const knex = require('./knex');
|
||||||
const fetchUpdates = require('./updates');
|
const fetchUpdates = require('./updates');
|
||||||
const { fetchScenes, fetchMovies } = require('./deep');
|
const { fetchScenes, fetchMovies } = require('./deep');
|
||||||
const { storeScenes, storeMovies, updateReleasesSearch } = require('./store-releases');
|
const { storeScenes, storeMovies, updateReleasesSearch } = require('./store-releases');
|
||||||
const { scrapeActors, flushActors, flushProfiles, interpolateProfiles } = require('./actors');
|
const { scrapeActors, interpolateProfiles } = require('./actors');
|
||||||
const { flushEntities } = require('./entities');
|
const { flushEntities } = require('./entities');
|
||||||
const { deleteScenes, deleteMovies, flushBatches } = require('./releases');
|
const { deleteScenes, deleteMovies, flushBatches } = require('./releases');
|
||||||
const { flushOrphanedMedia } = require('./media');
|
const { flushOrphanedMedia } = require('./media');
|
||||||
|
@ -26,15 +26,7 @@ async function init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.interpolateProfiles) {
|
if (argv.interpolateProfiles) {
|
||||||
await interpolateProfiles(argv.flushProfiles.length > 0 ? argv.flushProfiles : null);
|
await interpolateProfiles(argv.interpolateProfiles);
|
||||||
}
|
|
||||||
|
|
||||||
if (argv.flushActors) {
|
|
||||||
await flushActors(argv.flushActors);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argv.flushProfiles) {
|
|
||||||
await flushProfiles(argv.flushProfiles.length > 0 ? argv.flushProfiles : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.flushNetworks || argv.flushChannels) {
|
if (argv.flushNetworks || argv.flushChannels) {
|
||||||
|
|
10
src/argv.js
10
src/argv.js
|
@ -268,16 +268,6 @@ const { argv } = yargs
|
||||||
type: 'array',
|
type: 'array',
|
||||||
alias: 'flush-network',
|
alias: 'flush-network',
|
||||||
})
|
})
|
||||||
.option('flush-actors', {
|
|
||||||
describe: 'Delete actors with profiles and scenes.',
|
|
||||||
type: 'array',
|
|
||||||
alias: 'flush-actor',
|
|
||||||
})
|
|
||||||
.option('flush-profiles', {
|
|
||||||
describe: 'Delete all profiles for an actor.',
|
|
||||||
type: 'array',
|
|
||||||
alias: 'flush-profile',
|
|
||||||
})
|
|
||||||
.option('flush-batches', {
|
.option('flush-batches', {
|
||||||
describe: 'Delete all scenes and movies from batch by ID.',
|
describe: 'Delete all scenes and movies from batch by ID.',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
|
|
@ -779,7 +779,6 @@ async function flushOrphanedMedia() {
|
||||||
knex('releases_teasers').select('media_id'),
|
knex('releases_teasers').select('media_id'),
|
||||||
knex('movies_covers').select('media_id'),
|
knex('movies_covers').select('media_id'),
|
||||||
knex('movies_trailers').select('media_id'),
|
knex('movies_trailers').select('media_id'),
|
||||||
knex('actors').select(knex.raw('avatar_media_id as media_id')),
|
|
||||||
knex('actors_profiles').select(knex.raw('avatar_media_id as media_id')),
|
knex('actors_profiles').select(knex.raw('avatar_media_id as media_id')),
|
||||||
knex('actors_photos').select('media_id'),
|
knex('actors_photos').select('media_id'),
|
||||||
knex('clips_photos').select('media_id'),
|
knex('clips_photos').select('media_id'),
|
||||||
|
|
|
@ -168,12 +168,6 @@ function filterInternalDuplicateReleases(releases) {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!release.entryId) {
|
|
||||||
logger.warn(`No entry ID supplied for "${release.title}" from '${release.entity.name}'`);
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!acc[release.entity.id]) {
|
if (!acc[release.entity.id]) {
|
||||||
acc[release.entity.id] = {};
|
acc[release.entity.id] = {};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue