Compare commits
58 Commits
7372b560b2
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33a327a04b | ||
|
|
a46061e247 | ||
|
|
94e07ff23d | ||
|
|
4811befcf6 | ||
|
|
c455f02c66 | ||
|
|
efc5620a28 | ||
|
|
61123fdb6a | ||
|
|
3ec6911d46 | ||
|
|
2021093645 | ||
|
|
1c72dc202f | ||
|
|
1ef946fa77 | ||
|
|
3b6bbc39ff | ||
|
|
481c9feada | ||
|
|
953b3e9568 | ||
|
|
bdd2e68f49 | ||
|
|
e4cc349302 | ||
|
|
6547b93e55 | ||
|
|
bb9649d23b | ||
|
|
9e2eaef9d1 | ||
|
|
1c3ee75d3b | ||
|
|
15c9af8057 | ||
|
|
295573c1ef | ||
|
|
e93e8ace5c | ||
|
|
43af7ba777 | ||
|
|
0dad5b0d68 | ||
|
|
ae9b793318 | ||
|
|
fd8170f223 | ||
|
|
661b8b716b | ||
|
|
5ff076cac3 | ||
|
|
41c100ac4e | ||
|
|
c6e977f842 | ||
|
|
50b7f521b5 | ||
|
|
f0d0ee3acc | ||
|
|
7b3bdadd44 | ||
|
|
5deba6b90f | ||
|
|
a5afffc968 | ||
|
|
a239a5c593 | ||
|
|
e56e7333e3 | ||
|
|
d55e3c37cd | ||
|
|
97b78ea016 | ||
|
|
3e290b74dc | ||
|
|
65141207ae | ||
|
|
17dfeac1af | ||
|
|
4a9c428d69 | ||
|
|
333f252099 | ||
|
|
38232f258a | ||
|
|
582269cfaa | ||
|
|
0b646429fd | ||
|
|
fecef6c1cf | ||
|
|
73e5404c44 | ||
|
|
690d2bb3ed | ||
|
|
1dd935e1e9 | ||
|
|
8386230f33 | ||
|
|
5a68b06137 | ||
|
|
5918364cf5 | ||
|
|
df4d860d35 | ||
|
|
d9f0db6e3c | ||
|
|
ccb99e278c |
@@ -62,7 +62,7 @@ async function setConsent(consent, includeQueer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (includeQueer) {
|
if (includeQueer) {
|
||||||
this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter(tag => !['gay', 'bisexual', 'transsexual'].includes(tag)));
|
this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter((tag) => !['gay', 'bisexual', 'transsexual'].includes(tag)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,7 @@
|
|||||||
:fetch-releases="fetchEntity"
|
:fetch-releases="fetchEntity"
|
||||||
:items-total="totalCount"
|
:items-total="totalCount"
|
||||||
:items-per-page="limit"
|
:items-per-page="limit"
|
||||||
|
:available-tags="entity.tags"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="releases">
|
<div class="releases">
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this.svg = require(`../../img/icons/${this.icon}.svg`).default;
|
this.svg = require(`../../img/icons/${this.icon}.svg`).default; // eslint-disable-line global-require, import/no-dynamic-require
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,16 +11,31 @@
|
|||||||
class="empty"
|
class="empty"
|
||||||
>No results for "{{ $route.query.query }}"</span>
|
>No results for "{{ $route.query.query }}"</span>
|
||||||
|
|
||||||
<div
|
<template v-else>
|
||||||
v-else
|
<h2 class="heading">Popular</h2>
|
||||||
class="entity-tiles"
|
|
||||||
>
|
<div
|
||||||
<Entity
|
class="entity-tiles"
|
||||||
v-for="entity in entities"
|
>
|
||||||
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
<Entity
|
||||||
:entity="entity"
|
v-for="entity in popularEntities"
|
||||||
/>
|
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
||||||
</div>
|
:entity="entity"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="heading">All networks</h2>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="entity-tiles"
|
||||||
|
>
|
||||||
|
<Entity
|
||||||
|
v-for="entity in entities"
|
||||||
|
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
||||||
|
:entity="entity"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
@@ -58,6 +73,45 @@ async function searchEntities() {
|
|||||||
this.done = true;
|
this.done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function popularEntities() {
|
||||||
|
const entitiesBySlug = Object.fromEntries(this.entities.map((entity) => [entity.slug, entity]));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'21sextury',
|
||||||
|
'amateurallure',
|
||||||
|
'analvids',
|
||||||
|
'bamvisions',
|
||||||
|
'bang',
|
||||||
|
'bangbros',
|
||||||
|
'blowpass',
|
||||||
|
'brazzers',
|
||||||
|
'burningangel',
|
||||||
|
'digitalplayground',
|
||||||
|
'dogfartnetwork',
|
||||||
|
'dorcel',
|
||||||
|
'elegantangel',
|
||||||
|
'evilangel',
|
||||||
|
'fakehub',
|
||||||
|
'girlsway',
|
||||||
|
'hookuphotshot',
|
||||||
|
'hussiepass',
|
||||||
|
'insex',
|
||||||
|
'julesjordan',
|
||||||
|
'kellymadison',
|
||||||
|
'kink',
|
||||||
|
'mofos',
|
||||||
|
'naughtyamerica',
|
||||||
|
'newsensations',
|
||||||
|
'pervcity',
|
||||||
|
'pornpros',
|
||||||
|
'private',
|
||||||
|
'realitykings',
|
||||||
|
'twistys',
|
||||||
|
'vixen',
|
||||||
|
'xempire',
|
||||||
|
].map((slug) => entitiesBySlug[slug]).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
async function mounted() {
|
async function mounted() {
|
||||||
this.pageTitle = 'Channels';
|
this.pageTitle = 'Channels';
|
||||||
|
|
||||||
@@ -82,6 +136,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
channelCount,
|
channelCount,
|
||||||
|
popularEntities,
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: fetchEntities,
|
$route: fetchEntities,
|
||||||
@@ -130,6 +185,10 @@ export default {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
margin: 1rem 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint2) {
|
@media(max-width: $breakpoint2) {
|
||||||
.entity-tiles {
|
.entity-tiles {
|
||||||
grid-gap: .5rem;
|
grid-gap: .5rem;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="media-container">
|
<div class="media-container">
|
||||||
<div
|
<div
|
||||||
class="media"
|
class="media"
|
||||||
:class="{ center: release.photos.length < 2, preview: !me }"
|
:class="{ center: (release.photos?.length || 0) + (release.scenesPhotos?.length || 0) < 2, preview: !me }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="release.trailer || release.teaser"
|
v-if="release.trailer || release.teaser"
|
||||||
@@ -71,24 +71,28 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="release.covers && release.covers.length > 0">
|
<template v-if="release.covers?.length > 0">
|
||||||
<a
|
<div
|
||||||
v-for="cover in release.covers"
|
v-for="cover in release.covers"
|
||||||
:key="`cover-${cover.id}`"
|
:key="`cover-${cover.id}`"
|
||||||
:href="getPath(cover)"
|
class="item-container"
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
<img
|
<a
|
||||||
:src="getPath(cover, 'thumbnail')"
|
:href="getPath(cover)"
|
||||||
:style="{ 'background-image': getBgPath(cover, 'lazy') }"
|
target="_blank"
|
||||||
:width="cover.thumbnailWidth"
|
rel="noopener noreferrer"
|
||||||
:height="cover.thumbnailHeight"
|
|
||||||
class="item cover"
|
|
||||||
loading="lazy"
|
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
>
|
||||||
</a>
|
<img
|
||||||
|
:src="getPath(cover, 'thumbnail')"
|
||||||
|
:style="{ 'background-image': getBgPath(cover, 'lazy') }"
|
||||||
|
:width="cover.thumbnailWidth"
|
||||||
|
:height="cover.thumbnailHeight"
|
||||||
|
class="item cover"
|
||||||
|
loading="lazy"
|
||||||
|
@load="$emit('load', $event)"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -164,8 +168,8 @@ function poster() {
|
|||||||
function photos() {
|
function photos() {
|
||||||
const clips = this.release.clips || [];
|
const clips = this.release.clips || [];
|
||||||
const clipPostersById = clips.reduce((acc, clip) => ({ ...acc, [clip.poster.id]: clip.poster }), {});
|
const clipPostersById = clips.reduce((acc, clip) => ({ ...acc, [clip.poster.id]: clip.poster }), {});
|
||||||
const uniqueClipPosters = Array.from(new Set(clips.map(clip => clip.poster.id) || [])).map(posterId => clipPostersById[posterId]);
|
const uniqueClipPosters = Array.from(new Set(clips.map((clip) => clip.poster.id) || [])).map((posterId) => clipPostersById[posterId]);
|
||||||
const photosWithClipPosters = (this.release.photos || []).concat(uniqueClipPosters);
|
const photosWithClipPosters = (this.release.photos || []).concat(this.release.scenesPhotos || []).concat(uniqueClipPosters);
|
||||||
|
|
||||||
if (this.release.trailer || (this.release.teaser && this.release.teaser.mime !== 'image/gif')) {
|
if (this.release.trailer || (this.release.teaser && this.release.teaser.mime !== 'image/gif')) {
|
||||||
// poster will be on trailer video
|
// poster will be on trailer video
|
||||||
|
|||||||
@@ -3,12 +3,6 @@
|
|||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<SearchBar :placeholder="`Search ${totalCount} movies`" />
|
<SearchBar :placeholder="`Search ${totalCount} movies`" />
|
||||||
|
|
||||||
<TagFilter
|
|
||||||
class="filters-filter"
|
|
||||||
:filter="filter"
|
|
||||||
:available-tags="availableTags"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref="tiles"
|
ref="tiles"
|
||||||
class="tiles"
|
class="tiles"
|
||||||
@@ -36,7 +30,6 @@
|
|||||||
import MovieTile from './movie-tile.vue';
|
import MovieTile from './movie-tile.vue';
|
||||||
import SearchBar from '../search/bar.vue';
|
import SearchBar from '../search/bar.vue';
|
||||||
import Pagination from '../pagination/pagination.vue';
|
import Pagination from '../pagination/pagination.vue';
|
||||||
import TagFilter from '../filters/tag-filter.vue';
|
|
||||||
|
|
||||||
async function fetchMovies() {
|
async function fetchMovies() {
|
||||||
if (this.$route.query.query) {
|
if (this.$route.query.query) {
|
||||||
@@ -80,7 +73,6 @@ export default {
|
|||||||
MovieTile,
|
MovieTile,
|
||||||
SearchBar,
|
SearchBar,
|
||||||
Pagination,
|
Pagination,
|
||||||
TagFilter,
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
<Details :release="release" />
|
<Details :release="release" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="release.photos.length > 0"
|
v-if="release.photos?.length > 0 || release.scenesPhotos?.length > 0"
|
||||||
class="album-toggle"
|
class="album-toggle"
|
||||||
@click="$router.push({ hash: '#album' })"
|
@click="$router.push({ hash: '#album' })"
|
||||||
><Icon icon="grid3" />View album</button>
|
><Icon icon="grid3" />View album</button>
|
||||||
|
|
||||||
<Album
|
<Album
|
||||||
v-if="showAlbum"
|
v-if="showAlbum"
|
||||||
:items="[release.poster, ...release.photos]"
|
:items="[release.poster, ...(release.photos || []), ...(release.scenesPhotos || [])]"
|
||||||
:title="release.title"
|
:title="release.title"
|
||||||
:path="config.media.mediaPath"
|
:path="config.media.mediaPath"
|
||||||
@close="$router.replace({ hash: undefined })"
|
@close="$router.replace({ hash: undefined })"
|
||||||
@@ -79,22 +79,23 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="release.movies && release.movies.length > 0"
|
v-if="release.movies?.length > 0 || release.series?.length > 0"
|
||||||
class="row"
|
class="row"
|
||||||
>
|
>
|
||||||
<span class="row-label">Part of</span>
|
<span class="row-label">Part of</span>
|
||||||
|
|
||||||
<div class="movies">
|
<div class="movies">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="movie in release.movies"
|
v-for="movie in [...release.movies, ...release.series]"
|
||||||
:key="`movie-${movie.id}`"
|
:key="`movie-${movie.id}`"
|
||||||
:to="{ name: 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
:to="{ name: movie.type || 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
||||||
class="movie"
|
class="movie"
|
||||||
>
|
>
|
||||||
<span class="movie-title">{{ movie.title }}</span>
|
<span class="movie-title">{{ movie.title }}</span>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-if="movie.covers.length > 0"
|
v-if="movie.covers.length > 0 || movie.poster"
|
||||||
:src="getPath(movie.covers[0], 'thumbnail')"
|
:src="getPath(movie.covers[0] || movie.poster, 'thumbnail')"
|
||||||
class="movie-cover"
|
class="movie-cover"
|
||||||
>
|
>
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -243,6 +244,10 @@ async function fetchRelease(scroll = true) {
|
|||||||
this.release = await this.$store.dispatch('fetchMovieById', this.$route.params.releaseId);
|
this.release = await this.$store.dispatch('fetchMovieById', this.$route.params.releaseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.$route.name === 'serie') {
|
||||||
|
this.release = await this.$store.dispatch('fetchSerieById', this.$route.params.releaseId);
|
||||||
|
}
|
||||||
|
|
||||||
if (scroll && this.$refs.content) {
|
if (scroll && this.$refs.content) {
|
||||||
this.$refs.content.scrollTop = 0;
|
this.$refs.content.scrollTop = 0;
|
||||||
}
|
}
|
||||||
@@ -282,7 +287,7 @@ function pageTitle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showAlbum() {
|
function showAlbum() {
|
||||||
return this.release.photos?.length > 0 && this.$route.hash === '#album';
|
return (this.release.photos?.length > 0 || this.release.scenesPhotos?.length > 0) && this.$route.hash === '#album';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ const tagSlugsByCategory = {
|
|||||||
'titty-fucking',
|
'titty-fucking',
|
||||||
'fisting',
|
'fisting',
|
||||||
'anal-fisting',
|
'anal-fisting',
|
||||||
'fisting-dp',
|
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
'mfm',
|
'mfm',
|
||||||
@@ -108,16 +107,6 @@ const tagSlugsByCategory = {
|
|||||||
'bukkake',
|
'bukkake',
|
||||||
'fake-cum',
|
'fake-cum',
|
||||||
],
|
],
|
||||||
toys: [
|
|
||||||
'toys',
|
|
||||||
'toy-anal',
|
|
||||||
'toy-dp',
|
|
||||||
'double-dildo',
|
|
||||||
'double-dildo-blowjob',
|
|
||||||
'double-dildo-kiss',
|
|
||||||
'double-dildo-anal',
|
|
||||||
'double-dildo-dp',
|
|
||||||
],
|
|
||||||
roleplay: [
|
roleplay: [
|
||||||
'family',
|
'family',
|
||||||
'parody',
|
'parody',
|
||||||
@@ -126,6 +115,15 @@ const tagSlugsByCategory = {
|
|||||||
'maid',
|
'maid',
|
||||||
'nun',
|
'nun',
|
||||||
],
|
],
|
||||||
|
extreme: [
|
||||||
|
'dp',
|
||||||
|
'airtight',
|
||||||
|
'dap',
|
||||||
|
'dvp',
|
||||||
|
'triple-penetration',
|
||||||
|
'tap',
|
||||||
|
'tvp',
|
||||||
|
],
|
||||||
fetish: [
|
fetish: [
|
||||||
'bdsm',
|
'bdsm',
|
||||||
'femdom',
|
'femdom',
|
||||||
@@ -134,15 +132,15 @@ const tagSlugsByCategory = {
|
|||||||
'latex',
|
'latex',
|
||||||
'blindfold',
|
'blindfold',
|
||||||
],
|
],
|
||||||
extreme: [
|
toys: [
|
||||||
'dp',
|
'toys',
|
||||||
'airtight',
|
'toy-anal',
|
||||||
'dap',
|
'toy-dp',
|
||||||
'dvp',
|
'double-dildo',
|
||||||
'da-tp',
|
'double-dildo-blowjob',
|
||||||
'dv-tp',
|
'double-dildo-kiss',
|
||||||
'tap',
|
'double-dildo-anal',
|
||||||
'tvp',
|
'double-dildo-dp',
|
||||||
],
|
],
|
||||||
misc: [
|
misc: [
|
||||||
'gaping',
|
'gaping',
|
||||||
|
|||||||
@@ -65,19 +65,23 @@ function curateActor(actor, release) {
|
|||||||
return curatedActor;
|
return curatedActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function curateRelease(release) {
|
function curateRelease(release, type = 'scene') {
|
||||||
const curatedRelease = {
|
const curatedRelease = {
|
||||||
...release,
|
...release,
|
||||||
|
type: release.type || type,
|
||||||
actors: [],
|
actors: [],
|
||||||
poster: release.poster && release.poster.media,
|
poster: release.poster && release.poster.media,
|
||||||
tags: release.tags ? release.tags.map((tag) => tag.tag || tag) : [],
|
tags: release.tags ? release.tags.map((tag) => tag.tag || tag) : [],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (release.scenes) curatedRelease.scenes = release.scenes.filter(Boolean).map(({ scene }) => curateRelease(scene));
|
curatedRelease.scenes = release.scenes?.filter(Boolean).map(({ scene }) => curateRelease(scene, 'scene')) || [];
|
||||||
if (release.movies) curatedRelease.movies = release.movies.filter(Boolean).map(({ movie }) => curateRelease(movie));
|
curatedRelease.movies = release.movies?.filter(Boolean).map(({ movie }) => curateRelease(movie, 'movie')) || [];
|
||||||
if (release.chapters) curatedRelease.chapters = release.chapters.filter(Boolean).map((chapter) => curateRelease(chapter));
|
curatedRelease.series = release.series?.filter(Boolean).map(({ serie }) => curateRelease(serie, 'serie')) || [];
|
||||||
if (release.photos) curatedRelease.photos = release.photos.filter(Boolean).map((photo) => photo.media || photo);
|
curatedRelease.chapters = release.chapters?.filter(Boolean).map((chapter) => curateRelease(chapter)) || [];
|
||||||
if (release.covers) curatedRelease.covers = release.covers.filter(Boolean).map(({ media }) => media);
|
curatedRelease.photos = release.photos?.filter(Boolean).map((photo) => photo.media || photo) || [];
|
||||||
|
curatedRelease.scenesPhotos = release.scenesPhotos?.filter(Boolean).map((photo) => photo.media || photo) || [];
|
||||||
|
curatedRelease.covers = release.covers?.filter(Boolean).map(({ media }) => media) || [];
|
||||||
|
|
||||||
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
||||||
if (release.teaser) curatedRelease.teaser = release.teaser.media;
|
if (release.teaser) curatedRelease.teaser = release.teaser.media;
|
||||||
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map((actor) => curateActor(actor.actor || actor, curatedRelease));
|
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map((actor) => curateActor(actor.actor || actor, curatedRelease));
|
||||||
@@ -105,6 +109,7 @@ function curateEntity(entity, parent, releases) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (entity.tags) curatedEntity.tags = entity.tags.map(({ tag }) => tag);
|
if (entity.tags) curatedEntity.tags = entity.tags.map(({ tag }) => tag);
|
||||||
|
if (entity.sceneTags) curatedEntity.sceneTags = entity.sceneTags;
|
||||||
|
|
||||||
if (entity.children) {
|
if (entity.children) {
|
||||||
if (entity.children.nodes) {
|
if (entity.children.nodes) {
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ function initEntitiesActions(store, router) {
|
|||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sceneTags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
children: childEntitiesConnection(
|
children: childEntitiesConnection(
|
||||||
orderBy: [PRIORITY_DESC, NAME_ASC],
|
orderBy: [PRIORITY_DESC, NAME_ASC],
|
||||||
filter: {
|
filter: {
|
||||||
@@ -87,7 +92,7 @@ function initEntitiesActions(store, router) {
|
|||||||
or: [
|
or: [
|
||||||
{
|
{
|
||||||
date: {
|
date: {
|
||||||
isNull: ${entityType === 'channel'}
|
isNull: ${entityType !== 'network'}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -442,6 +442,29 @@ const releasesFragment = `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const mediaFields = `
|
||||||
|
id
|
||||||
|
index
|
||||||
|
path
|
||||||
|
thumbnail
|
||||||
|
lazy
|
||||||
|
isS3
|
||||||
|
comment
|
||||||
|
sfw: sfwMedia {
|
||||||
|
id
|
||||||
|
thumbnail
|
||||||
|
lazy
|
||||||
|
path
|
||||||
|
comment
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const mediaFragment = `
|
||||||
|
media {
|
||||||
|
${mediaFields}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const releaseFragment = `
|
const releaseFragment = `
|
||||||
release(id: $releaseId) {
|
release(id: $releaseId) {
|
||||||
id
|
id
|
||||||
@@ -536,6 +559,19 @@ const releaseFragment = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
series: seriesScenesBySceneId {
|
||||||
|
serie {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
slug
|
||||||
|
covers: seriesCoversBySerieId(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
|
${mediaFragment}
|
||||||
|
}
|
||||||
|
poster: seriesPosterBySerieId {
|
||||||
|
${mediaFragment}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
isFavorited
|
isFavorited
|
||||||
isStashed(includeFavorites: false)
|
isStashed(includeFavorites: false)
|
||||||
stashes: stashesScenesBySceneId(
|
stashes: stashesScenesBySceneId(
|
||||||
@@ -624,6 +660,8 @@ export {
|
|||||||
actorFields,
|
actorFields,
|
||||||
actorStashesFields,
|
actorStashesFields,
|
||||||
campaignsFragment,
|
campaignsFragment,
|
||||||
|
mediaFields,
|
||||||
|
mediaFragment,
|
||||||
movieFields,
|
movieFields,
|
||||||
releaseActorsFragment,
|
releaseActorsFragment,
|
||||||
releaseFields,
|
releaseFields,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
releaseFragment,
|
releaseFragment,
|
||||||
releaseFields,
|
releaseFields,
|
||||||
movieFields,
|
movieFields,
|
||||||
|
mediaFragment,
|
||||||
|
mediaFields,
|
||||||
} from '../fragments';
|
} from '../fragments';
|
||||||
import { curateRelease } from '../curate';
|
import { curateRelease } from '../curate';
|
||||||
import getDateRange from '../get-date-range';
|
import getDateRange from '../get-date-range';
|
||||||
@@ -141,16 +143,16 @@ function initReleasesActions(store, router) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchMovieById({ _commit }, movieId) {
|
async function fetchCollectionById({ _commit }, movieId, type = 'movie') {
|
||||||
// const release = await get(`/releases/${releaseId}`);
|
// const release = await get(`/releases/${releaseId}`);
|
||||||
|
|
||||||
const { movie } = await graphql(`
|
const result = await graphql(`
|
||||||
query Movie(
|
query Movie(
|
||||||
$movieId: Int!
|
$movieId: Int!
|
||||||
$hasAuth: Boolean!
|
$hasAuth: Boolean!
|
||||||
$userId: Int
|
$userId: Int
|
||||||
) {
|
) {
|
||||||
movie(id: $movieId) {
|
${type}(id: $movieId) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
@@ -182,7 +184,7 @@ function initReleasesActions(store, router) {
|
|||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poster: moviesPoster {
|
poster: ${type === 'series' ? 'seriesPosterBySerieId' : 'moviesPoster'} {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
@@ -195,7 +197,7 @@ function initReleasesActions(store, router) {
|
|||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
covers: ${type === 'series' ? 'seriesCoversBySerieId' : 'moviesCovers'}(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
@@ -208,14 +210,14 @@ function initReleasesActions(store, router) {
|
|||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trailer: moviesTrailer {
|
trailer: ${type === 'series' ? 'seriesTrailerBySerieId' : 'moviesTrailer'} {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scenes: moviesScenes {
|
scenes: ${type === 'series' ? 'seriesScenesBySerieId' : 'moviesScenes'} {
|
||||||
scene {
|
scene {
|
||||||
${releaseFields}
|
${releaseFields}
|
||||||
}
|
}
|
||||||
@@ -225,25 +227,11 @@ function initReleasesActions(store, router) {
|
|||||||
slug
|
slug
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
photos {
|
photos: ${type === 'series' ? 'seriesPhotosBySerieId' : 'moviesPhotos'} {
|
||||||
id
|
${mediaFragment}
|
||||||
index
|
}
|
||||||
path
|
scenesPhotos {
|
||||||
thumbnail
|
${mediaFields}
|
||||||
lazy
|
|
||||||
width
|
|
||||||
height
|
|
||||||
thumbnailWidth
|
|
||||||
thumbnailHeight
|
|
||||||
isS3
|
|
||||||
comment
|
|
||||||
sfw: sfwMedia {
|
|
||||||
id
|
|
||||||
thumbnail
|
|
||||||
lazy
|
|
||||||
path
|
|
||||||
comment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
entity {
|
entity {
|
||||||
id
|
id
|
||||||
@@ -259,7 +247,7 @@ function initReleasesActions(store, router) {
|
|||||||
hasLogo
|
hasLogo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stashes: stashesMovies(
|
stashes: ${type === 'series' ? 'stashesSeriesBySerieId' : 'stashesMovies'}(
|
||||||
filter: {
|
filter: {
|
||||||
stash: {
|
stash: {
|
||||||
userId: {
|
userId: {
|
||||||
@@ -283,12 +271,20 @@ function initReleasesActions(store, router) {
|
|||||||
userId: store.state.auth.user?.id,
|
userId: store.state.auth.user?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!movie) {
|
if (!result[type]) {
|
||||||
router.replace('/not-found');
|
router.replace('/not-found');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return curateRelease(movie);
|
return curateRelease(result[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchMovieById(context, movieId) {
|
||||||
|
return fetchCollectionById(context, movieId, 'movie');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchSerieById(context, serieId) {
|
||||||
|
return fetchCollectionById(context, serieId, 'series');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -296,6 +292,7 @@ function initReleasesActions(store, router) {
|
|||||||
fetchReleaseById,
|
fetchReleaseById,
|
||||||
fetchMovies,
|
fetchMovies,
|
||||||
fetchMovieById,
|
fetchMovieById,
|
||||||
|
fetchSerieById,
|
||||||
searchMovies,
|
searchMovies,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ const routes = [
|
|||||||
component: Release,
|
component: Release,
|
||||||
name: 'movie',
|
name: 'movie',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/serie/:releaseId/:releaseSlug?',
|
||||||
|
component: Release,
|
||||||
|
name: 'serie',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/actor/:actorId/:actorSlug',
|
path: '/actor/:actorId/:actorSlug',
|
||||||
name: 'actor',
|
name: 'actor',
|
||||||
|
|||||||
@@ -298,10 +298,6 @@ module.exports = {
|
|||||||
interval: 1000,
|
interval: 1000,
|
||||||
concurrency: 1,
|
concurrency: 1,
|
||||||
},
|
},
|
||||||
'www.realitykings.com': {
|
|
||||||
interval: 1000,
|
|
||||||
concurrency: 1,
|
|
||||||
},
|
|
||||||
'westcoastproductions.com': {
|
'westcoastproductions.com': {
|
||||||
interval: 100,
|
interval: 100,
|
||||||
concurrency: 1,
|
concurrency: 1,
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ exports.up = async (knex) => knex.raw(`
|
|||||||
)
|
)
|
||||||
|
|
||||||
SELECT releases FROM releases
|
SELECT releases FROM releases
|
||||||
INNER JOIN children ON children.id = releases.entity_id;
|
INNER JOIN children ON children.id = releases.entity_id
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT releases FROM releases
|
||||||
|
INNER JOIN children ON children.id = releases.studio_id;
|
||||||
$$ LANGUAGE SQL STABLE;
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
COMMENT ON FUNCTION entities_scenes IS E'@sortable';
|
COMMENT ON FUNCTION entities_scenes IS E'@sortable';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
exports.up = async (knex) => knex.raw(`
|
exports.up = async (knex) => knex.raw(`
|
||||||
CREATE OR REPLACE FUNCTION entities_scene_total(entity entities) RETURNS integer AS $$
|
CREATE OR REPLACE FUNCTION entities_scene_total(entity entities) RETURNS bigint AS $$
|
||||||
SELECT COUNT(id)
|
SELECT COUNT(id)
|
||||||
FROM releases
|
FROM releases
|
||||||
WHERE releases.entity_id = entity.id;
|
WHERE releases.entity_id = entity.id;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
exports.up = async (knex) => knex.raw(`
|
|
||||||
CREATE VIEW movies_tagged AS
|
|
||||||
SELECT * FROM movies;
|
|
||||||
`);
|
|
||||||
|
|
||||||
exports.down = async (knex) => knex.raw(`
|
|
||||||
DROP VIEW IF EXISTS movies_tagged;
|
|
||||||
`);
|
|
||||||
23
migrations/20220227215315_entity_filters.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
exports.up = async (knex) => knex.raw(`
|
||||||
|
CREATE FUNCTION entities_scene_tags(entity entities, selectable_tags text[]) RETURNS SETOF tags AS $$
|
||||||
|
SELECT tags.*
|
||||||
|
FROM releases
|
||||||
|
LEFT JOIN
|
||||||
|
releases_tags ON releases_tags.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
tags ON tags.id = releases_tags.tag_id
|
||||||
|
WHERE
|
||||||
|
releases.entity_id = entity.id
|
||||||
|
AND
|
||||||
|
CASE WHEN array_length(selectable_tags, 1) IS NOT NULL
|
||||||
|
THEN tags.slug = ANY(selectable_tags)
|
||||||
|
ELSE true
|
||||||
|
END
|
||||||
|
GROUP BY tags.id
|
||||||
|
ORDER BY tags.name;
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
`);
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS entities_scene_tags;
|
||||||
|
`);
|
||||||
215
migrations/20220304233846_series.js
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
const config = require('config');
|
||||||
|
|
||||||
|
exports.up = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.schema.createTable('series', (table) => {
|
||||||
|
table.increments('id', 16);
|
||||||
|
|
||||||
|
table.integer('entity_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('entities')
|
||||||
|
.notNullable();
|
||||||
|
|
||||||
|
table.integer('studio_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('entities');
|
||||||
|
|
||||||
|
table.text('entry_id');
|
||||||
|
table.unique(['entity_id', 'entry_id']);
|
||||||
|
|
||||||
|
table.text('url', 1000);
|
||||||
|
table.text('title');
|
||||||
|
table.text('slug');
|
||||||
|
|
||||||
|
table.timestamp('date');
|
||||||
|
table.index('date');
|
||||||
|
|
||||||
|
table.enum('date_precision', ['year', 'month', 'week', 'day', 'hour', 'minute', 'second'])
|
||||||
|
.defaultTo('day');
|
||||||
|
|
||||||
|
table.text('description');
|
||||||
|
|
||||||
|
table.boolean('deep');
|
||||||
|
table.text('deep_url', 1000);
|
||||||
|
|
||||||
|
table.text('comment');
|
||||||
|
|
||||||
|
table.integer('created_batch_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('batches')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('updated_batch_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('batches')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_scenes', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('scene_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('releases')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'scene_id']);
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_trailers', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.unique()
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_posters', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique('serie_id');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_covers', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_search', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('stashes_series', (table) => {
|
||||||
|
table.integer('stash_id')
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('stashes')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('serie_id')
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique(['stash_id', 'serie_id']);
|
||||||
|
|
||||||
|
table.string('comment');
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.notNullable()
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
ALTER TABLE series_search ADD COLUMN document tsvector;
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX series_search_unique ON series_search (serie_id);
|
||||||
|
CREATE INDEX series_search_index ON series_search USING GIN (document);
|
||||||
|
|
||||||
|
CREATE FUNCTION series_actors(serie series) RETURNS SETOF actors AS $$
|
||||||
|
SELECT actors.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
LEFT JOIN
|
||||||
|
releases_actors ON releases_actors.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
actors ON actors.id = releases_actors.actor_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
AND actors.id IS NOT NULL
|
||||||
|
GROUP BY actors.id
|
||||||
|
ORDER BY actors.name, actors.gender
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
CREATE FUNCTION series_tags(serie series) RETURNS SETOF tags AS $$
|
||||||
|
SELECT tags.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
LEFT JOIN
|
||||||
|
releases_tags ON releases_tags.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
tags ON tags.id = releases_tags.tag_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
AND tags.id IS NOT NULL
|
||||||
|
GROUP BY tags.id
|
||||||
|
ORDER BY tags.priority DESC
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
CREATE FUNCTION series_photos(serie series) RETURNS SETOF media AS $$
|
||||||
|
SELECT media.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
INNER JOIN
|
||||||
|
releases_photos ON releases_photos.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
media ON media.id = releases_photos.media_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
GROUP BY media.id
|
||||||
|
ORDER BY media.index ASC
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
GRANT ALL ON ALL TABLES IN SCHEMA public TO :visitor;
|
||||||
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO :visitor;
|
||||||
|
|
||||||
|
ALTER TABLE stashes_series ENABLE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
|
CREATE POLICY stashes_policy ON stashes_series
|
||||||
|
USING (EXISTS (
|
||||||
|
SELECT *
|
||||||
|
FROM stashes
|
||||||
|
WHERE stashes.id = stashes_series.stash_id
|
||||||
|
AND (stashes.user_id = current_user_id() OR stashes.public)
|
||||||
|
));
|
||||||
|
`, {
|
||||||
|
visitor: knex.raw(config.database.query.user),
|
||||||
|
}));
|
||||||
|
|
||||||
|
exports.down = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS series_actors;
|
||||||
|
DROP FUNCTION IF EXISTS series_tags;
|
||||||
|
DROP FUNCTION IF EXISTS series_photos;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS stashes_series CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_scenes CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_trailers CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_posters CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_covers CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_search CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series CASCADE;
|
||||||
|
`));
|
||||||
49
migrations/20220327230125_movie_photos.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const config = require('config');
|
||||||
|
|
||||||
|
exports.up = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
ALTER FUNCTION movies_photos(movie movies) RENAME TO movies_scenes_photos;
|
||||||
|
ALTER FUNCTION series_photos(serie series) RENAME TO series_scenes_photos;
|
||||||
|
`))
|
||||||
|
.then(() => knex.schema.createTable('movies_photos', (table) => {
|
||||||
|
table.integer('movie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('movies')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['movie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_photos', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
GRANT ALL ON ALL TABLES IN SCHEMA public TO :visitor;
|
||||||
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO :visitor;
|
||||||
|
`, {
|
||||||
|
visitor: knex.raw(config.database.query.user),
|
||||||
|
}));
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP TABLE IF EXISTS movies_photos CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_photos CASCADE;
|
||||||
|
|
||||||
|
ALTER FUNCTION movies_scenes_photos(movie movies) RENAME TO movies_photos;
|
||||||
|
ALTER FUNCTION series_scenes_photos(serie series) RENAME TO series_photos;
|
||||||
|
`);
|
||||||
23
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.207.0",
|
"version": "1.212.9",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.207.0",
|
"version": "1.212.9",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@casl/ability": "^5.2.2",
|
"@casl/ability": "^5.2.2",
|
||||||
@@ -11650,6 +11650,25 @@
|
|||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-gyp": {
|
"node_modules/node-gyp": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.207.0",
|
"version": "1.212.9",
|
||||||
"description": "All the latest porn releases in one place",
|
"description": "All the latest porn releases in one place",
|
||||||
"main": "src/app.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
BIN
public/img/logos/analvids/analvids.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
public/img/logos/analvids/lazy/analvids.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
public/img/logos/analvids/lazy/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
public/img/logos/analvids/lazy/favicon_light.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
public/img/logos/analvids/lazy/network.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
public/img/logos/analvids/network.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/logos/analvids/thumbs/analvids.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
public/img/logos/analvids/thumbs/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
public/img/logos/analvids/thumbs/favicon_light.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
public/img/logos/analvids/thumbs/network.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/logos/bang/bangpodcast.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
public/img/logos/bang/lazy/bangpodcast.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/logos/bang/lazy/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
public/img/logos/bang/lazy/favicon_light.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
public/img/logos/bang/thumbs/bangpodcast.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/logos/bang/thumbs/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
public/img/logos/bang/thumbs/favicon_light.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
public/img/logos/bjraw/bjraw.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
public/img/logos/bjraw/favicon.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/img/logos/bjraw/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/img/logos/bjraw/favicon_light.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/img/logos/bjraw/lazy/bjraw.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/img/logos/bjraw/lazy/favicon.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/img/logos/bjraw/lazy/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/img/logos/bjraw/lazy/favicon_light.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/img/logos/bjraw/lazy/network.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/img/logos/bjraw/misc/bj-raw_dark.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
public/img/logos/bjraw/network.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
public/img/logos/bjraw/thumbs/bjraw.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
public/img/logos/bjraw/thumbs/favicon.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
public/img/logos/bjraw/thumbs/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
public/img/logos/bjraw/thumbs/favicon_light.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
public/img/logos/bjraw/thumbs/network.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
public/img/logos/gotfilled/favicon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/img/logos/gotfilled/favicon_dark.png
Normal file
|
After Width: | Height: | Size: 16 KiB |