diff --git a/assets/components/tags/tags.vue b/assets/components/tags/tags.vue index e719c2b0..f505ef6d 100644 --- a/assets/components/tags/tags.vue +++ b/assets/components/tags/tags.vue @@ -75,6 +75,8 @@ async function mounted() { ], }); + console.log(tags); + this.tags = tags.reduce((acc, tag) => { if (acc[tag.group.slug]) { return { ...acc, [tag.group.slug]: [...acc[tag.group.slug], tag] }; diff --git a/assets/js/curate.js b/assets/js/curate.js index 61ad51d4..f20b0596 100644 --- a/assets/js/curate.js +++ b/assets/js/curate.js @@ -1,12 +1,13 @@ function curateActor(actor) { const curatedActor = { ...actor, - avatar: actor.avatar[0], origin: actor.originCountry && { country: actor.originCountry, }, }; + if (actor.avatar) curatedActor.avatar = actor.avatar.media; + return curatedActor; } @@ -14,17 +15,31 @@ function curateRelease(release) { const curatedRelease = { ...release, actors: release.actors.map(({ actor }) => curateActor(actor)), - poster: release.poster[0], - network: release.site.network, + poster: release.poster && release.poster.media, tags: release.tags.map(({ tag }) => tag), + network: release.site.network, }; - if (release.trailer) [curatedRelease.trailer] = release.trailer; + if (release.photos) curatedRelease.photos = release.photos.map(({ media }) => media); + if (release.trailer) [curatedRelease.trailer] = release.trailer.media; return curatedRelease; } +function curateTag(tag) { + const curatedTag = { + ...tag, + }; + + if (tag.releases) curatedTag.releases = tag.releases.map(({ release }) => curateRelease(release)); + if (tag.photos) curatedTag.photos = tag.photos.map(({ media }) => media); + if (tag.poster) curatedTag.poster = tag.poster.media; + + return curatedTag; +} + export { curateActor, curateRelease, + curateTag, }; diff --git a/assets/js/fragments.js b/assets/js/fragments.js index 26af807b..412f4e12 100644 --- a/assets/js/fragments.js +++ b/assets/js/fragments.js @@ -14,8 +14,8 @@ const siteFragment = ` `; const releaseActorsFragment = ` - actors: releasesActors(orderBy: GENDER_ASC) { - actor: releaseActor { + actors: releasesActorsSortables(orderBy: GENDER_ASC) { + actor { id name slug @@ -26,16 +26,18 @@ const releaseActorsFragment = ` name alias } - avatar: actorsMediasByTargetId(condition: { role: "avatar" }) { - thumbnail + avatar: actorsAvatarByActorId { + media { + thumbnail + } } } } `; const releaseTagsFragment = ` - tags: releasesTagsByTargetId { - tag: releaseTag { + tags: releasesTags { + tag { name priority slug @@ -45,28 +47,34 @@ const releaseTagsFragment = ` `; const releasePosterFragment = ` - poster: releasesMediasByTargetId(condition: { role: "poster" }) { - index - path - thumbnail - comment + poster: releasesPosterByReleaseId { + media { + index + path + thumbnail + comment + } } `; const releasePhotosFragment = ` - photos: releasesMediasByTargetId(condition: { role: "photo" }) { - index - path - thumbnail - comment + photos: releasesPhotos { + media { + index + path + thumbnail + comment + } } `; const releaseTrailerFragment = ` - trailer: releasesMediasByTargetId(condition: { role: "trailer" }) { - index - path - thumbnail + trailer: releasesTrailerByReleaseId { + media { + index + path + thumbnail + } } `; diff --git a/assets/js/tags/actions.js b/assets/js/tags/actions.js index 328605bb..cae5cd0f 100644 --- a/assets/js/tags/actions.js +++ b/assets/js/tags/actions.js @@ -5,18 +5,7 @@ import { releaseTagsFragment, siteFragment, } from '../fragments'; -import { curateRelease } from '../curate'; - -function curateTag(tag) { - const curatedTag = { - ...tag, - }; - - if (tag.releases) curatedTag.releases = tag.releases.map(({ tagRelease }) => curateRelease(tagRelease)); - if (tag.poster) [curatedTag.poster] = tag.poster; - - return curatedTag; -} +import { curateTag } from '../curate'; function initTagsActions(store, _router) { async function fetchTagBySlug(tagSlug) { @@ -31,20 +20,24 @@ function initTagsActions(store, _router) { name slug } - poster: tagsMediasByTargetId(condition: { role: "poster" }) { - id - thumbnail - path - comment + poster: tagsPosterByTagId { + media { + id + thumbnail + path + comment + } } - photos: tagsMediasByTargetId(condition: { role: "photo" }) { - id - thumbnail - path - comment + photos: tagsPhotos { + media { + id + thumbnail + path + comment + } } releases: releasesTags { - tagRelease { + release { id title date @@ -82,8 +75,10 @@ function initTagsActions(store, _router) { id name slug - poster: tagsMediasByTargetId(condition: { role: "poster" }) { - thumbnail + poster: tagsPosterByTagId { + media { + thumbnail + } } group { name diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index 8762dd60..a842425c 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -378,6 +378,19 @@ exports.up = knex => Promise.resolve() table.unique('release_id'); })) + .then(() => knex.schema.createTable('releases_trailers', (table) => { + table.integer('release_id', 16) + .notNullable() + .references('id') + .inTable('releases'); + + table.integer('media_id', 16) + .notNullable() + .references('id') + .inTable('media'); + + table.unique('release_id'); + })) .then(() => knex.schema.createTable('releases_photos', (table) => { table.integer('release_id', 16) .notNullable() @@ -405,27 +418,34 @@ exports.up = knex => Promise.resolve() table.unique(['tag_id', 'release_id']); })) .then(() => knex.raw(` + CREATE VIEW releases_actors_sortable AS + SELECT releases_actors.*, actors.gender, actors.name, actors.birthdate FROM releases_actors + JOIN actors ON releases_actors.actor_id = actors.id; + + COMMENT ON VIEW releases_actors_sortable IS E'@foreignKey (release_id) references releases (id)\n@foreignKey (actor_id) references actors (id)'; + /* allow conversion resolver to be added for height and weight */ COMMENT ON COLUMN actors.height IS E'@omit read,update,create,delete,all,many'; COMMENT ON COLUMN actors.weight IS E'@omit read,update,create,delete,all,many'; - /* - create function releases_by_tag_slugs(slugs text[]) returns setof releases as $$ - select distinct on (releases.id) releases.* from releases - join releases_tags on (releases_tags.release_id = releases.id) - join tags on (releases_tags.tag_id = tags.id) - where tags.slug = ANY($1); - $$ language sql stable - */ + CREATE FUNCTION releases_by_tag_slugs(slugs text[]) RETURNS setof releases AS $$ + SELECT DISTINCT ON (releases.id) releases.* FROM releases + JOIN releases_tags ON (releases_tags.release_id = releases.id) + JOIN tags ON (releases_tags.tag_id = tags.id) + WHERE tags.slug = ANY($1); + $$ LANGUAGE sql STABLE `)); exports.down = knex => knex.raw(` DROP FUNCTION IF EXISTS releases_by_tag_slugs; + DROP VIEW IF EXISTS releases_actors_view; + DROP TABLE IF EXISTS releases_actors CASCADE; DROP TABLE IF EXISTS releases_directors CASCADE; DROP TABLE IF EXISTS releases_posters CASCADE; DROP TABLE IF EXISTS releases_photos CASCADE; + DROP TABLE IF EXISTS releases_trailers CASCADE; DROP TABLE IF EXISTS releases_tags CASCADE; DROP TABLE IF EXISTS actors_avatars CASCADE; DROP TABLE IF EXISTS actors_photos CASCADE; diff --git a/seeds/03_tags.js b/seeds/03_tags.js index d0b91e43..913ad3d7 100644 --- a/seeds/03_tags.js +++ b/seeds/03_tags.js @@ -1544,7 +1544,7 @@ function getTagAliases(tagsMap) { exports.seed = knex => Promise.resolve() .then(async () => upsert('tags_groups', groups, 'slug', knex)) .then(async () => { - const groupEntries = knex('tags').select('*'); + const groupEntries = await knex('tags_groups').select('*'); const groupsMap = groupEntries.reduce((acc, { id, slug }) => ({ ...acc, [slug]: id }), {}); const tags = getTags(groupsMap); diff --git a/seeds/04_media.js b/seeds/04_media.js index d82549f7..cca3bde0 100644 --- a/seeds/04_media.js +++ b/seeds/04_media.js @@ -11,6 +11,11 @@ const tagPosters = [ tagSlug: 'anal', comment: '', }, + { + path: 'tags/da-tp/0.jpeg', + tagSlug: 'da-tp', + comment: 'Natasha Teen in LegalPorno SZ2164', + }, { path: 'tags/double-penetration/poster.jpeg', tagSlug: 'double-penetration', @@ -26,6 +31,11 @@ const tagPosters = [ tagSlug: 'double-vaginal', comment: '', }, + { + path: 'tags/dv-tp/poster.jpeg', + tagSlug: 'dv-tp', + comment: 'Juelz Ventura in "Gangbanged 5" for Elegant Angel', + }, { path: 'tags/tattoo/poster.jpeg', tagSlug: 'tattoo', @@ -141,11 +151,6 @@ const tagPhotos = [ tagSlug: 'airtight', comment: 'Sheena Shaw in "Ass Worship 14" for Jules Jordan', }, - { - path: 'tags/da-tp/0.jpeg', - tagSlug: 'da-tp', - comment: 'Natasha Teen in LegalPorno SZ2164', - }, { path: 'tags/da-tp/3.jpeg', tagSlug: 'da-tp', @@ -166,11 +171,6 @@ const tagPhotos = [ tagSlug: 'da-tp', comment: 'Ninel Mojado aka Mira Cuckold in GIO063 for LegalPorno', }, - { - path: 'tags/dv-tp/poster.jpeg', - tagSlug: 'dv-tp', - comment: 'Juelz Ventura in "Gangbanged 5" for Elegant Angel', - }, { path: 'tags/dv-tp/0.jpeg', tagSlug: 'dv-tp', diff --git a/src/actors.js b/src/actors.js index de609893..973f769d 100644 --- a/src/actors.js +++ b/src/actors.js @@ -399,7 +399,7 @@ async function scrapeBasicActors() { async function associateActors(mappedActors, releases) { const [existingActorEntries, existingAssociationEntries] = await Promise.all([ knex('actors').whereIn('name', Object.keys(mappedActors)), - knex('actors_associated').whereIn('release_id', releases.map(release => release.id)), + knex('releases_actors').whereIn('release_id', releases.map(release => release.id)), ]); const associations = await Promise.map(Object.entries(mappedActors), async ([actorName, releaseIds]) => { @@ -418,7 +418,7 @@ async function associateActors(mappedActors, releases) { }); await Promise.all([ - knex('actors_associated').insert(associations.flat()), + knex('releases_actors').insert(associations.flat()), scrapeBasicActors(), ]); } diff --git a/src/tags.js b/src/tags.js index 6499d15d..2b3f31d3 100644 --- a/src/tags.js +++ b/src/tags.js @@ -66,20 +66,16 @@ async function associateTags(release, releaseId) { ? await matchTags(release.tags) // scraper returned raw tags : release.tags; // tags already matched by (outdated) scraper - const associationEntries = await knex('tags_associated') - .where({ - domain: 'releases', - target_id: releaseId, - }) + const associationEntries = await knex('releases_tags') + .where('release_id', releaseId) .whereIn('tag_id', tags); const existingAssociations = new Set(associationEntries.map(association => association.tag_id)); const newAssociations = tags.filter(tagId => !existingAssociations.has(tagId)); - await knex('tags_associated').insert(newAssociations.map(tagId => ({ + await knex('releases_tags').insert(newAssociations.map(tagId => ({ tag_id: tagId, - domain: 'releases', - target_id: releaseId, + release_id: releaseId, }))); }