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), ]);