Storing directors.
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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 => ({
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 709 B |
Before Width: | Height: | Size: 640 B After Width: | Height: | Size: 640 B |
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 41 KiB |
|
@ -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'],
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
]);
|
]);
|
||||||
|
|