Storing directors.

This commit is contained in:
DebaucheryLibrarian 2021-03-07 00:01:02 +01:00
parent 9ae113ab92
commit 17e6f5a5da
17 changed files with 102 additions and 27 deletions

View File

@ -68,6 +68,20 @@
:tags="release.tags" :tags="release.tags"
/> />
<div
v-if="release.directors"
class="row"
>
<span class="row-label">Director</span>
<router-link
v-for="director in release.directors"
:key="`director-${director.id}`"
class="link director"
:to="`/director/${director.id}/${director.slug}`"
>{{ director.name }}</router-link>
</div>
<div <div
v-if="release.movies && release.movies.length > 0" v-if="release.movies && release.movies.length > 0"
class="row" class="row"
@ -423,6 +437,10 @@ export default {
color: var(--link); color: var(--link);
text-decoration: none; text-decoration: none;
&.director:not(:last-child)::after {
content: ', ';
}
&:hover { &:hover {
color: var(--primary); color: var(--primary);

View File

@ -75,6 +75,7 @@ function curateRelease(release) {
if (release.trailer) curatedRelease.trailer = release.trailer.media; if (release.trailer) curatedRelease.trailer = release.trailer.media;
if (release.teaser) curatedRelease.teaser = release.teaser.media; if (release.teaser) curatedRelease.teaser = release.teaser.media;
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map(actor => curateActor(actor.actor || actor, curatedRelease)); if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map(actor => curateActor(actor.actor || actor, curatedRelease));
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map(director => curateActor(director.director || director, curatedRelease));
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag); if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease)); if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));

View File

@ -82,6 +82,14 @@ const releaseActorsFragment = `
} }
`; `;
const releaseDirectorFragment = `
directors: releasesDirectors(orderBy: ACTOR_BY_DIRECTOR_ID__NAME_ASC) {
director {
${actorFields}
}
}
`;
const releaseTagsFragment = ` const releaseTagsFragment = `
tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) { tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) {
tag { tag {
@ -261,6 +269,7 @@ const releaseFragment = `
comment comment
url url
${releaseActorsFragment} ${releaseActorsFragment}
${releaseDirectorFragment}
${releaseTagsFragment} ${releaseTagsFragment}
${releasePosterFragment} ${releasePosterFragment}
${releasePhotosFragment} ${releasePhotosFragment}

View File

