Abstracted fragments and curation. Using GraphQL for tags.

This commit is contained in:
ThePendulum 2019-12-16 05:30:25 +01:00
parent f4c2e6c08c
commit 6950a76cb5
10 changed files with 260 additions and 159 deletions

View File

@ -50,7 +50,7 @@
</div> </div>
<div class="content-inner"> <div class="content-inner">
<Releases :releases="releases" /> <Releases :releases="tag.releases" />
</div> </div>
</div> </div>
</div> </div>
@ -68,17 +68,13 @@ import Releases from '../releases/releases.vue';
const converter = new Converter(); const converter = new Converter();
async function fetchReleases() { async function fetchReleases() {
this.releases = await this.$store.dispatch('fetchTagReleases', this.$route.params.tagSlug); this.tag = await this.$store.dispatch('fetchTags', { tagSlug: this.$route.params.tagSlug });
} }
async function mounted() { async function mounted() {
[this.tag] = await Promise.all([ this.tag = await this.$store.dispatch('fetchTags', { tagSlug: this.$route.params.tagSlug });
this.$store.dispatch('fetchTags', { tagId: this.$route.params.tagSlug }),
this.fetchReleases(),
]);
this.description = converter.makeHtml(escapeHtml(this.tag.description));
this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description));
this.pageTitle = this.tag.name; this.pageTitle = this.tag.name;
} }
@ -90,6 +86,7 @@ export default {
data() { data() {
return { return {
tag: null, tag: null,
description: null,
releases: null, releases: null,
pageTitle: null, pageTitle: null,
}; };

View File

@ -47,7 +47,7 @@ import Tag from '../tile/tag.vue';
async function mounted() { async function mounted() {
const tags = await this.$store.dispatch('fetchTags', { const tags = await this.$store.dispatch('fetchTags', {
slug: [ slugs: [
'airtight', 'airtight',
'anal', 'anal',
'double-anal', 'double-anal',

30
assets/js/curate.js Normal file
View File

@ -0,0 +1,30 @@
function curateActor(actor) {
const curatedActor = {
...actor,
avatar: actor.avatar[0],
origin: actor.originCountry && {
country: actor.originCountry,
},
};
return curatedActor;
}
function curateRelease(release) {
const curatedRelease = {
...release,
actors: release.actors.map(({ actor }) => curateActor(actor)),
poster: release.poster[0],
network: release.site.network,
tags: release.tags.map(({ tag }) => tag),
};
if (release.trailer) [curatedRelease.trailer] = release.trailer;
return curatedRelease;
}
export {
curateActor,
curateRelease,
};

119
assets/js/fragments.js Normal file
View File

@ -0,0 +1,119 @@
const siteFragment = `
site {
id
name
slug
url
network {
id
name
slug
url
}
}
`;
const releaseActorsFragment = `
actors: releasesActors(orderBy: GENDER_ASC) {
actor: releaseActor {
id
name
slug
birthdate
age
originCountry: countryByBirthCountryAlpha2 {
alpha2
name
alias
}
avatar: actorsMediasByTargetId(condition: { role: "avatar" }) {
thumbnail
}
}
}
`;
const releaseTagsFragment = `
tags: releasesTagsByTargetId {
tag: releaseTag {
name
priority
slug
id
}
}
`;
const releasePosterFragment = `
poster: releasesMediasByTargetId(condition: { role: "poster" }) {
index
path
thumbnail
}
`;
const releasePhotosFragment = `
photos: releasesMediasByTargetId(condition: { role: "photo" }) {
index
path
thumbnail
}
`;
const releaseTrailerFragment = `
trailer: releasesMediasByTargetId(condition: { role: "trailer" }) {
index
path
thumbnail
}
`;
const releasesFragment = `
releases(first:$limit, orderBy: DATE_DESC) {
id
title
date
createdAt
url
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
${siteFragment}
}
`;
const releaseFragment = `
release(id: $releaseId) {
id
title
description
date
duration
createdAt
shootId
url
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
${releasePhotosFragment}
${releaseTrailerFragment}
${siteFragment}
studio {
id
name
slug
url
}
}
`;
export {
releaseActorsFragment,
releaseTagsFragment,
releasePosterFragment,
releasePhotosFragment,
releaseTrailerFragment,
releasesFragment,
releaseFragment,
siteFragment,
};

View File

@ -1,24 +1,6 @@
import { graphql } from '../api'; import { graphql } from '../api';
import { releasesFragment, releaseFragment } from '../fragments';
function curateRelease(release) { import { curateRelease } from '../curate';
const curatedRelease = {
...release,
actors: release.actors.map(({ actor }) => ({
...actor,
avatar: actor.avatar[0],
origin: actor.originCountry && {
country: actor.originCountry,
},
})),
poster: release.poster[0],
network: release.site.network,
tags: release.tags.map(({ tag }) => tag),
};
if (release.trailer) [curatedRelease.trailer] = release.trailer;
return curatedRelease;
}
function initReleasesActions(_store, _router) { function initReleasesActions(_store, _router) {
async function fetchReleases({ _commit }, { limit = 100 }) { async function fetchReleases({ _commit }, { limit = 100 }) {
@ -32,58 +14,7 @@ function initReleasesActions(_store, _router) {
const { releases } = await graphql(` const { releases } = await graphql(`
query Releases($limit:Int!) { query Releases($limit:Int!) {
releases(first:$limit, orderBy: DATE_DESC) { ${releasesFragment}
id
title
description
date
duration
createdAt
shootId
url
actors: actorsAssociateds {
actor {
id
name
slug
birthdate
age
originCountry: countryByBirthCountryAlpha2 {
alpha2
name
alias
}
avatar: actorsMediasByTargetId(condition: { role: "avatar" }) {
thumbnail
}
}
}
poster: releasesMediasByTargetId(condition: { role: "poster" }) {
index
path
thumbnail
}
tags: releasesTagsByTargetId {
tag: releaseTag {
name
priority
slug
id
}
}
site {
id
name
slug
url
network {
id
name
slug
url
}
}
}
} }
`, { `, {
limit, limit,
@ -97,68 +28,7 @@ function initReleasesActions(_store, _router) {
const { release } = await graphql(` const { release } = await graphql(`
query Release($releaseId:Int!) { query Release($releaseId:Int!) {
release(id: $releaseId) { ${releaseFragment}
id
title
description
date
duration
createdAt
shootId
url
actors: actorsAssociateds {
actor {
id
name
slug
birthdate
age
originCountry: countryByBirthCountryAlpha2 {
alpha2
name
alias
}
avatar: actorsMediasByTargetId(condition: { role: "avatar" }) {
thumbnail
}
}
}
poster: releasesMediasByTargetId(condition: { role: "poster" }) {
index
path
thumbnail
}
photos: releasesMediasByTargetId(condition: { role: "photo" }) {
index
path
thumbnail
}
trailer: releasesMediasByTargetId(condition: { role: "trailer" }) {
index
path
thumbnail
}
tags: releasesTagsByTargetId {
tag: releaseTag {
name
priority
slug
id
}
}
site {
id
name
slug
url
network {
id
name
slug
url
}
}
}
} }
`, { `, {
releaseId: Number(releaseId), releaseId: Number(releaseId),

View File

@ -1,23 +1,100 @@
import { get } from '../api'; import { graphql, get } from '../api';
import {
releasePosterFragment,
releaseActorsFragment,
releaseTagsFragment,
siteFragment,
} from '../fragments';
import { curateRelease } from '../curate';
function initTagsActions(store, _router) { function curateTag(tag) {
async function fetchTags({ _commit }, { const curatedTag = {
tagId, ...tag,
limit = 100, };
slug,
group, if (tag.releases) curatedTag.releases = tag.releases.map(({ tagRelease }) => curateRelease(tagRelease));
priority, if (tag.poster) [curatedTag.poster] = tag.poster;
}) {
if (tagId) { return curatedTag;
return get(`/tags/${tagId}`);
} }
return get('/tags', { function initTagsActions(store, _router) {
limit, async function fetchTagBySlug(tagSlug) {
slug, const { tagBySlug } = await graphql(`
priority, query Tag($tagSlug:String!) {
group, tagBySlug(slug:$tagSlug) {
id
name
slug
description
group {
name
slug
}
poster: tagsMediasByTargetId(condition: { role: "poster" }) {
id
thumbnail
path
}
photos: tagsMediasByTargetId(condition: { role: "photo" }) {
id
thumbnail
path
}
releases: releasesTags {
tagRelease {
id
title
date
createdAt
url
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
${siteFragment}
}
}
}
}
`, {
tagSlug,
}); });
return curateTag(tagBySlug);
}
async function fetchTags({ _commit }, {
tagSlug,
limit = 100,
slugs = [],
_group,
_priority,
}) {
if (tagSlug) {
return fetchTagBySlug(tagSlug);
}
const { tags } = await graphql(`
query Tags($slugs: [String!] = [], $limit: Int = 100) {
tags(filter: {slug: {in: $slugs}}, first: $limit) {
id
name
slug
poster: tagsMediasByTargetId(condition: { role: "poster" }) {
thumbnail
}
group {
name
slug
}
}
}
`, {
slugs,
limit,
});
return tags.map(tag => curateTag(tag));
} }
async function fetchTagReleases({ _commit }, tagId) { async function fetchTagReleases({ _commit }, tagId) {
@ -33,6 +110,7 @@ function initTagsActions(store, _router) {
return { return {
fetchTags, fetchTags,
fetchTagReleases, fetchTagReleases,
fetchTagBySlug,
}; };
} }

View File

@ -249,7 +249,7 @@ exports.up = knex => Promise.resolve()
.defaultTo(knex.fn.now()); .defaultTo(knex.fn.now());
})) }))
.then(() => knex.schema.createTable('actors_associated', (table) => { .then(() => knex.schema.createTable('actors_associated', (table) => {
table.increments('id', 16); // table.increments('id', 16);
table.integer('release_id', 16) table.integer('release_id', 16)
.notNullable() .notNullable()
@ -292,9 +292,11 @@ exports.up = knex => Promise.resolve()
.then(() => knex.raw(` .then(() => knex.raw(`
CREATE VIEW releases_media AS SELECT * FROM media WHERE domain = 'releases'; CREATE VIEW releases_media AS SELECT * FROM media WHERE domain = 'releases';
CREATE VIEW actors_media AS SELECT * FROM media WHERE domain = 'actors'; CREATE VIEW actors_media AS SELECT * FROM media WHERE domain = 'actors';
CREATE VIEW tags_media AS SELECT * FROM media WHERE domain = 'media'; CREATE VIEW tags_media AS SELECT * FROM media WHERE domain = 'tags';
CREATE VIEW releases_tags AS SELECT * FROM tags_associated WHERE domain = 'releases'; CREATE VIEW releases_tags AS SELECT * FROM tags_associated WHERE domain = 'releases';
/* used for sorting release actors and tags */
CREATE VIEW releases_actors AS SELECT actors_associated.*,actors.gender,actors.birthdate FROM actors_associated LEFT JOIN actors ON actors_associated.actor_id = actors.id;
CREATE VIEW actors_social AS SELECT * FROM social WHERE domain = 'actors'; CREATE VIEW actors_social AS SELECT * FROM social WHERE domain = 'actors';
@ -306,6 +308,9 @@ exports.up = knex => Promise.resolve()
COMMENT ON VIEW releases_tags IS E'@foreignKey (target_id) references releases (id)|@fieldName tagRelease\n@foreignKey (tag_id) references tags (id)|@fieldName releaseTag'; COMMENT ON VIEW releases_tags IS E'@foreignKey (target_id) references releases (id)|@fieldName tagRelease\n@foreignKey (tag_id) references tags (id)|@fieldName releaseTag';
/* restore foreign keys in view, used for sorting release actors */
COMMENT ON VIEW releases_actors IS E'@foreignKey (release_id) references releases (id)|@fieldName actorRelease\n@foreignKey (actor_id) references actors (id)|@fieldName releaseActor';
COMMENT ON COLUMN actors.height IS E'@omit read,update,create,delete,all,many'; 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'; COMMENT ON COLUMN actors.weight IS E'@omit read,update,create,delete,all,many';
`)); `));
@ -317,6 +322,7 @@ exports.down = knex => Promise.resolve()
DROP VIEW tags_media; DROP VIEW tags_media;
DROP VIEW releases_tags; DROP VIEW releases_tags;
DROP VIEW releases_actors;
DROP VIEW actors_social; DROP VIEW actors_social;
`)) `))

View File

@ -19,7 +19,7 @@ function getMedia(tagsMap) {
comment: 'Chloe Amour in "DP Masters 4" for Jules Jordan', comment: 'Chloe Amour in "DP Masters 4" for Jules Jordan',
}, },
{ {
path: 'tags/airtight/0/poster.jpeg', path: 'tags/airtight/0.jpeg',
domain: 'tags', domain: 'tags',
target_id: tagsMap.airtight, target_id: tagsMap.airtight,
comment: 'Sheena Shaw in "Ass Worship 14" for Jules Jordan', comment: 'Sheena Shaw in "Ass Worship 14" for Jules Jordan',

View File

@ -143,8 +143,7 @@ async function scrapeReleases() {
}); });
if (argv.save) { if (argv.save) {
const { movies } = await storeReleases(scrapedNetworks.flat(2)); await storeReleases(scrapedNetworks.flat(2));
console.log(movies);
} }
} }

View File

@ -20,6 +20,8 @@ const schemaExtender = makeExtendSchemaPlugin(_build => ({
resolvers: { resolvers: {
Actor: { Actor: {
age(parent, _args, _context, _info) { age(parent, _args, _context, _info) {
console.log(parent);
if (!parent.birthdate) return null; if (!parent.birthdate) return null;
return moment().diff(parent.birthdate, 'years'); return moment().diff(parent.birthdate, 'years');