Experimenting using GraphQL in favor of REST.
This commit is contained in:
parent
36c5fa3b52
commit
7ba716cd6f
|
@ -3,7 +3,8 @@
|
|||
<Header />
|
||||
|
||||
<div class="content">
|
||||
<router-view />
|
||||
<!-- key forces rerender when new and old path use same component -->
|
||||
<router-view :key="$route.fullPath" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -108,6 +108,22 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="release.scenes && release.scenes.length > 0">
|
||||
<h3>Scenes</h3>
|
||||
|
||||
<Releases
|
||||
v-if="release.scenes && release.scenes.length > 0"
|
||||
:releases="release.scenes"
|
||||
class="row"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="release.movie">
|
||||
<h3>Movie</h3>
|
||||
|
||||
<Release :release="release.movie" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="release.tags.length > 0"
|
||||
class="row"
|
||||
|
@ -196,8 +212,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Actor from '../tile/actor.vue';
|
||||
import Banner from './banner.vue';
|
||||
import Actor from '../tile/actor.vue';
|
||||
import Release from '../tile/release.vue';
|
||||
import Releases from './releases.vue';
|
||||
|
||||
function pageTitle() {
|
||||
return this.release && this.release.title;
|
||||
|
@ -211,6 +229,8 @@ export default {
|
|||
components: {
|
||||
Actor,
|
||||
Banner,
|
||||
Releases,
|
||||
Release,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -56,6 +56,7 @@ export default {
|
|||
}
|
||||
|
||||
.tiles {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, .33fr));
|
||||
grid-gap: 1rem;
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
|
||||
<span
|
||||
v-if="actor.ageThen && actor.ageThen < actor.age"
|
||||
v-tooltip="'Age at scene date'"
|
||||
v-tooltip="`${actor.ageThen} years old on release date`"
|
||||
class="age-then"
|
||||
>@ {{ actor.ageThen }}</span>
|
||||
>{{ actor.ageThen }}</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="actor.origin"
|
||||
|
@ -114,6 +114,7 @@ export default {
|
|||
color: $text-contrast;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: .5rem;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<div class="tile">
|
||||
<div
|
||||
class="tile"
|
||||
:class="{ movie: release.type === 'movie' }"
|
||||
>
|
||||
<span class="banner">
|
||||
<span class="details">
|
||||
<router-link
|
||||
|
@ -39,7 +42,7 @@
|
|||
</span>
|
||||
|
||||
<router-link
|
||||
:to="`/scene/${release.id}`"
|
||||
:to="`/${release.type || 'scene'}/${release.id}`"
|
||||
class="link"
|
||||
>
|
||||
<img
|
||||
|
@ -66,14 +69,19 @@
|
|||
|
||||
<div class="info">
|
||||
<router-link
|
||||
:to="`/scene/${release.id}`"
|
||||
:to="`/${release.type || 'scene'}/${release.id}`"
|
||||
class="row link"
|
||||
>
|
||||
<h3
|
||||
v-tooltip.top="release.title"
|
||||
:title="release.title"
|
||||
class="title"
|
||||
>{{ release.title }}</h3>
|
||||
>
|
||||
<Icon
|
||||
v-if="release.type === 'movie'"
|
||||
icon="film"
|
||||
/>{{ release.title }}
|
||||
</h3>
|
||||
</router-link>
|
||||
|
||||
<span class="row">
|
||||
|
@ -212,13 +220,19 @@ export default {
|
|||
}
|
||||
|
||||
.title {
|
||||
color: $text;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 .25rem .25rem 0;
|
||||
color: $text;
|
||||
font-size: 1rem;
|
||||
max-height: 3rem;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
||||
.icon {
|
||||
margin: 0 .25rem 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.network {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<title>film</title>
|
||||
<path d="M0 0v16h16v-16h-16zM10 1h2v2h-2v-2zM7 1h2v2h-2v-2zM4 1h2v2h-2v-2zM1 1h2v2h-2v-2zM1 4h6v8h-6v-8zM3 15h-2v-2h2v2zM6 15h-2v-2h2v2zM9 15h-2v-2h2v2zM12 15h-2v-2h2v2zM15 15h-2v-2h2v2zM15 12h-7v-8h7v8zM15 3h-2v-2h2v2z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 387 B |
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<title>film2</title>
|
||||
<path d="M0 1v14h16v-14h-16zM3 14h-2v-2h2v2zM3 11h-2v-2h2v2zM3 7h-2v-2h2v2zM3 4h-2v-2h2v2zM12 14h-8v-5h8v5zM12 7h-8v-5h8v5zM15 14h-2v-2h2v2zM15 11h-2v-2h2v2zM15 7h-2v-2h2v2zM15 4h-2v-2h2v2z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 358 B |
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<title>film3</title>
|
||||
<path d="M0 2v12h16v-12h-16zM3 13h-2v-2h2v2zM3 9h-2v-2h2v2zM3 5h-2v-2h2v2zM12 13h-8v-10h8v10zM15 13h-2v-2h2v2zM15 9h-2v-2h2v2zM15 5h-2v-2h2v2z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 311 B |
|
@ -21,7 +21,7 @@ async function get(endpoint, query = {}) {
|
|||
|
||||
async function post(endpoint, data) {
|
||||
const res = await fetch(`${config.api.url}${endpoint}`, {
|
||||
method: 'GET',
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
@ -39,4 +39,34 @@ async function post(endpoint, data) {
|
|||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
export { get, post };
|
||||
async function graphql(operationName, query, variables = null) {
|
||||
const res = await fetch('/graphql', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({
|
||||
operationName,
|
||||
query,
|
||||
variables,
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const { data } = await res.json();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
const errorMsg = await res.text();
|
||||
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
export {
|
||||
get,
|
||||
post,
|
||||
graphql,
|
||||
};
|
||||
|
|
|
@ -1,14 +1,97 @@
|
|||
import { get } from '../api';
|
||||
import { get, graphql } from '../api';
|
||||
|
||||
function initReleasesActions(store, _router) {
|
||||
function initReleasesActions(_store, _router) {
|
||||
async function fetchReleases({ _commit }) {
|
||||
/*
|
||||
const releases = await get('/releases', {
|
||||
filter: store.state.ui.filter,
|
||||
after: store.getters.after,
|
||||
before: store.getters.before,
|
||||
});
|
||||
*/
|
||||
|
||||
return releases;
|
||||
const { releases } = await graphql('MyQuery', `
|
||||
query MyQuery {
|
||||
releases(orderBy: DATE_DESC) {
|
||||
id
|
||||
title
|
||||
description
|
||||
date
|
||||
duration
|
||||
createdAt
|
||||
shootId
|
||||
url
|
||||
actors: actorsAssociateds {
|
||||
actor {
|
||||
id
|
||||
name
|
||||
slug
|
||||
origin: countryByBirthCountryAlpha2 {
|
||||
alpha2
|
||||
name
|
||||
}
|
||||
avatar: actorsMediasByTargetId(condition: { role: "avatar" }) {
|
||||
id
|
||||
thumbnail
|
||||
path
|
||||
mime
|
||||
}
|
||||
}
|
||||
}
|
||||
poster: releasesMediasByTargetId(condition: { role: "poster" }) {
|
||||
mime
|
||||
id
|
||||
index
|
||||
path
|
||||
thumbnail
|
||||
role
|
||||
}
|
||||
photos: releasesMediasByTargetId(condition: { role: "photos" }) {
|
||||
mime
|
||||
id
|
||||
index
|
||||
path
|
||||
thumbnail
|
||||
role
|
||||
}
|
||||
tags: releasesTagsByTargetId {
|
||||
tag {
|
||||
name
|
||||
priority
|
||||
slug
|
||||
id
|
||||
}
|
||||
}
|
||||
site {
|
||||
id
|
||||
name
|
||||
slug
|
||||
url
|
||||
network {
|
||||
id
|
||||
name
|
||||
slug
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const curatedReleases = releases.map(release => ({
|
||||
...release,
|
||||
actors: release.actors.map(({ actor }) => ({
|
||||
...actor,
|
||||
avatar: actor.avatar[0],
|
||||
})),
|
||||
poster: release.poster[0],
|
||||
network: release.site.network,
|
||||
tags: release.tags.map(({ tag }) => tag),
|
||||
}));
|
||||
|
||||
console.log(curatedReleases);
|
||||
|
||||
return curatedReleases;
|
||||
}
|
||||
|
||||
async function fetchReleaseById({ _commit }, releaseId) {
|
||||
|
|
|
@ -200,7 +200,7 @@ exports.up = knex => Promise.resolve()
|
|||
table.integer('duration')
|
||||
.unsigned();
|
||||
|
||||
table.integer('parent', 16)
|
||||
table.integer('parent_id', 16)
|
||||
.references('id')
|
||||
.inTable('releases');
|
||||
|
||||
|
@ -220,6 +220,8 @@ exports.up = knex => Promise.resolve()
|
|||
table.string('domain');
|
||||
table.integer('target_id', 16);
|
||||
|
||||
table.json('target');
|
||||
|
||||
table.string('role');
|
||||
table.string('quality', 6);
|
||||
|
||||
|
@ -286,9 +288,29 @@ exports.up = knex => Promise.resolve()
|
|||
table.integer('target_id', 16);
|
||||
|
||||
table.unique(['domain', 'tag_id', 'target_id']);
|
||||
}));
|
||||
}))
|
||||
.then(() => knex.raw(`
|
||||
CREATE VIEW releases_media AS SELECT * FROM public.media WHERE domain = 'releases';
|
||||
CREATE VIEW actors_media AS SELECT * FROM public.media WHERE domain = 'actors';
|
||||
CREATE VIEW tags_media AS SELECT * FROM public.media WHERE domain = 'media';
|
||||
|
||||
CREATE VIEW releases_tags AS SELECT * FROM public.tags_associated WHERE domain = 'releases';
|
||||
|
||||
COMMENT ON VIEW releases_media IS E'@foreignKey (target_id) references releases (id)|@fieldName releaseId';
|
||||
COMMENT ON VIEW actors_media IS E'@foreignKey (target_id) references actors (id)|@fieldName actorId';
|
||||
COMMENT ON VIEW tags_media IS E'@foreignKey (target_id) references tags (id)|@fieldName tagMediaId';
|
||||
|
||||
COMMENT ON VIEW releases_tags IS E'@foreignKey (target_id) references releases (id)\n@foreignKey (tag_id) references tags (id)';
|
||||
`));
|
||||
|
||||
exports.down = knex => Promise.resolve()
|
||||
.then(() => knex.raw(`
|
||||
DROP VIEW releases_media;
|
||||
DROP VIEW actors_media;
|
||||
DROP VIEW tags_media;
|
||||
|
||||
DROP VIEW releases_tags;
|
||||
`))
|
||||
.then(() => knex.schema.dropTable('tags_associated'))
|
||||
.then(() => knex.schema.dropTable('directors_associated'))
|
||||
.then(() => knex.schema.dropTable('actors_associated'))
|
||||
|
|
|
@ -1422,6 +1422,16 @@
|
|||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@graphile-contrib/pg-simplify-inflector": {
|
||||
"version": "5.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@graphile-contrib/pg-simplify-inflector/-/pg-simplify-inflector-5.0.0-beta.1.tgz",
|
||||
"integrity": "sha512-oE1znqxBgGl6WK7t8sO4okQEqlP+GZ7ZYT4m2EB38GGbT3YuzjHTI8TcxJtDZsLPG3kPvZvB4Uc34Kb0/NGUVQ=="
|
||||
},
|
||||
"@graphile/lru": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@graphile/lru/-/lru-4.5.0.tgz",
|
||||
"integrity": "sha512-OoIgewLowjegJzz3tpcRE5LpQKqsap1ETFaZtC1r9p36h5ieUJnWTxCTpB7XIsU9muMTt7MMt8x0E5apS47QIQ=="
|
||||
},
|
||||
"@tensorflow/tfjs": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-1.4.0.tgz",
|
||||
|
@ -1526,11 +1536,115 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/accepts": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
|
||||
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/bluebird": {
|
||||
"version": "3.5.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.29.tgz",
|
||||
"integrity": "sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw=="
|
||||
},
|
||||
"@types/body-parser": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz",
|
||||
"integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==",
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
|
||||
"integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/cookies": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz",
|
||||
"integrity": "sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw==",
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/express": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz",
|
||||
"integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==",
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.0.tgz",
|
||||
"integrity": "sha512-Xnub7w57uvcBqFdIGoRg1KhNOeEj0vB6ykUM7uFWyxvbdE89GFyqgmUcanAriMr4YOxNFZBAWkfcWIb4WBPt3g==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/range-parser": "*"
|
||||
}
|
||||
},
|
||||
"@types/http-assert": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz",
|
||||
"integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ=="
|
||||
},
|
||||
"@types/json5": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.30.tgz",
|
||||
"integrity": "sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA=="
|
||||
},
|
||||
"@types/jsonwebtoken": {
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.5.tgz",
|
||||
"integrity": "sha512-VGM1gb+LwsQ5EPevvbvdnKncajBdYqNcrvixBif1BsiDQiSF1q+j4bBTvKC6Bt9n2kqNSx+yNTY2TVJ360E7EQ==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/keygrip": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz",
|
||||
"integrity": "sha1-/1QEYtL7TQqIRBzq8n0oewHD2Hg="
|
||||
},
|
||||
"@types/koa": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.0.tgz",
|
||||
"integrity": "sha512-Hgx/1/rVlJvqYBrdeCsS7PDiR2qbxlMt1RnmNWD4Uxi5FF9nwkYqIldo7urjc+dfNpk+2NRGcnAYd4L5xEhCcQ==",
|
||||
"requires": {
|
||||
"@types/accepts": "*",
|
||||
"@types/cookies": "*",
|
||||
"@types/http-assert": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/koa-compose": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/koa-compose": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
|
||||
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
|
||||
"requires": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
|
||||
"integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.12.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz",
|
||||
|
@ -1549,11 +1663,39 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
|
||||
"integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q=="
|
||||
},
|
||||
"@types/pg": {
|
||||
"version": "7.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-7.11.2.tgz",
|
||||
"integrity": "sha512-4+rj7fnidA77jFURNanuPPc1HrQv+RkhI6s+K18G9zOKbOUUpChA/rbNMqFukNuZ89LoIt/I9dAlxf329TjCNw==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/pg-types": "*"
|
||||
}
|
||||
},
|
||||
"@types/pg-types": {
|
||||
"version": "1.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg-types/-/pg-types-1.11.5.tgz",
|
||||
"integrity": "sha512-L8ogeT6vDzT1vxlW3KITTCt+BVXXVkLXfZ/XNm6UqbcJgxf+KPO7yjWx7dQQE8RW07KopL10x2gNMs41+IkMGQ=="
|
||||
},
|
||||
"@types/range-parser": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
|
||||
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
|
||||
},
|
||||
"@types/seedrandom": {
|
||||
"version": "2.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz",
|
||||
"integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE="
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
|
||||
"integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
|
||||
"requires": {
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/mime": "*"
|
||||
}
|
||||
},
|
||||
"@types/webgl-ext": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz",
|
||||
|
@ -1564,6 +1706,14 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.4.tgz",
|
||||
"integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw=="
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz",
|
||||
"integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@vue/component-compiler-utils": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.0.tgz",
|
||||
|
@ -2691,6 +2841,11 @@
|
|||
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
|
||||
"dev": true
|
||||
},
|
||||
"backo2": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
|
@ -3089,6 +3244,11 @@
|
|||
"isarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
|
@ -4204,6 +4364,14 @@
|
|||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"editorconfig": {
|
||||
"version": "0.15.3",
|
||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
|
||||
|
@ -4740,6 +4908,11 @@
|
|||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
|
||||
},
|
||||
"events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
|
||||
|
@ -6208,6 +6381,147 @@
|
|||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
|
||||
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
|
||||
},
|
||||
"graphile-build": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/graphile-build/-/graphile-build-4.5.0.tgz",
|
||||
"integrity": "sha512-U/1K4nHWp3MGJ7kwTwIYBZnO3ZDlufmHHpdd1t4uFA46OtxdP7RG7KnXyol/XB8hfTfqSVGabaZP8lr+NVyQPA==",
|
||||
"requires": {
|
||||
"@graphile/lru": "4.5.0",
|
||||
"chalk": "^2.4.2",
|
||||
"debug": "^4.1.1",
|
||||
"graphql-parse-resolve-info": "4.5.0",
|
||||
"iterall": "^1.2.2",
|
||||
"lodash": ">=4 <5",
|
||||
"lru-cache": "^5.0.0",
|
||||
"pluralize": "^7.0.0",
|
||||
"semver": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"requires": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"graphile-build-pg": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/graphile-build-pg/-/graphile-build-pg-4.5.3.tgz",
|
||||
"integrity": "sha512-Sp3DC/PC9c8+dQkQ6FM5F2TwByWQIMX3TKpxm63SePFJfPdq2Lbl4mOjBxJykYf4Fh094MVAIz4Alz5a1yRBKw==",
|
||||
"requires": {
|
||||
"@graphile/lru": "4.5.0",
|
||||
"chalk": "^2.4.2",
|
||||
"debug": "^4.1.1",
|
||||
"graphile-build": "4.5.0",
|
||||
"graphql-iso-date": "^3.6.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash": ">=4 <5",
|
||||
"lru-cache": ">=4 <5",
|
||||
"pg-sql2": "4.5.0",
|
||||
"postgres-interval": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"graphile-utils": {
|
||||
"version": "4.5.6",
|
||||
"resolved": "https://registry.npmjs.org/graphile-utils/-/graphile-utils-4.5.6.tgz",
|
||||
"integrity": "sha512-Tt4SBVxfS3wbewUhQiN1oXg4KjPVi2a9GOjD8AXWlQfKin25TH2dDRyJRALM/blVuSyBlzn9OqPnvsbM3NqXpQ==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"graphql": ">=0.9 <0.14 || ^14.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"graphql": {
|
||||
"version": "14.5.8",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-14.5.8.tgz",
|
||||
"integrity": "sha512-MMwmi0zlVLQKLdGiMfWkgQD7dY/TUKt4L+zgJ/aR0Howebod3aNgP5JkgvAULiR2HPVZaP2VEElqtdidHweLkg==",
|
||||
"requires": {
|
||||
"iterall": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"graphql-iso-date": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/graphql-iso-date/-/graphql-iso-date-3.6.1.tgz",
|
||||
"integrity": "sha512-AwFGIuYMJQXOEAgRlJlFL4H1ncFM8n8XmoVDTNypNOZyQ8LFDG2ppMFlsS862BSTCDcSUfHp8PD3/uJhv7t59Q=="
|
||||
},
|
||||
"graphql-parse-resolve-info": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-parse-resolve-info/-/graphql-parse-resolve-info-4.5.0.tgz",
|
||||
"integrity": "sha512-51eKipZcj9AQWKLtstAmqys3GmOHUoUwFN/ALe1s4k2his0sP4ASri/ZdqcweLRnno4cDPqp2dcWnJ/Pe2a2rQ==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
|
@ -7000,6 +7314,11 @@
|
|||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"iterall": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
|
||||
"integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
|
||||
},
|
||||
"js-base64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
|
||||
|
@ -7143,6 +7462,30 @@
|
|||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"jsonwebtoken": {
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
|
||||
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
|
||||
"requires": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
|
@ -7164,6 +7507,25 @@
|
|||
"object.assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||
"requires": {
|
||||
"jwa": "^1.4.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"keypress": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz",
|
||||
|
@ -7402,6 +7764,41 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
||||
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI="
|
||||
},
|
||||
"lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
|
||||
},
|
||||
"lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
|
||||
},
|
||||
"lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
|
||||
},
|
||||
"lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
|
||||
},
|
||||
"lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
|
||||
},
|
||||
"lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
|
@ -8890,6 +9287,31 @@
|
|||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.7.tgz",
|
||||
"integrity": "sha512-UiJyO5B9zZpu32GSlP0tXy8J2NsJ9EFGFfz5v6PSbdz/1hBLX1rNiiy5+mAm5iJJYwfCv4A0EBcQLGWwjbpzZw=="
|
||||
},
|
||||
"pg-sql2": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-sql2/-/pg-sql2-4.5.0.tgz",
|
||||
"integrity": "sha512-kmqhJgKbOWsVzKjhzsfglZagyrV5fXkrHeY33WdeSsxhegZI1Evpa/lQzG1uQj2ZfLPIePV7RyoaZH8eVHRd3A==",
|
||||
"requires": {
|
||||
"@graphile/lru": "4.5.0",
|
||||
"@types/pg": ">=6 <8",
|
||||
"debug": ">=3 <5"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"pg-types": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||
|
@ -8948,6 +9370,11 @@
|
|||
"find-up": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"pluralize": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
|
||||
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow=="
|
||||
},
|
||||
"pn": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
|
||||
|
@ -9108,6 +9535,75 @@
|
|||
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"postgraphile": {
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/postgraphile/-/postgraphile-4.5.5.tgz",
|
||||
"integrity": "sha512-JjUcZIabf8rMUwBlvDCp2VOciJcrT/AnE4ksOiYDiv//sWj4twt6QR1T7+Zw7+jA8x1DxCKeIdCKCk7EO5H/4Q==",
|
||||
"requires": {
|
||||
"@graphile/lru": "4.5.0",
|
||||
"@types/json5": "^0.0.30",
|
||||
"@types/jsonwebtoken": "^8.3.2",
|
||||
"@types/koa": "^2.0.44",
|
||||
"@types/pg": "^7.4.10",
|
||||
"@types/ws": "^6.0.1",
|
||||
"body-parser": "^1.15.2",
|
||||
"chalk": "^2.4.2",
|
||||
"commander": "^2.19.0",
|
||||
"debug": "^4.1.1",
|
||||
"finalhandler": "^1.0.6",
|
||||
"graphile-utils": "4.5.6",
|
||||
"graphql": "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.2",
|
||||
"http-errors": "^1.5.1",
|
||||
"iterall": "^1.0.2",
|
||||
"json5": "^2.1.1",
|
||||
"jsonwebtoken": "^8.0.0",
|
||||
"parseurl": "^1.3.2",
|
||||
"pg": ">=6.1.0 <8",
|
||||
"pg-connection-string": "^2.0.0",
|
||||
"pg-sql2": "4.5.0",
|
||||
"postgraphile-core": "4.5.3",
|
||||
"subscriptions-transport-ws": "^0.9.15",
|
||||
"tslib": "^1.5.0",
|
||||
"ws": "^6.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"postgraphile-core": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/postgraphile-core/-/postgraphile-core-4.5.3.tgz",
|
||||
"integrity": "sha512-DmE9JdQEMMJH0W+FVRGL/pO9zZzanuXE49+V+s2agLNjNlDFRFCNKnlUI2sA0PKTNJXilVAPQFpBifn1t74moA==",
|
||||
"requires": {
|
||||
"graphile-build": "4.5.0",
|
||||
"graphile-build-pg": "4.5.3"
|
||||
}
|
||||
},
|
||||
"postgraphile-plugin-connection-filter": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/postgraphile-plugin-connection-filter/-/postgraphile-plugin-connection-filter-1.1.3.tgz",
|
||||
"integrity": "sha512-QWn2lDQ3d8M0iiQVZtozIcJmL3b2A3L6DnMD2e8EOOVqxxAy9Kt3b7k4a+bH46rz4Eh6NuDtHWb0PZnxx41kVg=="
|
||||
},
|
||||
"postgres-array": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||
|
@ -11038,6 +11534,28 @@
|
|||
"schema-utils": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"subscriptions-transport-ws": {
|
||||
"version": "0.9.16",
|
||||
"resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz",
|
||||
"integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==",
|
||||
"requires": {
|
||||
"backo2": "^1.0.2",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"iterall": "^1.2.1",
|
||||
"symbol-observable": "^1.0.4",
|
||||
"ws": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
|
||||
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
@ -11046,6 +11564,11 @@
|
|||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
},
|
||||
"symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
|
@ -11417,8 +11940,7 @@
|
|||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
|
||||
},
|
||||
"tty-browserify": {
|
||||
"version": "0.0.0",
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
"webpack-cli": "^3.3.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphile-contrib/pg-simplify-inflector": "^5.0.0-beta.1",
|
||||
"@tensorflow/tfjs-node": "^1.4.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"bhttp": "^1.2.4",
|
||||
|
@ -90,6 +91,8 @@
|
|||
"moment": "^2.24.0",
|
||||
"opn": "^5.5.0",
|
||||
"pg": "^7.14.0",
|
||||
"postgraphile": "^4.5.5",
|
||||
"postgraphile-plugin-connection-filter": "^1.1.3",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
|
|
|
@ -188,14 +188,21 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
.title[data-v-3abcf101] {
|
||||
color: #222;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
margin: 0 .25rem .25rem 0;
|
||||
color: #222;
|
||||
font-size: 1rem;
|
||||
max-height: 3rem;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.title .icon[data-v-3abcf101] {
|
||||
margin: 0 .25rem 0 0;
|
||||
}
|
||||
.network[data-v-3abcf101] {
|
||||
color: #555;
|
||||
margin: 0 .25rem 0 0;
|
||||
|
@ -255,6 +262,7 @@
|
|||
text-transform: capitalize;
|
||||
}
|
||||
.tiles[data-v-22ffe3e4] {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 0.33fr));
|
||||
grid-gap: 1rem;
|
||||
|
@ -270,6 +278,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.banner[data-v-42bb19c4] {
|
||||
background: #222;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
|
||||
font-size: 0;
|
||||
}
|
||||
.banner[data-v-42bb19c4]::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.trailer[data-v-42bb19c4] {
|
||||
display: inline-block;
|
||||
max-width: 100vw;
|
||||
}
|
||||
.trailer-video[data-v-42bb19c4] {
|
||||
max-width: 100%;
|
||||
}
|
||||
.item[data-v-42bb19c4] {
|
||||
height: 18rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.actor[data-v-6989dc6f] {
|
||||
width: 10rem;
|
||||
|
@ -317,6 +350,8 @@
|
|||
width: 100%;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: justify;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
@ -330,31 +365,6 @@
|
|||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.banner[data-v-42bb19c4] {
|
||||
background: #222;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
|
||||
font-size: 0;
|
||||
}
|
||||
.banner[data-v-42bb19c4]::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.trailer[data-v-42bb19c4] {
|
||||
display: inline-block;
|
||||
max-width: 100vw;
|
||||
}
|
||||
.trailer-video[data-v-42bb19c4] {
|
||||
max-width: 100%;
|
||||
}
|
||||
.item[data-v-42bb19c4] {
|
||||
height: 18rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.column[data-v-d4b03dc2] {
|
||||
width: 1200px;
|
||||
|
|
|
@ -235,6 +235,7 @@ function getMedia(tagsMap) {
|
|||
mime: 'image/jpeg',
|
||||
index,
|
||||
domain: file.domain || 'tags',
|
||||
target: { [file.domain || 'tags']: file.target_id },
|
||||
role: file.role || 'photo',
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ const { scrapeActors, scrapeBasicActors } = require('./actors');
|
|||
|
||||
async function init() {
|
||||
if (argv.scene) {
|
||||
await Promise.map(argv.scene, async url => scrapeRelease(url, null, false, false), {
|
||||
await Promise.map(argv.scene, async url => scrapeRelease(url, null, false, 'scene'), {
|
||||
concurrency: 5,
|
||||
});
|
||||
}
|
||||
|
||||
if (argv.movie) {
|
||||
await Promise.map(argv.movie, async url => scrapeRelease(url, null, false, true), {
|
||||
await Promise.map(argv.movie, async url => scrapeRelease(url, null, false, 'movie'), {
|
||||
concurrency: 5,
|
||||
});
|
||||
}
|
||||
|
|
262
src/releases.js
262
src/releases.js
|
@ -15,8 +15,45 @@ const {
|
|||
} = require('./media');
|
||||
const { fetchSites, findSiteByUrl } = require('./sites');
|
||||
|
||||
async function curateRelease(release) {
|
||||
const [actors, tags, media] = await Promise.all([
|
||||
function commonQuery(queryBuilder, {
|
||||
filter = [],
|
||||
after = new Date(0), // January 1970
|
||||
before = new Date(2 ** 44), // May 2109
|
||||
limit = 100,
|
||||
}) {
|
||||
const finalFilter = [].concat(filter); // ensure filter is array
|
||||
|
||||
queryBuilder
|
||||
.leftJoin('sites', 'releases.site_id', 'sites.id')
|
||||
.leftJoin('studios', 'releases.studio_id', 'studios.id')
|
||||
.leftJoin('networks', 'sites.network_id', 'networks.id')
|
||||
.select(
|
||||
'releases.*',
|
||||
'sites.name as site_name', 'sites.slug as site_slug', 'sites.url as site_url', 'sites.network_id', 'sites.parameters as site_parameters',
|
||||
'studios.name as studio_name', 'sites.slug as site_slug', 'studios.url as studio_url',
|
||||
'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', 'networks.description as network_description',
|
||||
)
|
||||
.whereNotExists((builder) => {
|
||||
// apply tag filters
|
||||
builder
|
||||
.select('*')
|
||||
.from('tags_associated')
|
||||
.leftJoin('tags', 'tags_associated.tag_id', 'tags.id')
|
||||
.whereIn('tags.slug', finalFilter)
|
||||
.where('tags_associated.domain', 'releases')
|
||||
.whereRaw('tags_associated.target_id = releases.id');
|
||||
})
|
||||
.andWhere('releases.date', '>', after)
|
||||
.andWhere('releases.date', '<=', before)
|
||||
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
|
||||
.limit(limit);
|
||||
}
|
||||
|
||||
async function curateMovie(release, deep = true) {
|
||||
const [scenes, actors, tags, media] = await Promise.all([
|
||||
knex('releases')
|
||||
.where('releases.parent_id', release.id)
|
||||
.modify(commonQuery, {}),
|
||||
knex('actors_associated')
|
||||
.select(
|
||||
'actors.id', 'actors.name', 'actors.gender', 'actors.slug', 'actors.birthdate',
|
||||
|
@ -49,8 +86,9 @@ async function curateRelease(release) {
|
|||
.orderBy(['role', 'index']),
|
||||
]);
|
||||
|
||||
return {
|
||||
const curatedRelease = {
|
||||
id: release.id,
|
||||
type: release.type,
|
||||
title: release.title,
|
||||
date: release.date,
|
||||
dateAdded: release.created_at,
|
||||
|
@ -108,6 +146,126 @@ async function curateRelease(release) {
|
|||
url: release.network_url,
|
||||
},
|
||||
};
|
||||
|
||||
if (scenes && scenes.length > 0 && deep) {
|
||||
curatedRelease.scenes = await Promise.map(scenes, scene => curateRelease(scene, false));
|
||||
}
|
||||
|
||||
return curatedRelease;
|
||||
}
|
||||
|
||||
async function curateScene(release, deep = true) {
|
||||
const [movie, actors, tags, media] = await Promise.all([
|
||||
knex('releases')
|
||||
.where('releases.id', release.parent_id)
|
||||
.modify(commonQuery, {})
|
||||
.first(),
|
||||
knex('actors_associated')
|
||||
.select(
|
||||
'actors.id', 'actors.name', 'actors.gender', 'actors.slug', 'actors.birthdate',
|
||||
'birth_countries.alpha2 as birth_country_alpha2', 'birth_countries.name as birth_country_name', 'birth_countries.alias as birth_country_alias',
|
||||
'media.thumbnail as avatar',
|
||||
)
|
||||
.where({ release_id: release.id })
|
||||
.leftJoin('actors', 'actors.id', 'actors_associated.actor_id')
|
||||
.leftJoin('countries as birth_countries', 'actors.birth_country_alpha2', 'birth_countries.alpha2')
|
||||
.leftJoin('media', (builder) => {
|
||||
builder
|
||||
.on('media.target_id', 'actors.id')
|
||||
.andOnVal('media.domain', 'actors')
|
||||
.andOnVal('media.index', '0');
|
||||
})
|
||||
.orderBy('actors.gender'),
|
||||
knex('tags_associated')
|
||||
.select('tags.name', 'tags.slug')
|
||||
.where({
|
||||
domain: 'releases',
|
||||
target_id: release.id,
|
||||
})
|
||||
.leftJoin('tags', 'tags.id', 'tags_associated.tag_id')
|
||||
.orderBy('tags.priority', 'desc'),
|
||||
knex('media')
|
||||
.where({
|
||||
target_id: release.id,
|
||||
domain: 'releases',
|
||||
})
|
||||
.orderBy(['role', 'index']),
|
||||
]);
|
||||
|
||||
const curatedRelease = {
|
||||
id: release.id,
|
||||
type: release.type,
|
||||
title: release.title,
|
||||
date: release.date,
|
||||
dateAdded: release.created_at,
|
||||
description: release.description,
|
||||
url: release.url,
|
||||
shootId: release.shoot_id,
|
||||
entryId: release.entry_id,
|
||||
actors: actors.map(actor => ({
|
||||
id: actor.id,
|
||||
slug: actor.slug,
|
||||
name: actor.name,
|
||||
gender: actor.gender,
|
||||
birthdate: actor.birthdate,
|
||||
age: moment().diff(actor.birthdate, 'years'),
|
||||
ageThen: moment(release.date).diff(actor.birthdate, 'years'),
|
||||
avatar: actor.avatar,
|
||||
origin: actor.birth_country_alpha2
|
||||
? {
|
||||
country: {
|
||||
name: actor.birth_country_alias,
|
||||
alpha2: actor.birth_country_alpha2,
|
||||
},
|
||||
}
|
||||
: null,
|
||||
})),
|
||||
director: release.director,
|
||||
tags,
|
||||
duration: release.duration,
|
||||
photos: media.filter(item => item.role === 'photo'),
|
||||
poster: media.filter(item => item.role === 'poster')[0],
|
||||
covers: media.filter(item => item.role === 'cover'),
|
||||
trailer: media.filter(item => item.role === 'trailer')[0],
|
||||
site: {
|
||||
id: release.site_id,
|
||||
name: release.site_name,
|
||||
independent: release.site_parameters
|
||||
? (JSON.parse(release.site_parameters).independent || false)
|
||||
: false,
|
||||
slug: release.site_slug,
|
||||
url: release.site_url,
|
||||
},
|
||||
studio: release.studio_id
|
||||
? {
|
||||
id: release.studio_id,
|
||||
name: release.studio_name,
|
||||
slug: release.studio_slug,
|
||||
url: release.studio_url,
|
||||
}
|
||||
: null,
|
||||
network: {
|
||||
id: release.network_id,
|
||||
name: release.network_name,
|
||||
description: release.network_description,
|
||||
slug: release.network_slug,
|
||||
url: release.network_url,
|
||||
},
|
||||
};
|
||||
|
||||
if (movie && deep) {
|
||||
curatedRelease.movie = await curateMovie(movie, false);
|
||||
}
|
||||
|
||||
return curatedRelease;
|
||||
}
|
||||
|
||||
async function curateRelease(release) {
|
||||
if (release.type === 'movie') {
|
||||
return curateMovie(release);
|
||||
}
|
||||
|
||||
return curateScene(release);
|
||||
}
|
||||
|
||||
function curateReleases(releases) {
|
||||
|
@ -129,12 +287,14 @@ async function getChannelSite(release) {
|
|||
}
|
||||
}
|
||||
|
||||
async function curateScrapedRelease(release) {
|
||||
async function curateReleaseEntry(release) {
|
||||
const curatedRelease = {
|
||||
site_id: release.site.id,
|
||||
studio_id: release.studio ? release.studio.id : null,
|
||||
shoot_id: release.shootId || null,
|
||||
entry_id: release.entryId || null,
|
||||
parent_id: release.parentId,
|
||||
type: release.type,
|
||||
url: release.url,
|
||||
title: release.title,
|
||||
date: release.date,
|
||||
|
@ -159,40 +319,6 @@ async function curateScrapedRelease(release) {
|
|||
return curatedRelease;
|
||||
}
|
||||
|
||||
function commonQuery(queryBuilder, {
|
||||
filter = [],
|
||||
after = new Date(0), // January 1970
|
||||
before = new Date(2 ** 44), // May 2109
|
||||
limit = 100,
|
||||
}) {
|
||||
const finalFilter = [].concat(filter); // ensure filter is array
|
||||
|
||||
queryBuilder
|
||||
.leftJoin('sites', 'releases.site_id', 'sites.id')
|
||||
.leftJoin('studios', 'releases.studio_id', 'studios.id')
|
||||
.leftJoin('networks', 'sites.network_id', 'networks.id')
|
||||
.select(
|
||||
'releases.*',
|
||||
'sites.name as site_name', 'sites.slug as site_slug', 'sites.url as site_url', 'sites.network_id', 'sites.parameters as site_parameters',
|
||||
'studios.name as studio_name', 'sites.slug as site_slug', 'studios.url as studio_url',
|
||||
'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', 'networks.description as network_description',
|
||||
)
|
||||
.whereNotExists((builder) => {
|
||||
// apply tag filters
|
||||
builder
|
||||
.select('*')
|
||||
.from('tags_associated')
|
||||
.leftJoin('tags', 'tags_associated.tag_id', 'tags.id')
|
||||
.whereIn('tags.slug', finalFilter)
|
||||
.where('tags_associated.domain', 'releases')
|
||||
.whereRaw('tags_associated.target_id = releases.id');
|
||||
})
|
||||
.andWhere('date', '>', after)
|
||||
.andWhere('date', '<=', before)
|
||||
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
|
||||
.limit(limit);
|
||||
}
|
||||
|
||||
async function fetchReleases(queryObject = {}, options = {}) {
|
||||
const releases = await knex('releases')
|
||||
.modify(commonQuery, options)
|
||||
|
@ -244,6 +370,40 @@ async function fetchTagReleases(queryObject, options = {}) {
|
|||
return curateReleases(releases);
|
||||
}
|
||||
|
||||
function accumulateActors(releases) {
|
||||
return releases.reduce((acc, release) => {
|
||||
if (!release.actors) return acc;
|
||||
|
||||
release.actors.forEach((actor) => {
|
||||
const trimmedActor = actor.trim();
|
||||
|
||||
if (acc[trimmedActor]) {
|
||||
acc[trimmedActor] = acc[trimmedActor].concat(release.id);
|
||||
return;
|
||||
}
|
||||
|
||||
acc[trimmedActor] = [release.id];
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function accumulateMovies(releases) {
|
||||
return releases.reduce((acc, release) => {
|
||||
if (release.movie) {
|
||||
if (acc[release.movie]) {
|
||||
acc[release.movie] = acc[release.movie].concat(release.id);
|
||||
return acc;
|
||||
}
|
||||
|
||||
acc[release.movie] = [release.id];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
async function storeReleaseAssets(release, releaseId) {
|
||||
const subpath = `${release.site.network.slug}/${release.site.slug}/${release.id}/`;
|
||||
const identifier = `"${release.title}" (${releaseId})`;
|
||||
|
@ -279,7 +439,7 @@ async function storeReleaseAssets(release, releaseId) {
|
|||
|
||||
async function storeRelease(release) {
|
||||
const existingRelease = await knex('releases').where('entry_id', release.entryId).first();
|
||||
const curatedRelease = await curateScrapedRelease(release);
|
||||
const curatedRelease = await curateReleaseEntry(release);
|
||||
|
||||
if (existingRelease && !argv.redownload) {
|
||||
return existingRelease.id;
|
||||
|
@ -339,22 +499,8 @@ async function storeReleases(releases) {
|
|||
concurrency: 10,
|
||||
}).filter(release => release);
|
||||
|
||||
const actors = storedReleases.reduce((acc, release) => {
|
||||
if (!release.actors) return acc;
|
||||
|
||||
release.actors.forEach((actor) => {
|
||||
const trimmedActor = actor.trim();
|
||||
|
||||
if (acc[trimmedActor]) {
|
||||
acc[trimmedActor] = acc[trimmedActor].concat(release.id);
|
||||
return;
|
||||
}
|
||||
|
||||
acc[trimmedActor] = [release.id];
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
const actors = accumulateActors(storedReleases);
|
||||
const movies = accumulateMovies(storedReleases);
|
||||
|
||||
await Promise.all([
|
||||
associateActors(actors, storedReleases),
|
||||
|
@ -363,7 +509,11 @@ async function storeReleases(releases) {
|
|||
}),
|
||||
]);
|
||||
|
||||
return storedReleases;
|
||||
return {
|
||||
releases: storedReleases,
|
||||
actors,
|
||||
movies,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -28,7 +28,7 @@ async function findSite(url, release) {
|
|||
return null;
|
||||
}
|
||||
|
||||
async function scrapeRelease(url, release, deep = false, isMovie = false) {
|
||||
async function scrapeRelease(url, release, deep = true, type = 'scene') {
|
||||
const site = await findSite(url, release);
|
||||
|
||||
if (!site) {
|
||||
|
@ -41,21 +41,32 @@ async function scrapeRelease(url, release, deep = false, isMovie = false) {
|
|||
throw new Error('Could not find scraper for URL');
|
||||
}
|
||||
|
||||
if (!isMovie && !scraper.fetchScene) {
|
||||
if (type === 'scene' && !scraper.fetchScene) {
|
||||
throw new Error(`The '${site.name}'-scraper cannot fetch individual scenes`);
|
||||
}
|
||||
|
||||
if (isMovie && !scraper.fetchMovie) {
|
||||
if (type === 'movie' && !scraper.fetchMovie) {
|
||||
throw new Error(`The '${site.name}'-scraper cannot fetch individual movies`);
|
||||
}
|
||||
|
||||
const scrapedRelease = isMovie
|
||||
? await scraper.fetchMovie(url, site, release)
|
||||
: await scraper.fetchScene(url, site, release);
|
||||
const scrapedRelease = type === 'scene'
|
||||
? await scraper.fetchScene(url, site, release)
|
||||
: await scraper.fetchMovie(url, site, release);
|
||||
|
||||
const curatedRelease = { ...scrapedRelease, type };
|
||||
|
||||
if (!deep && argv.save) {
|
||||
// don't store release when called by site scraper
|
||||
const [storedRelease] = await storeReleases([scrapedRelease]);
|
||||
const movie = scrapedRelease.movie
|
||||
? await scrapeRelease(scrapedRelease.movie, null, false, 'movie')
|
||||
: null;
|
||||
|
||||
if (movie) {
|
||||
const { releases: [storedMovie] } = await storeReleases([movie]);
|
||||
curatedRelease.parentId = storedMovie.id;
|
||||
}
|
||||
|
||||
const { releases: [storedRelease] } = await storeReleases([curatedRelease]);
|
||||
|
||||
if (storedRelease) {
|
||||
console.log(`http://${config.web.host}:${config.web.port}/scene/${storedRelease.id}`);
|
||||
|
|
|
@ -70,7 +70,7 @@ async function deepFetchReleases(baseReleases) {
|
|||
return Promise.map(baseReleases, async (release) => {
|
||||
if (release.url) {
|
||||
try {
|
||||
const fullRelease = await scrapeRelease(release.url, release, true);
|
||||
const fullRelease = await scrapeRelease(release.url, release, true, 'scene');
|
||||
|
||||
return {
|
||||
...release,
|
||||
|
@ -114,7 +114,7 @@ async function scrapeSiteReleases(scraper, site) {
|
|||
async function scrapeReleases() {
|
||||
const networks = await fetchIncludedSites();
|
||||
|
||||
const scrapedReleases = await Promise.map(networks, async network => Promise.map(network.sites, async (site) => {
|
||||
const scrapedNetworks = await Promise.map(networks, async network => Promise.map(network.sites, async (site) => {
|
||||
const scraper = scrapers.releases[site.slug] || scrapers.releases[site.network.slug];
|
||||
|
||||
if (!scraper) {
|
||||
|
@ -143,7 +143,8 @@ async function scrapeReleases() {
|
|||
});
|
||||
|
||||
if (argv.save) {
|
||||
await storeReleases(scrapedReleases.flat(2));
|
||||
const { movies } = await storeReleases(scrapedNetworks.flat(2));
|
||||
console.log(movies);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ async function getPhotos(albumUrl) {
|
|||
const lastPhotoPage = Array.from(document.querySelectorAll('.preview-image-container a')).slice(-1)[0].href;
|
||||
const lastPhotoIndex = parseInt(lastPhotoPage.match(/\d+.jpg/)[0], 10);
|
||||
|
||||
const photoUrls = await Promise.map(Array.from({ length: lastPhotoIndex }), async (index) => {
|
||||
const photoUrls = await Promise.map(Array.from({ length: lastPhotoIndex }), async (value, index) => {
|
||||
const pageUrl = `https://blacksonblondes.com${lastPhotoPage.replace(/\d+.jpg/, `${index.toString().padStart(3, '0')}.jpg`)}`;
|
||||
|
||||
return getPhoto(pageUrl);
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
const path = require('path');
|
||||
const config = require('config');
|
||||
const express = require('express');
|
||||
const { postgraphile } = require('postgraphile');
|
||||
const Router = require('express-promise-router');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
const ConnectionFilterPlugin = require('postgraphile-plugin-connection-filter');
|
||||
const PgSimplifyInflectorPlugin = require('@graphile-contrib/pg-simplify-inflector');
|
||||
|
||||
const {
|
||||
fetchReleases,
|
||||
fetchReleaseById,
|
||||
|
@ -28,6 +32,25 @@ function initServer() {
|
|||
const app = express();
|
||||
const router = Router();
|
||||
|
||||
const connectionString = `postgres://${config.database.user}:${config.database.password}@${config.database.host}:5432/${config.database.database}`;
|
||||
|
||||
app.use(postgraphile(
|
||||
connectionString,
|
||||
'public',
|
||||
{
|
||||
// watchPg: true,
|
||||
dynamicJson: true,
|
||||
graphiql: true,
|
||||
enhanceGraphiql: true,
|
||||
allowExplain: () => true,
|
||||
simpleCollections: 'only',
|
||||
graphileBuildOptions: {
|
||||
pgOmitListSuffix: true,
|
||||
},
|
||||
appendPlugins: [PgSimplifyInflectorPlugin, ConnectionFilterPlugin],
|
||||
},
|
||||
));
|
||||
|
||||
router.use('/media', express.static(config.media.path));
|
||||
router.use(express.static('public'));
|
||||
|
||||
|
|
Loading…
Reference in New Issue