diff --git a/assets/components/releases/release.vue b/assets/components/releases/release.vue
index 9fa1b199..1810052c 100644
--- a/assets/components/releases/release.vue
+++ b/assets/components/releases/release.vue
@@ -68,6 +68,20 @@
:tags="release.tags"
/>
+
+ Director
+
+ {{ director.name }}
+
+
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.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
diff --git a/assets/js/fragments.js b/assets/js/fragments.js
index 083a74e1..20c3779f 100644
--- a/assets/js/fragments.js
+++ b/assets/js/fragments.js
@@ -82,6 +82,14 @@ const releaseActorsFragment = `
}
`;
+const releaseDirectorFragment = `
+ directors: releasesDirectors(orderBy: ACTOR_BY_DIRECTOR_ID__NAME_ASC) {
+ director {
+ ${actorFields}
+ }
+ }
+`;
+
const releaseTagsFragment = `
tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) {
tag {
@@ -261,6 +269,7 @@ const releaseFragment = `
comment
url
${releaseActorsFragment}
+ ${releaseDirectorFragment}
${releaseTagsFragment}
${releasePosterFragment}
${releasePhotosFragment}
diff --git a/assets/js/router.js b/assets/js/router.js
index 1ef29b75..a88af9e9 100644
--- a/assets/js/router.js
+++ b/assets/js/router.js
@@ -67,6 +67,23 @@ const routes = [
component: Actor,
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',
redirect: from => ({
diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js
index 85bed018..0e713681 100644
--- a/migrations/20190325001339_releases.js
+++ b/migrations/20190325001339_releases.js
@@ -599,20 +599,6 @@ exports.up = knex => Promise.resolve()
table.datetime('created_at')
.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) => {
table.increments('id', 16);
@@ -702,12 +688,21 @@ exports.up = knex => Promise.resolve()
.inTable('releases')
.onDelete('cascade');
- table.integer('director_id', 8)
+ table.integer('director_id', 12)
.notNullable()
.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.datetime('created_at')
+ .defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('releases_posters', (table) => {
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 releases CASCADE;
DROP TABLE IF EXISTS actors CASCADE;
- DROP TABLE IF EXISTS directors CASCADE;
DROP TABLE IF EXISTS tags CASCADE;
DROP TABLE IF EXISTS tags_groups CASCADE;
DROP TABLE IF EXISTS social CASCADE;
diff --git a/public/img/favicon/android-chrome-192x192.png b/public/img/favicon/android-chrome-192x192.png
index 21cfdffb..9fb68239 100644
Binary files a/public/img/favicon/android-chrome-192x192.png and b/public/img/favicon/android-chrome-192x192.png differ
diff --git a/public/img/favicon/android-chrome-194x194.png b/public/img/favicon/android-chrome-194x194.png
new file mode 100755
index 00000000..3c8d32cd
Binary files /dev/null and b/public/img/favicon/android-chrome-194x194.png differ
diff --git a/public/img/favicon/android-chrome-196x196.png b/public/img/favicon/android-chrome-196x196.png
new file mode 100644
index 00000000..d1737b68
Binary files /dev/null and b/public/img/favicon/android-chrome-196x196.png differ
diff --git a/public/img/favicon/android-chrome-32x32.png b/public/img/favicon/android-chrome-32x32.png
new file mode 100755
index 00000000..7512a7d6
Binary files /dev/null and b/public/img/favicon/android-chrome-32x32.png differ
diff --git a/public/img/favicon/favicon-32x32.png b/public/img/favicon/favicon-32x32.png
index 73f82de6..00b28d1d 100644
Binary files a/public/img/favicon/favicon-32x32.png and b/public/img/favicon/favicon-32x32.png differ
diff --git a/public/img/favicon/site.webmanifest b/public/img/favicon/site.webmanifest
index ed370de3..269600a5 100644
--- a/public/img/favicon/site.webmanifest
+++ b/public/img/favicon/site.webmanifest
@@ -2,18 +2,33 @@
"name": "traxxx",
"short_name": "traxxx",
"icons": [
+ {
+ "src": "/img/favicon/android-chrome-32x32.png",
+ "sizes": "32x32",
+ "type": "image/png"
+ },
{
"src": "/img/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"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",
"sizes": "512x512",
"type": "image/png"
}
],
- "theme_color": "#ffffff",
+ "theme_color": "#ff6c88",
"background_color": "#ffffff",
"display": "standalone"
}
diff --git a/public/img/tags/fake-cum/4.jpeg b/public/img/tags/fake-cum/4.jpeg
new file mode 100644
index 00000000..8206b93c
Binary files /dev/null and b/public/img/tags/fake-cum/4.jpeg differ
diff --git a/public/img/tags/fake-cum/lazy/4.jpeg b/public/img/tags/fake-cum/lazy/4.jpeg
new file mode 100644
index 00000000..17c82ebd
Binary files /dev/null and b/public/img/tags/fake-cum/lazy/4.jpeg differ
diff --git a/public/img/tags/fake-cum/thumbs/4.jpeg b/public/img/tags/fake-cum/thumbs/4.jpeg
new file mode 100644
index 00000000..a2e6e5df
Binary files /dev/null and b/public/img/tags/fake-cum/thumbs/4.jpeg differ
diff --git a/seeds/04_media.js b/seeds/04_media.js
index a0850e8a..cb43a73a 100644
--- a/seeds/04_media.js
+++ b/seeds/04_media.js
@@ -841,6 +841,7 @@ const tagPhotos = [
['fake-cum', 3, 'Alexia Anders in "Thanksgiving Creampies" for Cum 4K'],
['fake-cum', 0, 'Jynx Maze for Cumshot Surprise (Porn Pros)'],
['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'],
['fingering', 2, 'Kylie Page and Hadley Viscara in "Busty Blonde Bombshells" for LesbianX'],
['fingering', 0, 'Ashly Anderson in "Rough Love" for Hookup Hotshot'],
diff --git a/src/actors.js b/src/actors.js
index 649262cd..3460e871 100644
--- a/src/actors.js
+++ b/src/actors.js
@@ -760,8 +760,6 @@ async function scrapeActors(argNames) {
const actorNames = await getActorNames(argNames);
const baseActors = toBaseActors(actorNames);
- console.log(baseActors);
-
logger.info(`Scraping profiles for ${actorNames.length} actors`);
const sources = argv.profileSources || config.profiles || Object.keys(scrapers.actors);
@@ -898,13 +896,17 @@ async function getOrCreateActors(baseActors, batchId) {
return existingActors;
}
-async function associateActors(releases, batchId) {
+async function associatePeople(releases, batchId, type = 'actor') {
try {
const baseActorsByReleaseId = releases.reduce((acc, release) => {
- if (release.actors) {
+ if (type === 'actors' && release.actors) {
acc[release.id] = toBaseActors(release.actors, release);
}
+ if (type === 'directors' && release.director) {
+ acc[release.id] = toBaseActors([release.director], release);
+ }
+
return acc;
}, {});
@@ -922,6 +924,11 @@ async function associateActors(releases, batchId) {
const uniqueBaseActors = Object.values(baseActorsBySlug);
const actors = await getOrCreateActors(uniqueBaseActors, batchId);
+ const personKey = ({
+ actors: 'actor_id',
+ directors: 'director_id',
+ })[type];
+
const actorIdsByEntityIdEntryIdAndSlug = actors.reduce((acc, actor) => ({
...acc,
[actor.entity_id]: {
@@ -929,7 +936,7 @@ async function associateActors(releases, batchId) {
[actor.entry_id]: {
...acc[actor.entity_id]?.[actor.entry_id],
[actor.slug]: {
- actor_id: actor.alias_for || actor.id,
+ [personKey]: actor.alias_for || actor.id,
alias_id: actor.alias_for ? actor.id : null,
},
},
@@ -944,15 +951,15 @@ async function associateActors(releases, batchId) {
})))
.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) {
- const invalidReleaseActorAssociations = releaseActorAssociations.filter(association => !association.release_id || !association.actor_id);
+ const invalidReleaseActorAssociations = releaseActorAssociations.filter(association => !association.release_id || !association[personKey]);
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`);
@@ -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) {
const actor = await knex('actors')
.select(knex.raw(`
@@ -1081,6 +1096,7 @@ async function flushActors() {
module.exports = {
associateActors,
+ associateDirectors,
deleteActors,
fetchActor,
flushActors,
diff --git a/src/store-releases.js b/src/store-releases.js
index d85c9d91..c321fda0 100644
--- a/src/store-releases.js
+++ b/src/store-releases.js
@@ -9,7 +9,7 @@ const slugify = require('./utils/slugify');
const bulkInsert = require('./utils/bulk-insert');
const resolvePlace = require('./utils/resolve-place');
const { formatDate } = require('./utils/qu');
-const { associateActors, scrapeActors, toBaseActors } = require('./actors');
+const { associateActors, associateDirectors, scrapeActors, toBaseActors } = require('./actors');
const { associateReleaseTags } = require('./tags');
const { curateEntity } = require('./entities');
const { associateReleaseMedia } = require('./media');
@@ -229,6 +229,7 @@ async function updateReleasesSearch(releaseIds) {
COALESCE(releases.shoot_id, '') || ' ' ||
COALESCE(TO_CHAR(releases.date, 'YYYY YY MM FMMM FMmonth mon DD FMDD'), '') || ' ' ||
STRING_AGG(COALESCE(actors.name, ''), ' ') || ' ' ||
+ STRING_AGG(COALESCE(directors.name, ''), ' ') || ' ' ||
STRING_AGG(COALESCE(tags.name, ''), ' ') || ' ' ||
STRING_AGG(COALESCE(tags_aliases.name, ''), ' ')
) as document
@@ -236,8 +237,10 @@ async function updateReleasesSearch(releaseIds) {
LEFT JOIN entities ON releases.entity_id = entities.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_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 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 as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true
${releaseIds ? 'WHERE releases.id = ANY(?)' : ''}
@@ -319,6 +322,7 @@ async function storeScenes(releases) {
const [actors] = await Promise.all([
associateActors(releasesWithId, batchId),
+ associateDirectors(releasesWithId, batchId),
associateReleaseTags(releasesWithId),
storeChapters(releasesWithId),
]);