@ -67,6 +67,23 @@ const routes = [
component: Actor, component: Actor,
name: 'actorRange', name: 'actorRange',
}, },
{
path: '/director/:actorId/:actorSlug',
name: 'director',
redirect: from => ({
name: 'directorRange',
params: {
...from.params,
range: 'latest',
pageNumber: 1,
},
}),
},
{
path: '/director/:actorId/:actorSlug',
component: Actor,
name: 'directorRange',
},
{ {
path: '/channel/:entitySlug', path: '/channel/:entitySlug',
redirect: from => ({ redirect: from => ({

View File

@ -599,20 +599,6 @@ exports.up = knex => Promise.resolve()
table.datetime('created_at') table.datetime('created_at')
.defaultTo(knex.fn.now()); .defaultTo(knex.fn.now());
})) }))
.then(() => knex.schema.createTable('directors', (table) => {
table.increments('id', 12);
table.text('name');
table.integer('alias_for', 12)
.references('id')
.inTable('directors');
table.text('slug', 32)
.unique();
table.datetime('created_at')
.defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('releases', (table) => { .then(() => knex.schema.createTable('releases', (table) => {
table.increments('id', 16); table.increments('id', 16);
@ -702,12 +688,21 @@ exports.up = knex => Promise.resolve()
.inTable('releases') .inTable('releases')
.onDelete('cascade'); .onDelete('cascade');
table.integer('director_id', 8) table.integer('director_id', 12)
.notNullable() .notNullable()
.references('id') .references('id')
.inTable('directors'); .inTable('actors')
.onDelete('cascade');
table.integer('alias_id', 12)
.references('id')
.inTable('actors')
.onDelete('cascade');
table.unique(['release_id', 'director_id']); table.unique(['release_id', 'director_id']);
table.datetime('created_at')
.defaultTo(knex.fn.now());
})) }))
.then(() => knex.schema.createTable('releases_posters', (table) => { .then(() => knex.schema.createTable('releases_posters', (table) => {
table.integer('release_id', 16) table.integer('release_id', 16)
@ -1236,7 +1231,6 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS chapters CASCADE; DROP TABLE IF EXISTS chapters CASCADE;
DROP TABLE IF EXISTS releases CASCADE; DROP TABLE IF EXISTS releases CASCADE;
DROP TABLE IF EXISTS actors CASCADE; DROP TABLE IF EXISTS actors CASCADE;
DROP TABLE IF EXISTS directors CASCADE;
DROP TABLE IF EXISTS tags CASCADE; DROP TABLE IF EXISTS tags CASCADE;
DROP TABLE IF EXISTS tags_groups CASCADE; DROP TABLE IF EXISTS tags_groups CASCADE;
DROP TABLE IF EXISTS social CASCADE; DROP TABLE IF EXISTS social CASCADE;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 640 B

View File

@ -2,18 +2,33 @@
"name": "traxxx", "name": "traxxx",
"short_name": "traxxx", "short_name": "traxxx",
"icons": [ "icons": [
{
"src": "/img/favicon/android-chrome-32x32.png",
"sizes": "32x32",
"type": "image/png"
},
{ {
"src": "/img/favicon/android-chrome-192x192.png", "src": "/img/favicon/android-chrome-192x192.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png" "type": "image/png"
}, },
{
"src": "/img/favicon/android-chrome-194x194.png",
"sizes": "194x194",
"type": "image/png"
},
{
"src": "/img/favicon/android-chrome-196x196.png",
"sizes": "194x194",
"type": "image/png"
},
{ {
"src": "/img/favicon/android-chrome-512x512.png", "src": "/img/favicon/android-chrome-512x512.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png" "type": "image/png"
} }
], ],
"theme_color": "#ffffff", "theme_color": "#ff6c88",
"background_color": "#ffffff", "background_color": "#ffffff",
"display": "standalone" "display": "standalone"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -841,6 +841,7 @@ const tagPhotos = [
['fake-cum', 3, 'Alexia Anders in "Thanksgiving Creampies" for Cum 4K'], ['fake-cum', 3, 'Alexia Anders in "Thanksgiving Creampies" for Cum 4K'],
['fake-cum', 0, 'Jynx Maze for Cumshot Surprise (Porn Pros)'], ['fake-cum', 0, 'Jynx Maze for Cumshot Surprise (Porn Pros)'],
['fake-cum', 1, 'Ricki White for Fucked Up Facials'], ['fake-cum', 1, 'Ricki White for Fucked Up Facials'],
['fake-cum', 4, 'Vina Sky in "Creaming Her Pipes" for Anal 4K'],
['femdom', 1, 'Little Caprice in "Femdom" for Little Caprice Dreams'], ['femdom', 1, 'Little Caprice in "Femdom" for Little Caprice Dreams'],
['fingering', 2, 'Kylie Page and Hadley Viscara in "Busty Blonde Bombshells" for LesbianX'], ['fingering', 2, 'Kylie Page and Hadley Viscara in "Busty Blonde Bombshells" for LesbianX'],
['fingering', 0, 'Ashly Anderson in "Rough Love" for Hookup Hotshot'], ['fingering', 0, 'Ashly Anderson in "Rough Love" for Hookup Hotshot'],

View File

@ -760,8 +760,6 @@ async function scrapeActors(argNames) {
const actorNames = await getActorNames(argNames); const actorNames = await getActorNames(argNames);
const baseActors = toBaseActors(actorNames); const baseActors = toBaseActors(actorNames);
console.log(baseActors);
logger.info(`Scraping profiles for ${actorNames.length} actors`); logger.info(`Scraping profiles for ${actorNames.length} actors`);
const sources = argv.profileSources || config.profiles || Object.keys(scrapers.actors); const sources = argv.profileSources || config.profiles || Object.keys(scrapers.actors);
@ -898,13 +896,17 @@ async function getOrCreateActors(baseActors, batchId) {
return existingActors; return existingActors;
} }
async function associateActors(releases, batchId) { async function associatePeople(releases, batchId, type = 'actor') {
try { try {
const baseActorsByReleaseId = releases.reduce((acc, release) => { const baseActorsByReleaseId = releases.reduce((acc, release) => {
if (release.actors) { if (type === 'actors' && release.actors) {
acc[release.id] = toBaseActors(release.actors, release); acc[release.id] = toBaseActors(release.actors, release);
} }
if (type === 'directors' && release.director) {
acc[release.id] = toBaseActors([release.director], release);
}
return acc; return acc;
}, {}); }, {});
@ -922,6 +924,11 @@ async function associateActors(releases, batchId) {
const uniqueBaseActors = Object.values(baseActorsBySlug); const uniqueBaseActors = Object.values(baseActorsBySlug);
const actors = await getOrCreateActors(uniqueBaseActors, batchId); const actors = await getOrCreateActors(uniqueBaseActors, batchId);
const personKey = ({
actors: 'actor_id',
directors: 'director_id',
})[type];
const actorIdsByEntityIdEntryIdAndSlug = actors.reduce((acc, actor) => ({ const actorIdsByEntityIdEntryIdAndSlug = actors.reduce((acc, actor) => ({
...acc, ...acc,
[actor.entity_id]: { [actor.entity_id]: {
@ -929,7 +936,7 @@ async function associateActors(releases, batchId) {
[actor.entry_id]: { [actor.entry_id]: {
...acc[actor.entity_id]?.[actor.entry_id], ...acc[actor.entity_id]?.[actor.entry_id],
[actor.slug]: { [actor.slug]: {
actor_id: actor.alias_for || actor.id, [personKey]: actor.alias_for || actor.id,
alias_id: actor.alias_for ? actor.id : null, alias_id: actor.alias_for ? actor.id : null,
}, },
}, },
@ -944,15 +951,15 @@ async function associateActors(releases, batchId) {
}))) })))
.flat(); .flat();
const validReleaseActorAssociations = releaseActorAssociations.filter(association => association.release_id && association.actor_id); const validReleaseActorAssociations = releaseActorAssociations.filter(association => association.release_id && association[personKey]);
if (releaseActorAssociations.length > validReleaseActorAssociations.length) { if (releaseActorAssociations.length > validReleaseActorAssociations.length) {
const invalidReleaseActorAssociations = releaseActorAssociations.filter(association => !association.release_id || !association.actor_id); const invalidReleaseActorAssociations = releaseActorAssociations.filter(association => !association.release_id || !association[personKey]);
logger.error(invalidReleaseActorAssociations); logger.error(invalidReleaseActorAssociations);
} }
await bulkInsert('releases_actors', validReleaseActorAssociations, false); await bulkInsert(`releases_${type}`, validReleaseActorAssociations, false);
logger.verbose(`Associated ${releaseActorAssociations.length} actors to ${releases.length} scenes`); logger.verbose(`Associated ${releaseActorAssociations.length} actors to ${releases.length} scenes`);
@ -964,6 +971,14 @@ async function associateActors(releases, batchId) {
} }
} }
async function associateActors(releases, batchId) {
return associatePeople(releases, batchId, 'actors');
}
async function associateDirectors(releases, batchId) {
return associatePeople(releases, batchId, 'directors');
}
async function fetchActor(actorId) { async function fetchActor(actorId) {
const actor = await knex('actors') const actor = await knex('actors')
.select(knex.raw(` .select(knex.raw(`
@ -1081,6 +1096,7 @@ async function flushActors() {
module.exports = { module.exports = {
associateActors, associateActors,
associateDirectors,
deleteActors, deleteActors,
fetchActor, fetchActor,
flushActors, flushActors,

View File

@ -9,7 +9,7 @@ const slugify = require('./utils/slugify');
const bulkInsert = require('./utils/bulk-insert'); const bulkInsert = require('./utils/bulk-insert');
const resolvePlace = require('./utils/resolve-place'); const resolvePlace = require('./utils/resolve-place');
const { formatDate } = require('./utils/qu'); const { formatDate } = require('./utils/qu');
const { associateActors, scrapeActors, toBaseActors } = require('./actors'); const { associateActors, associateDirectors, scrapeActors, toBaseActors } = require('./actors');
const { associateReleaseTags } = require('./tags'); const { associateReleaseTags } = require('./tags');
const { curateEntity } = require('./entities'); const { curateEntity } = require('./entities');
const { associateReleaseMedia } = require('./media'); const { associateReleaseMedia } = require('./media');
@ -229,6 +229,7 @@ async function updateReleasesSearch(releaseIds) {
COALESCE(releases.shoot_id, '') || ' ' || COALESCE(releases.shoot_id, '') || ' ' ||
COALESCE(TO_CHAR(releases.date, 'YYYY YY MM FMMM FMmonth mon DD FMDD'), '') || ' ' || COALESCE(TO_CHAR(releases.date, 'YYYY YY MM FMMM FMmonth mon DD FMDD'), '') || ' ' ||
STRING_AGG(COALESCE(actors.name, ''), ' ') || ' ' || STRING_AGG(COALESCE(actors.name, ''), ' ') || ' ' ||
STRING_AGG(COALESCE(directors.name, ''), ' ') || ' ' ||
STRING_AGG(COALESCE(tags.name, ''), ' ') || ' ' || STRING_AGG(COALESCE(tags.name, ''), ' ') || ' ' ||
STRING_AGG(COALESCE(tags_aliases.name, ''), ' ') STRING_AGG(COALESCE(tags_aliases.name, ''), ' ')
) as document ) as document
@ -236,8 +237,10 @@ async function updateReleasesSearch(releaseIds) {
LEFT JOIN entities ON releases.entity_id = entities.id LEFT JOIN entities ON releases.entity_id = entities.id
LEFT JOIN entities AS parents ON parents.id = entities.parent_id LEFT JOIN entities AS parents ON parents.id = entities.parent_id
LEFT JOIN releases_actors AS local_actors ON local_actors.release_id = releases.id LEFT JOIN releases_actors AS local_actors ON local_actors.release_id = releases.id
LEFT JOIN releases_directors AS local_directors ON local_directors.release_id = releases.id
LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id
LEFT JOIN actors ON local_actors.actor_id = actors.id LEFT JOIN actors ON local_actors.actor_id = actors.id
LEFT JOIN actors AS directors ON local_directors.director_id = directors.id
LEFT JOIN tags ON local_tags.tag_id = tags.id AND tags.priority >= 6 LEFT JOIN tags ON local_tags.tag_id = tags.id AND tags.priority >= 6
LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true
${releaseIds ? 'WHERE releases.id = ANY(?)' : ''} ${releaseIds ? 'WHERE releases.id = ANY(?)' : ''}
@ -319,6 +322,7 @@ async function storeScenes(releases) {
const [actors] = await Promise.all([ const [actors] = await Promise.all([
associateActors(releasesWithId, batchId), associateActors(releasesWithId, batchId),
associateDirectors(releasesWithId, batchId),
associateReleaseTags(releasesWithId), associateReleaseTags(releasesWithId),
storeChapters(releasesWithId), storeChapters(releasesWithId),
]); ]);