Added timerange filters. Refactored releases module for more efficient queries.

This commit is contained in:
ThePendulum 2019-11-15 01:27:58 +01:00
parent a089bf892c
commit 1c3f17ec82
13 changed files with 280 additions and 155 deletions

View File

@ -2,7 +2,7 @@
"root": true, "root": true,
"extends": ["airbnb-base", "plugin:vue/recommended"], "extends": ["airbnb-base", "plugin:vue/recommended"],
"parserOptions": { "parserOptions": {
"ecmaVersion": 2017, "ecmaVersion": 2019,
"sourceType": "module" "sourceType": "module"
}, },
"rules": { "rules": {

View File

@ -1,24 +1,70 @@
<template> <template>
<div class="filter-bar noselect"> <div class="filter-bar noselect">
<Icon icon="filter" /> <span>
<label class="range">
<input
:id="`${_uid}-all`"
:checked="range === 'all'"
type="radio"
class="range-input"
@click="$emit('set-range', 'all')"
>
<label
:for="`${_uid}-all`"
class="range-button"
>All</label>
</label>
<Filters <label class="range">
class="filters-container" <input
:filter="filter" :id="`${_uid}-new`"
@set-filter="filter => $emit('set-filter', filter)" :checked="range === 'new'"
/> type="radio"
class="range-input"
@click="$emit('set-range', 'new')"
>
<label
:for="`${_uid}-new`"
class="range-button"
>New</label>
</label>
<v-popover class="filters-compact"> <label class="range">
<div>Filters</div> <input
:id="`${_uid}-upcoming`"
:checked="range === 'upcoming'"
type="radio"
class="range-input"
@click="$emit('set-range', 'upcoming')"
>
<label
:for="`${_uid}-upcoming`"
class="range-button"
>Upcoming</label>
</label>
</span>
<div slot="popover"> <span>
<Filters <Icon icon="filter" />
:compact="true"
:filter="filter" <Filters
@set-filter="filter => $emit('set-filter', filter)" class="filters-container"
/> :filter="filter"
</div> @set-filter="filter => $emit('set-filter', filter)"
</v-popover> />
<v-popover class="filters-compact">
<div>Filters</div>
<div slot="popover">
<Filters
:compact="true"
:filter="filter"
@set-filter="filter => $emit('set-filter', filter)"
/>
</div>
</v-popover>
</span>
</div> </div>
</template> </template>
@ -34,6 +80,10 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
range: {
type: String,
default: null,
},
}, },
}; };
</script> </script>
@ -43,7 +93,8 @@ export default {
.filter-bar { .filter-bar {
background: $background; background: $background;
display: block; display: flex;
justify-content: space-between;
padding: .5rem 1rem; padding: .5rem 1rem;
font-size: 0; font-size: 0;
box-shadow: 0 0 3px $shadow; box-shadow: 0 0 3px $shadow;
@ -64,6 +115,30 @@ export default {
margin: 0 0 0 .5rem; margin: 0 0 0 .5rem;
} }
.range-button {
color: $shadow;
background: $background;
display: inline-block;
padding: .5rem 1rem;
border: none;
box-shadow: 0 0 2px $shadow-weak;
font-size: .8rem;
font-weight: bold;
&:hover {
color: $text;
cursor: pointer;
}
}
.range-input {
display: none;
&:checked + .range-button {
color: $primary;
}
}
@media(max-width: $breakpoint) { @media(max-width: $breakpoint) {
.filters-container { .filters-container {
display: none; display: none;

View File

@ -1,25 +1,6 @@
<template> <template>
<div :class="{ compact }"> <div :class="{ compact }">
<ul class="filters"> <ul class="filters">
<li
v-tooltip.bottom="'Not yet available'"
class="filter"
>
<label
class="toggle"
:class="{ active: !localFilter.includes('straight') }"
>
<input
v-model="localFilter"
value="straight"
type="checkbox"
class="check"
disabled
@change="$emit('set-filter', localFilter)"
>straight
</label>
</li>
<li class="filter"> <li class="filter">
<label <label
class="toggle" class="toggle"
@ -82,23 +63,6 @@
</label> </label>
</li> </li>
</ul> </ul>
<ul class="filters">
<li class="filter">
<label
class="toggle"
:class="{ active: !localFilter.includes('femdom') }"
>
<input
v-model="localFilter"
value="femdom"
type="checkbox"
class="check"
@change="$emit('set-filter', localFilter)"
>femdom
</label>
</li>
</ul>
</div> </div>
</template> </template>

View File

@ -2,7 +2,9 @@
<div class="content"> <div class="content">
<FilterBar <FilterBar
:filter="filter" :filter="filter"
:range="range"
@set-filter="setFilter" @set-filter="setFilter"
@set-range="setRange"
/> />
<div class="content-inner"> <div class="content-inner">
@ -23,9 +25,12 @@
import FilterBar from './filter-bar.vue'; import FilterBar from './filter-bar.vue';
import ReleaseTile from '../tile/release.vue'; import ReleaseTile from '../tile/release.vue';
import rangeDates from '../../js/range-dates';
async function fetchReleases() { async function fetchReleases() {
this.releases = await this.$store.dispatch('fetchReleases', { this.releases = await this.$store.dispatch('fetchReleases', {
filter: this.filter, filter: this.filter,
...rangeDates(this.range),
}); });
} }
@ -36,6 +41,13 @@ async function setFilter(filter) {
await this.fetchReleases(); await this.fetchReleases();
} }
async function setRange(range) {
this.range = range;
localStorage.setItem('range', this.range);
await this.fetchReleases();
}
async function mounted() { async function mounted() {
this.pageTitle = ''; this.pageTitle = '';
@ -49,9 +61,11 @@ export default {
}, },
data() { data() {
const storedFilter = localStorage.getItem('filter'); const storedFilter = localStorage.getItem('filter');
const storedRange = localStorage.getItem('range');
return { return {
filter: storedFilter ? storedFilter.split(',') : ['gay', 'transsexual'], filter: storedFilter ? storedFilter.split(',') : ['gay', 'transsexual'],
range: storedRange || 'new',
releases: [], releases: [],
networks: [], networks: [],
pageTitle: null, pageTitle: null,
@ -61,6 +75,7 @@ export default {
methods: { methods: {
fetchReleases, fetchReleases,
setFilter, setFilter,
setRange,
}, },
}; };
</script> </script>

View File

@ -9,6 +9,7 @@
<div class="column"> <div class="column">
<a <a
v-if="release.date" v-if="release.date"
v-tooltip.bottom="`View scene on ${release.site.name}`"
:title="`View scene on ${release.site.name}`" :title="`View scene on ${release.site.name}`"
:href="release.url" :href="release.url"
target="_blank" target="_blank"
@ -21,6 +22,7 @@
<a <a
v-if="release.date" v-if="release.date"
v-tooltip.bottom="`View scene on ${release.site.name}`"
:title="`View scene on ${release.site.name}`" :title="`View scene on ${release.site.name}`"
:href="release.url" :href="release.url"
target="_blank" target="_blank"
@ -33,6 +35,7 @@
<span <span
v-if="release.shootId" v-if="release.shootId"
v-tooltip.bottom="`Shoot #`"
class="tidbit shoot hideable" class="tidbit shoot hideable"
> >
<Icon icon="clapboard-play" /> <Icon icon="clapboard-play" />
@ -41,6 +44,7 @@
<span <span
v-if="release.duration" v-if="release.duration"
v-tooltip.bottom="`Duration`"
class="tidbit duration hideable" class="tidbit duration hideable"
> >
<Icon icon="stopwatch" /> <Icon icon="stopwatch" />
@ -127,6 +131,20 @@
</ul> </ul>
</div> </div>
<div
v-if="release.duration"
class="row duration showable"
>
<Icon icon="stopwatch" />
<span
v-if="release.duration >= 3600"
class="duration-segment"
>{{ Math.floor(release.duration / 3600) }}:</span>
<span class="duration-segment">{{ Math.floor((release.duration % 3600) / 60).toString().padStart(2, '0') }}:</span>
<span class="duration-segment">{{ (release.duration % 60).toString().padStart(2, '0') }}</span>
</div>
<p <p
v-if="release.description" v-if="release.description"
class="row description" class="row description"
@ -150,29 +168,19 @@
>{{ release.studio.name }}</a> >{{ release.studio.name }}</a>
</div> </div>
<a
v-if="release.shootId"
:href="release.url"
:title="`release.shootId`"
target="_blank"
rel="noopener noreferrer"
class="row shoot showable"
>
<Icon icon="clapboard-play" />{{ release.shootId }}
</a>
<div <div
v-if="release.duration" v-if="release.shootId"
class="row duration showable" class="row showable"
> >
<Icon icon="stopwatch" /> <Icon icon="clapboard-play" />
<span <a
v-if="release.duration >= 3600" :href="release.url"
class="duration-segment" :title="`release.shootId`"
>{{ Math.floor(release.duration / 3600) }}:</span> target="_blank"
<span class="duration-segment">{{ Math.floor((release.duration % 3600) / 60).toString().padStart(2, '0') }}:</span> rel="noopener noreferrer"
<span class="duration-segment">{{ (release.duration % 60).toString().padStart(2, '0') }}</span> class="link shoot"
>{{ release.shootId }}</a>
</div> </div>
<span class="row"> <span class="row">
@ -199,7 +207,7 @@ function pageTitle() {
} }
async function mounted() { async function mounted() {
[this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId }); this.release = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId });
} }
export default { export default {
@ -271,6 +279,7 @@ export default {
&.date, &.date,
&.duration, &.duration,
&.shoot { &.shoot {
flex-shrink: 0;
padding: 1.25rem 1rem 1.25rem 0; padding: 1.25rem 1rem 1.25rem 0;
margin: 0 1rem 0 0; margin: 0 1rem 0 0;
} }
@ -293,12 +302,14 @@ export default {
height: 3rem; height: 3rem;
max-width: 15rem; max-width: 15rem;
object-fit: contain; object-fit: contain;
object-position: 100% 50%;
} }
.logo-network { .logo-network {
height: 1.5rem; height: 1.5rem;
max-width: 10rem; max-width: 10rem;
object-fit: contain; object-fit: contain;
object-position: 100% 50%;
} }
.chain { .chain {
@ -373,7 +384,8 @@ export default {
} }
.logo-site { .logo-site {
max-width: 10rem; width: 15rem;
max-width: 100%;
} }
} }
</style> </style>

View File

@ -46,6 +46,6 @@ body {
@media(max-width: $breakpoint) { @media(max-width: $breakpoint) {
.scenes { .scenes {
grid-template-columns: repeat(auto-fit, minmax(22.5rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
} }
} }

18
assets/js/range-dates.js Normal file
View File

@ -0,0 +1,18 @@
function rangeDates(range) {
return ({
new: () => ({
after: new Date(0),
before: new Date(),
}),
upcoming: () => ({
after: new Date(),
before: new Date(2 ** 42),
}),
all: () => ({
after: new Date(0),
before: new Date(2 ** 42),
}),
})[range]();
}
export default rangeDates;

View File

@ -1,8 +1,22 @@
import dayjs from 'dayjs';
import { get } from '../api'; import { get } from '../api';
function initReleasesActions(_store, _router) { function initReleasesActions(_store, _router) {
async function fetchReleases({ _commit }, { id, filter }) { async function fetchReleases({ _commit }, {
const releases = await get(`/releases/${id || ''}`, { filter }); id,
filter,
after,
before,
}) {
const afterString = dayjs(after).format('YYYY-MM-DD');
const beforeString = dayjs(before).format('YYYY-MM-DD');
const releases = await get(`/releases/${id || ''}`, {
filter,
after: afterString,
before: beforeString,
});
return releases; return releases;
} }

View File

@ -42,7 +42,8 @@
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.filter-bar[data-v-a678373a] { .filter-bar[data-v-a678373a] {
background: #fff; background: #fff;
display: block; display: flex;
justify-content: space-between;
padding: .5rem 1rem; padding: .5rem 1rem;
font-size: 0; font-size: 0;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
@ -59,6 +60,26 @@
display: none; display: none;
margin: 0 0 0 .5rem; margin: 0 0 0 .5rem;
} }
.range-button[data-v-a678373a] {
color: rgba(0, 0, 0, 0.5);
background: #fff;
display: inline-block;
padding: .5rem 1rem;
border: none;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
font-size: .8rem;
font-weight: bold;
}
.range-button[data-v-a678373a]:hover {
color: #222;
cursor: pointer;
}
.range-input[data-v-a678373a] {
display: none;
}
.range-input:checked + .range-button[data-v-a678373a] {
color: #ff6c88;
}
@media (max-width: 720px) { @media (max-width: 720px) {
.filters-container[data-v-a678373a] { .filters-container[data-v-a678373a] {
display: none; display: none;
@ -271,6 +292,7 @@
margin: 0 .25rem 0 0; margin: 0 .25rem 0 0;
} }
.tidbit.date[data-v-2bc41e74], .tidbit.duration[data-v-2bc41e74], .tidbit.shoot[data-v-2bc41e74] { .tidbit.date[data-v-2bc41e74], .tidbit.duration[data-v-2bc41e74], .tidbit.shoot[data-v-2bc41e74] {
flex-shrink: 0;
padding: 1.25rem 1rem 1.25rem 0; padding: 1.25rem 1rem 1.25rem 0;
margin: 0 1rem 0 0; margin: 0 1rem 0 0;
} }
@ -290,12 +312,16 @@
max-width: 15rem; max-width: 15rem;
-o-object-fit: contain; -o-object-fit: contain;
object-fit: contain; object-fit: contain;
-o-object-position: 100% 50%;
object-position: 100% 50%;
} }
.logo-network[data-v-2bc41e74] { .logo-network[data-v-2bc41e74] {
height: 1.5rem; height: 1.5rem;
max-width: 10rem; max-width: 10rem;
-o-object-fit: contain; -o-object-fit: contain;
object-fit: contain; object-fit: contain;
-o-object-position: 100% 50%;
object-position: 100% 50%;
} }
.chain[data-v-2bc41e74] { .chain[data-v-2bc41e74] {
color: rgba(0, 0, 0, 0.5); color: rgba(0, 0, 0, 0.5);
@ -355,7 +381,8 @@
display: block; display: block;
} }
.logo-site[data-v-2bc41e74] { .logo-site[data-v-2bc41e74] {
max-width: 10rem; width: 15rem;
max-width: 100%;
} }
} }
@ -686,7 +713,7 @@ body {
@media (max-width: 720px) { @media (max-width: 720px) {
.scenes { .scenes {
grid-template-columns: repeat(auto-fit, minmax(22.5rem, 1fr)); } } grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); } }
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.header[data-v-10b7ec04] { .header[data-v-10b7ec04] {

View File

@ -992,6 +992,7 @@ function getSites(networksMap) {
name: 'Evil Angel', name: 'Evil Angel',
url: 'https://evilangel.com', url: 'https://evilangel.com',
description: 'Welcome to the award winning Evil Angel website, home to the most popular pornstars of today, yesterday and tomorrow in their most extreme and hardcore porn scenes to date. We feature almost 30 years of rough sex videos and hardcore anal porn like you\'ve never seen before, and have won countless AVN and XBiz awards including \'Best Site\' and \'Best Studio\'.', description: 'Welcome to the award winning Evil Angel website, home to the most popular pornstars of today, yesterday and tomorrow in their most extreme and hardcore porn scenes to date. We feature almost 30 years of rough sex videos and hardcore anal porn like you\'ve never seen before, and have won countless AVN and XBiz awards including \'Best Site\' and \'Best Studio\'.',
parameters: JSON.stringify({ independent: true }),
network_id: networksMap['evilangel'], network_id: networksMap['evilangel'],
}, },
// JULES JORDAN // JULES JORDAN

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const knex = require('./knex'); const knex = require('./knex');
const whereOr = require('./utils/where-or');
async function curateRelease(release) { async function curateRelease(release) {
const [actors, tags, media] = await Promise.all([ const [actors, tags, media] = await Promise.all([
@ -70,10 +71,13 @@ function curateReleases(releases) {
return Promise.all(releases.map(async release => curateRelease(release))); return Promise.all(releases.map(async release => curateRelease(release)));
} }
async function fetchReleases(releaseId, filter = []) { function commonQuery(queryBuilder, {
// const straightFilter = filter.includes('straight') ? ['gay', 'lesbian'] : []; filter = [],
after = new Date(0), // January 1970
const releases = await knex('releases') before = new Date(2 ** 44), // May 2109
limit = 100,
}) {
queryBuilder
.leftJoin('sites', 'releases.site_id', 'sites.id') .leftJoin('sites', 'releases.site_id', 'sites.id')
.leftJoin('studios', 'releases.studio_id', 'studios.id') .leftJoin('studios', 'releases.studio_id', 'studios.id')
.leftJoin('networks', 'sites.network_id', 'networks.id') .leftJoin('networks', 'sites.network_id', 'networks.id')
@ -84,7 +88,7 @@ async function fetchReleases(releaseId, filter = []) {
'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', 'networks.description as network_description', 'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', 'networks.description as network_description',
) )
.whereNotExists((builder) => { .whereNotExists((builder) => {
// apply filters // apply tag filters
builder builder
.select('*') .select('*')
.from('tags_associated') .from('tags_associated')
@ -92,91 +96,58 @@ async function fetchReleases(releaseId, filter = []) {
.whereIn('tags.slug', filter) .whereIn('tags.slug', filter)
.andWhereRaw('tags_associated.release_id = releases.id'); .andWhereRaw('tags_associated.release_id = releases.id');
}) })
.andWhere(releaseId ? { 'releases.id': releaseId } : {}) .andWhere('date', '>', after)
.andWhere('date', '<=', before)
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }]) .orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
.limit(100); .limit(limit);
return curateReleases(releases);
} }
async function fetchSiteReleases(siteId, siteSlug) { async function fetchReleases(queryObject = {}, options = {}) {
const releases = await knex('releases') const releases = await knex('releases')
.where({ 'sites.id': siteId }) .modify(commonQuery, options)
.orWhere({ 'sites.slug': siteSlug }) .andWhere(builder => whereOr(queryObject, 'releases', builder));
.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',
)
.leftJoin('sites', 'releases.site_id', 'sites.id')
.leftJoin('studios', 'releases.studio_id', 'studios.id')
.leftJoin('networks', 'sites.network_id', 'networks.id')
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
.limit(100);
return curateReleases(releases); return curateReleases(releases);
} }
async function fetchNetworkReleases(networkId, networkSlug) { async function fetchSiteReleases(queryObject, options = {}) {
const releases = await knex('releases') const releases = await knex('releases')
.where({ 'networks.id': networkId }) .modify(commonQuery, options)
.orWhere({ 'networks.slug': networkSlug }) .where(builder => whereOr(queryObject, 'sites', builder));
.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',
)
.leftJoin('sites', 'releases.site_id', 'sites.id')
.leftJoin('studios', 'releases.studio_id', 'studios.id')
.leftJoin('networks', 'sites.network_id', 'networks.id')
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
.limit(100);
return curateReleases(releases); return curateReleases(releases);
} }
async function fetchActorReleases(actorId, actorSlug) { async function fetchNetworkReleases(queryObject, options = {}) {
const releases = await knex('releases')
.modify(commonQuery, options)
.where(builder => whereOr(queryObject, 'networks', builder));
return curateReleases(releases);
}
async function fetchActorReleases(queryObject, options = {}) {
const releases = await knex('actors_associated') const releases = await knex('actors_associated')
.where({ 'actors.id': actorId })
.orWhere({ 'actors.slug': actorSlug })
.select(
'releases.*',
'actors.name as actor_name',
'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',
)
.leftJoin('releases', 'actors_associated.release_id', 'releases.id') .leftJoin('releases', 'actors_associated.release_id', 'releases.id')
.leftJoin('actors', 'actors_associated.actor_id', 'actors.id') .leftJoin('actors', 'actors_associated.actor_id', 'actors.id')
.leftJoin('sites', 'releases.site_id', 'sites.id') .select(
.leftJoin('studios', 'releases.studio_id', 'studios.id') 'actors.name as actor_name',
.leftJoin('networks', 'sites.network_id', 'networks.id') )
.orderBy([{ column: 'releases.date', order: 'desc' }, { column: 'releases.created_at', order: 'desc' }]) .modify(commonQuery, options)
.limit(100); .where(builder => whereOr(queryObject, 'actors', builder));
return curateReleases(releases); return curateReleases(releases);
} }
async function fetchTagReleases(tagId, tagSlug) { async function fetchTagReleases(queryObject, options = {}) {
const releases = await knex('tags_associated') const releases = await knex('tags_associated')
.where({ 'tags.id': tagId })
.orWhere({ 'tags.slug': tagSlug })
.select(
'releases.*',
'tags.name as tag_name',
'sites.name as site_name', 'sites.slug as site_slug', 'sites.url as site_url', 'sites.network_id',
'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',
)
.leftJoin('releases', 'tags_associated.release_id', 'releases.id') .leftJoin('releases', 'tags_associated.release_id', 'releases.id')
.leftJoin('tags', 'tags_associated.tag_id', 'tags.id') .leftJoin('tags', 'tags_associated.tag_id', 'tags.id')
.leftJoin('sites', 'releases.site_id', 'sites.id') .select(
.leftJoin('studios', 'releases.studio_id', 'studios.id') 'tags.name as tag_name',
.leftJoin('networks', 'sites.network_id', 'networks.id') )
.orderBy([{ column: 'releases.date', order: 'desc' }, { column: 'releases.created_at', order: 'desc' }]) .modify(commonQuery, options)
.limit(100); .where(builder => whereOr(queryObject, 'tags', builder));
return curateReleases(releases); return curateReleases(releases);
} }

View File

@ -9,16 +9,33 @@ const {
} = require('../releases'); } = require('../releases');
async function fetchReleasesApi(req, res) { async function fetchReleasesApi(req, res) {
const releases = await fetchReleases(req.params.releaseId, req.query.filter ? [].concat(req.query.filter) : []); const filter = req.query.filter ? [].concat(req.query.filter) : []; // don't filter for 'undefined'
const releases = await fetchReleases({}, {
filter,
after: req.query.after,
before: req.query.before,
});
res.send(releases); res.send(releases);
} }
async function fetchReleaseByIdApi(req, res) {
const [release] = await fetchReleases({
id: req.params.releaseId,
});
res.send(release);
}
async function fetchActorReleasesApi(req, res) { async function fetchActorReleasesApi(req, res) {
const actorId = Number.isInteger(Number(req.params.actorId)) ? Number(req.params.actorId) : null; const actorId = Number.isInteger(Number(req.params.actorId)) ? Number(req.params.actorId) : null;
const actorSlug = typeof req.params.actorId === 'string' ? req.params.actorId : null; const actorSlug = typeof req.params.actorId === 'string' ? req.params.actorId : null;
const releases = await fetchActorReleases(actorId, actorSlug); const releases = await fetchActorReleases({
id: actorId,
slug: actorSlug,
});
res.send(releases); res.send(releases);
} }
@ -27,7 +44,10 @@ async function fetchNetworkReleasesApi(req, res) {
const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : null; const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : null;
const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : null; const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : null;
const releases = await fetchNetworkReleases(networkId, networkSlug); const releases = await fetchNetworkReleases({
id: networkId,
slug: networkSlug,
});
res.send(releases); res.send(releases);
} }
@ -36,7 +56,10 @@ async function fetchSiteReleasesApi(req, res) {
const siteId = typeof req.params.siteId === 'number' ? req.params.siteId : null; const siteId = typeof req.params.siteId === 'number' ? req.params.siteId : null;
const siteSlug = typeof req.params.siteId === 'string' ? req.params.siteId : null; const siteSlug = typeof req.params.siteId === 'string' ? req.params.siteId : null;
const releases = await fetchSiteReleases(siteId, siteSlug); const releases = await fetchSiteReleases({
id: siteId,
slug: siteSlug,
});
res.send(releases); res.send(releases);
} }
@ -45,13 +68,17 @@ async function fetchTagReleasesApi(req, res) {
const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : null; const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : null;
const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : null; const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : null;
const releases = await fetchTagReleases(tagId, tagSlug); const releases = await fetchTagReleases({
id: tagId,
slug: tagSlug,
});
res.send(releases); res.send(releases);
} }
module.exports = { module.exports = {
fetchReleases: fetchReleasesApi, fetchReleases: fetchReleasesApi,
fetchReleaseById: fetchReleaseByIdApi,
fetchActorReleases: fetchActorReleasesApi, fetchActorReleases: fetchActorReleasesApi,
fetchNetworkReleases: fetchNetworkReleasesApi, fetchNetworkReleases: fetchNetworkReleasesApi,
fetchSiteReleases: fetchSiteReleasesApi, fetchSiteReleases: fetchSiteReleasesApi,

View File

@ -8,6 +8,7 @@ const bodyParser = require('body-parser');
const { const {
fetchReleases, fetchReleases,
fetchReleaseById,
fetchActorReleases, fetchActorReleases,
fetchNetworkReleases, fetchNetworkReleases,
fetchSiteReleases, fetchSiteReleases,
@ -37,7 +38,7 @@ function initServer() {
router.use(bodyParser.json({ strict: false })); router.use(bodyParser.json({ strict: false }));
router.get('/api/releases', fetchReleases); router.get('/api/releases', fetchReleases);
router.get('/api/releases/:releaseId', fetchReleases); router.get('/api/releases/:releaseId', fetchReleaseById);
router.get('/api/releases/networks', fetchNetworksFromReleases); router.get('/api/releases/networks', fetchNetworksFromReleases);
router.get('/api/actors', fetchActors); router.get('/api/actors', fetchActors);