forked from DebaucheryLibrarian/traxxx
Renamed chapters to clips. Fixed Vixen trailers.
This commit is contained in:
parent
2835c66694
commit
501e764c21
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<ul class="clips nolist">
|
||||||
|
<li
|
||||||
|
v-for="clip in clips"
|
||||||
|
:key="`clip-${clip.id}`"
|
||||||
|
class="clip"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
v-if="clip.poster"
|
||||||
|
:href="`/media/${clip.poster.path}`"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="clip-poster-link"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="`/media/${clip.poster.thumbnail}`"
|
||||||
|
class="clip-poster"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="clip-info">
|
||||||
|
<div class="clip-header">
|
||||||
|
<h3 class="clip-title">{{ clip.title }}</h3>
|
||||||
|
<span
|
||||||
|
v-if="clip.duration"
|
||||||
|
class="clip-duration"
|
||||||
|
>{{ formatDuration(clip.duration) }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p
|
||||||
|
v-if="clip.description"
|
||||||
|
class="clip-description"
|
||||||
|
>{{ clip.description }}</p>
|
||||||
|
|
||||||
|
<Tags :tags="clip.tags" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Tags from './tags.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Tags,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
clips: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.clip {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: .25fr .75fr;
|
||||||
|
background: var(--background);
|
||||||
|
box-shadow: 0 0 3px var(--shadow-weak);
|
||||||
|
margin: 0 0 .5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clip-poster {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clip-info {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 1rem 1rem .5rem 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clip-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clip-title {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -105,20 +105,20 @@ function sfw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function photos() {
|
function photos() {
|
||||||
const photosWithChapterPosters = (this.release.photos || []).concat(this.release.chapters ? this.release.chapters.map(chapter => chapter.poster) : []);
|
const photosWithClipPosters = (this.release.photos || []).concat(this.release.clips ? this.release.clips.map(clip => clip.poster) : []);
|
||||||
|
|
||||||
if (this.release.trailer || this.release.teaser) {
|
if (this.release.trailer || this.release.teaser) {
|
||||||
// poster will be on trailer video
|
// poster will be on trailer video
|
||||||
return photosWithChapterPosters;
|
return photosWithClipPosters;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.release.poster) {
|
if (this.release.poster) {
|
||||||
// no trailer, add poster to photos
|
// no trailer, add poster to photos
|
||||||
return [this.release.poster].concat(this.release.photos).concat(photosWithChapterPosters);
|
return [this.release.poster].concat(this.release.photos).concat(photosWithClipPosters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no poster available
|
// no poster available
|
||||||
return photosWithChapterPosters;
|
return photosWithClipPosters;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -87,10 +87,17 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="labels">
|
<div class="labels">
|
||||||
<span
|
<router-link
|
||||||
v-if="release.shootId"
|
v-if="release.shootId && release.studio"
|
||||||
|
:to="{ name: 'studio', params: { entitySlug: release.studio.slug } }"
|
||||||
:title="release.studio && release.studio.name"
|
:title="release.studio && release.studio.name"
|
||||||
class="shoot"
|
class="shoot nolink"
|
||||||
|
>{{ release.shootId }}</router-link>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else-if="release.shootId"
|
||||||
|
:title="release.studio && release.studio.name"
|
||||||
|
class="shoot nolink"
|
||||||
>{{ release.shootId }}</span>
|
>{{ release.shootId }}</span>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
|
|
|
@ -99,51 +99,6 @@
|
||||||
<p class="description">{{ release.description }}</p>
|
<p class="description">{{ release.description }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul
|
|
||||||
v-if="release.chapters && release.chapters.length > 0"
|
|
||||||
class="chapters row nolist"
|
|
||||||
>
|
|
||||||
<span class="row-label">Chapters</span>
|
|
||||||
<li
|
|
||||||
v-for="chapter in release.chapters"
|
|
||||||
:key="`chapter-${chapter.id}`"
|
|
||||||
class="chapter"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
v-if="chapter.poster"
|
|
||||||
:href="`/media/${chapter.poster.path}`"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="chapter-poster-link"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="`/media/${chapter.poster.thumbnail}`"
|
|
||||||
class="chapter-poster"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="chapter-info">
|
|
||||||
<div class="chapter-header">
|
|
||||||
<h3 class="chapter-title">{{ chapter.title }}</h3>
|
|
||||||
<span
|
|
||||||
v-if="chapter.duration"
|
|
||||||
class="chapter-duration"
|
|
||||||
>{{ chapter.duration }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p
|
|
||||||
v-if="chapter.description"
|
|
||||||
class="chapter-description"
|
|
||||||
>{{ chapter.description }}</p>
|
|
||||||
|
|
||||||
<ul class="nolist"><li
|
|
||||||
v-for="tag in chapter.tags"
|
|
||||||
:key="`chapter-tag-${tag.id}`"
|
|
||||||
>{{ tag.name }}</li></ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="row row-tidbits">
|
<div class="row row-tidbits">
|
||||||
<div
|
<div
|
||||||
v-if="release.duration"
|
v-if="release.duration"
|
||||||
|
@ -151,14 +106,7 @@
|
||||||
>
|
>
|
||||||
<span class="row-label">Duration</span>
|
<span class="row-label">Duration</span>
|
||||||
|
|
||||||
<div class="duration">
|
<div class="duration">{{ formatDuration(release.duration) }}</div>
|
||||||
<span
|
|
||||||
v-if="release.duration >= 3600"
|
|
||||||
class="duration-segment"
|
|
||||||
>{{ Math.floor(release.duration / 3600).toString().padStart(2, '0') }}:</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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -216,6 +164,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="release.clips && release.clips.length > 0"
|
||||||
|
class="row nolist"
|
||||||
|
>
|
||||||
|
<span class="row-label">Clips</span>
|
||||||
|
|
||||||
|
<Clips :clips="release.clips" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="release.comment"
|
v-if="release.comment"
|
||||||
class="row"
|
class="row"
|
||||||
|
@ -241,6 +198,7 @@
|
||||||
import Media from './media.vue';
|
import Media from './media.vue';
|
||||||
import Details from './details.vue';
|
import Details from './details.vue';
|
||||||
import Tags from './tags.vue';
|
import Tags from './tags.vue';
|
||||||
|
import Clips from './clips.vue';
|
||||||
import Actor from '../actors/tile.vue';
|
import Actor from '../actors/tile.vue';
|
||||||
import Scroll from '../scroll/scroll.vue';
|
import Scroll from '../scroll/scroll.vue';
|
||||||
import Expand from '../expand/expand.vue';
|
import Expand from '../expand/expand.vue';
|
||||||
|
@ -262,6 +220,7 @@ export default {
|
||||||
Media,
|
Media,
|
||||||
Scroll,
|
Scroll,
|
||||||
Expand,
|
Expand,
|
||||||
|
Clips,
|
||||||
Tags,
|
Tags,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -346,14 +305,6 @@ export default {
|
||||||
margin: -.25rem 0 0 0;
|
margin: -.25rem 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.duration {
|
|
||||||
font-size: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.duration-segment {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actors {
|
.actors {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||||
|
@ -395,36 +346,6 @@ export default {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter {
|
|
||||||
display: flex;
|
|
||||||
background: var(--background);
|
|
||||||
box-shadow: 0 0 3px var(--shadow-weak);
|
|
||||||
margin: 0 0 .5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-poster {
|
|
||||||
width: 12rem;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
object-position: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-info {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: 1rem 1rem .5rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-title {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
.flag {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
margin: 0 0 -.15rem .1rem;
|
margin: 0 0 -.15rem .1rem;
|
||||||
|
|
|
@ -69,7 +69,7 @@ function curateRelease(release) {
|
||||||
|
|
||||||
if (release.scenes) curatedRelease.scenes = release.scenes.map(({ scene }) => curateRelease(scene));
|
if (release.scenes) curatedRelease.scenes = release.scenes.map(({ scene }) => curateRelease(scene));
|
||||||
if (release.movies) curatedRelease.movies = release.movies.map(({ movie }) => curateRelease(movie));
|
if (release.movies) curatedRelease.movies = release.movies.map(({ movie }) => curateRelease(movie));
|
||||||
if (release.chapters) curatedRelease.chapters = release.chapters.map(chapter => curateRelease(chapter));
|
if (release.clips) curatedRelease.clips = release.clips.map(clip => curateRelease(clip));
|
||||||
if (release.photos) curatedRelease.photos = release.photos.map(({ media }) => media);
|
if (release.photos) curatedRelease.photos = release.photos.map(({ media }) => media);
|
||||||
if (release.covers) curatedRelease.covers = release.covers.map(({ media }) => media);
|
if (release.covers) curatedRelease.covers = release.covers.map(({ media }) => media);
|
||||||
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
||||||
|
|
|
@ -255,19 +255,19 @@ const releaseFragment = `
|
||||||
${releaseTrailerFragment}
|
${releaseTrailerFragment}
|
||||||
${releaseTeaserFragment}
|
${releaseTeaserFragment}
|
||||||
${siteFragment}
|
${siteFragment}
|
||||||
chapters {
|
clips {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
duration
|
duration
|
||||||
tags: chaptersTags {
|
tags: clipsTags {
|
||||||
tag {
|
tag {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poster: chaptersPosterByChapterId {
|
poster: clipsPosterByClipId {
|
||||||
media {
|
media {
|
||||||
index
|
index
|
||||||
path
|
path
|
||||||
|
|
|
@ -14,6 +14,20 @@ import Container from '../components/container/container.vue';
|
||||||
import Icon from '../components/icon/icon.vue';
|
import Icon from '../components/icon/icon.vue';
|
||||||
import Footer from '../components/footer/footer.vue';
|
import Footer from '../components/footer/footer.vue';
|
||||||
|
|
||||||
|
function formatDuration(duration, forceHours) {
|
||||||
|
const hours = Math.floor(duration / 3600);
|
||||||
|
const minutes = Math.floor((duration % 3600) / 60);
|
||||||
|
const seconds = Math.floor(duration % 60);
|
||||||
|
|
||||||
|
const [formattedHours, formattedMinutes, formattedSeconds] = [hours, minutes, seconds].map(segment => segment.toString().padStart(2, '0'));
|
||||||
|
|
||||||
|
if (duration >= 3600 || forceHours) {
|
||||||
|
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${formattedMinutes}:${formattedSeconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
function formatDate(date, format = 'MMMM D, YYYY', precision = 'day') {
|
function formatDate(date, format = 'MMMM D, YYYY', precision = 'day') {
|
||||||
if (precision === 'year') {
|
if (precision === 'year') {
|
||||||
const newFormat = format.match(/Y+/);
|
const newFormat = format.match(/Y+/);
|
||||||
|
@ -54,6 +68,7 @@ function init() {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatDate,
|
formatDate,
|
||||||
|
formatDuration,
|
||||||
isAfter: (dateA, dateB) => dayjs(dateA).isAfter(dateB),
|
isAfter: (dateA, dateB) => dayjs(dateA).isAfter(dateB),
|
||||||
isBefore: (dateA, dateB) => dayjs(dateA).isBefore(dateB),
|
isBefore: (dateA, dateB) => dayjs(dateA).isBefore(dateB),
|
||||||
},
|
},
|
||||||
|
|
|
@ -853,7 +853,7 @@ exports.up = knex => Promise.resolve()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('media');
|
.inTable('media');
|
||||||
}))
|
}))
|
||||||
.then(() => knex.schema.createTable('chapters', (table) => {
|
.then(() => knex.schema.createTable('clips', (table) => {
|
||||||
table.increments('id', 16);
|
table.increments('id', 16);
|
||||||
|
|
||||||
table.integer('release_id', 12)
|
table.integer('release_id', 12)
|
||||||
|
@ -861,9 +861,9 @@ exports.up = knex => Promise.resolve()
|
||||||
.inTable('releases')
|
.inTable('releases')
|
||||||
.notNullable();
|
.notNullable();
|
||||||
|
|
||||||
table.integer('chapter', 6);
|
table.integer('clip', 6);
|
||||||
|
|
||||||
table.unique(['release_id', 'chapter']);
|
table.unique(['release_id', 'clip']);
|
||||||
|
|
||||||
table.text('title');
|
table.text('title');
|
||||||
table.text('description');
|
table.text('description');
|
||||||
|
@ -882,44 +882,44 @@ exports.up = knex => Promise.resolve()
|
||||||
table.datetime('created_at')
|
table.datetime('created_at')
|
||||||
.defaultTo(knex.fn.now());
|
.defaultTo(knex.fn.now());
|
||||||
}))
|
}))
|
||||||
.then(() => knex.schema.createTable('chapters_posters', (table) => {
|
.then(() => knex.schema.createTable('clips_posters', (table) => {
|
||||||
table.integer('chapter_id', 16)
|
table.integer('clip_id', 16)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('chapters');
|
.inTable('clips');
|
||||||
|
|
||||||
table.text('media_id', 21)
|
table.text('media_id', 21)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('media');
|
.inTable('media');
|
||||||
|
|
||||||
table.unique('chapter_id');
|
table.unique('clip_id');
|
||||||
}))
|
}))
|
||||||
.then(() => knex.schema.createTable('chapters_photos', (table) => {
|
.then(() => knex.schema.createTable('clips_photos', (table) => {
|
||||||
table.integer('chapter_id', 16)
|
table.integer('clip_id', 16)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('chapters');
|
.inTable('clips');
|
||||||
|
|
||||||
table.text('media_id', 21)
|
table.text('media_id', 21)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('media');
|
.inTable('media');
|
||||||
|
|
||||||
table.unique(['chapter_id', 'media_id']);
|
table.unique(['clip_id', 'media_id']);
|
||||||
}))
|
}))
|
||||||
.then(() => knex.schema.createTable('chapters_tags', (table) => {
|
.then(() => knex.schema.createTable('clips_tags', (table) => {
|
||||||
table.integer('tag_id', 12)
|
table.integer('tag_id', 12)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('tags');
|
.inTable('tags');
|
||||||
|
|
||||||
table.integer('chapter_id', 16)
|
table.integer('clip_id', 16)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('chapters');
|
.inTable('clips');
|
||||||
|
|
||||||
table.unique(['tag_id', 'chapter_id']);
|
table.unique(['tag_id', 'clip_id']);
|
||||||
}))
|
}))
|
||||||
// SEARCH
|
// SEARCH
|
||||||
.then(() => { // eslint-disable-line arrow-body-style
|
.then(() => { // eslint-disable-line arrow-body-style
|
||||||
|
@ -1100,9 +1100,9 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
|
||||||
DROP TABLE IF EXISTS movies_scenes CASCADE;
|
DROP TABLE IF EXISTS movies_scenes CASCADE;
|
||||||
DROP TABLE IF EXISTS movies_trailers CASCADE;
|
DROP TABLE IF EXISTS movies_trailers CASCADE;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS chapters_tags CASCADE;
|
DROP TABLE IF EXISTS clips_tags CASCADE;
|
||||||
DROP TABLE IF EXISTS chapters_posters CASCADE;
|
DROP TABLE IF EXISTS clips_posters CASCADE;
|
||||||
DROP TABLE IF EXISTS chapters_photos CASCADE;
|
DROP TABLE IF EXISTS clips_photos CASCADE;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS batches CASCADE;
|
DROP TABLE IF EXISTS batches CASCADE;
|
||||||
|
|
||||||
|
@ -1122,7 +1122,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
|
||||||
DROP TABLE IF EXISTS tags_posters CASCADE;
|
DROP TABLE IF EXISTS tags_posters CASCADE;
|
||||||
DROP TABLE IF EXISTS tags_photos CASCADE;
|
DROP TABLE IF EXISTS tags_photos CASCADE;
|
||||||
DROP TABLE IF EXISTS movies CASCADE;
|
DROP TABLE IF EXISTS movies CASCADE;
|
||||||
DROP TABLE IF EXISTS chapters CASCADE;
|
DROP TABLE IF EXISTS clips CASCADE;
|
||||||
DROP TABLE IF EXISTS releases CASCADE;
|
DROP TABLE IF EXISTS releases CASCADE;
|
||||||
DROP TABLE IF EXISTS actors CASCADE;
|
DROP TABLE IF EXISTS actors CASCADE;
|
||||||
DROP TABLE IF EXISTS directors CASCADE;
|
DROP TABLE IF EXISTS directors CASCADE;
|
||||||
|
|
|
@ -58,7 +58,7 @@ const groups = [
|
||||||
|
|
||||||
const tags = [
|
const tags = [
|
||||||
{
|
{
|
||||||
name: '3d',
|
name: '3D',
|
||||||
slug: '3d',
|
slug: '3d',
|
||||||
description: 'Available in 3D.',
|
description: 'Available in 3D.',
|
||||||
},
|
},
|
||||||
|
|
|
@ -146,6 +146,12 @@ const studios = [
|
||||||
url: 'https://www.legalporno.com/studios/kinky-sex',
|
url: 'https://www.legalporno.com/studios/kinky-sex',
|
||||||
parent: 'legalporno',
|
parent: 'legalporno',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slug: 'sexyangelproductions',
|
||||||
|
name: 'Sexy Angel Productions',
|
||||||
|
url: 'https://www.legalporno.com/studios/sexy-angel-productions',
|
||||||
|
parent: 'legalporno',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slug: 'nfstudio',
|
slug: 'nfstudio',
|
||||||
name: 'N&F Studio',
|
name: 'N&F Studio',
|
||||||
|
|
|
@ -38,7 +38,7 @@ function scrapeScene({ query, html }, url, channel) {
|
||||||
|
|
||||||
release.poster = qu.prefixUrl(html.match(/background-image: url\('(.*)'\)/)?.[1], channel.url);
|
release.poster = qu.prefixUrl(html.match(/background-image: url\('(.*)'\)/)?.[1], channel.url);
|
||||||
|
|
||||||
release.chapters = query.all('.ClipOuter').map((el) => {
|
release.clips = query.all('.ClipOuter').map((el) => {
|
||||||
const chapter = {};
|
const chapter = {};
|
||||||
|
|
||||||
chapter.title = query.text(el, 'h4');
|
chapter.title = query.text(el, 'h4');
|
||||||
|
|
|
@ -49,7 +49,10 @@ async function getTrailer(scene, site, url) {
|
||||||
file: scene.previewVideoUrl1080P,
|
file: scene.previewVideoUrl1080P,
|
||||||
sizes: qualities.join('+'),
|
sizes: qualities.join('+'),
|
||||||
type: 'trailer',
|
type: 'trailer',
|
||||||
}, { referer: url });
|
}, {
|
||||||
|
referer: url,
|
||||||
|
origin: site.url,
|
||||||
|
});
|
||||||
|
|
||||||
if (!tokenRes.ok) {
|
if (!tokenRes.ok) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -243,44 +243,44 @@ async function updateReleasesSearch(releaseIds) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function storeChapters(releases) {
|
async function storeClips(releases) {
|
||||||
const chapters = releases.map(release => release.chapters?.map((chapter, index) => ({
|
const clips = releases.map(release => release.clips?.map((clip, index) => ({
|
||||||
title: chapter.title,
|
title: clip.title,
|
||||||
description: chapter.description,
|
description: clip.description,
|
||||||
releaseId: release.id,
|
releaseId: release.id,
|
||||||
chapter: index + 1,
|
clip: index + 1,
|
||||||
duration: chapter.duration,
|
duration: clip.duration,
|
||||||
poster: chapter.poster,
|
poster: clip.poster,
|
||||||
photos: chapter.photos,
|
photos: clip.photos,
|
||||||
tags: chapter.tags,
|
tags: clip.tags,
|
||||||
}))).flat().filter(Boolean);
|
}))).flat().filter(Boolean);
|
||||||
|
|
||||||
const curatedChapterEntries = chapters.map(chapter => ({
|
const curatedClipEntries = clips.map(clip => ({
|
||||||
title: chapter.title,
|
title: clip.title,
|
||||||
description: chapter.description,
|
description: clip.description,
|
||||||
duration: chapter.duration,
|
duration: clip.duration,
|
||||||
release_id: chapter.releaseId,
|
release_id: clip.releaseId,
|
||||||
chapter: chapter.chapter,
|
clip: clip.clip,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const storedChapters = await bulkInsert('chapters', curatedChapterEntries);
|
const storedClips = await bulkInsert('clips', curatedClipEntries);
|
||||||
const chapterIdsByReleaseIdAndChapter = storedChapters.reduce((acc, chapter) => ({
|
const clipIdsByReleaseIdAndClip = storedClips.reduce((acc, clip) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[chapter.release_id]: {
|
[clip.release_id]: {
|
||||||
...acc[chapter.release_id],
|
...acc[clip.release_id],
|
||||||
[chapter.chapter]: chapter.id,
|
[clip.clip]: clip.id,
|
||||||
},
|
},
|
||||||
}), {});
|
}), {});
|
||||||
|
|
||||||
const chaptersWithId = chapters.map(chapter => ({
|
const clipsWithId = clips.map(clip => ({
|
||||||
...chapter,
|
...clip,
|
||||||
id: chapterIdsByReleaseIdAndChapter[chapter.releaseId][chapter.chapter],
|
id: clipIdsByReleaseIdAndClip[clip.releaseId][clip.clip],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await associateReleaseTags(chaptersWithId, 'chapter');
|
await associateReleaseTags(clipsWithId, 'clip');
|
||||||
|
|
||||||
// media is more error-prone, associate separately
|
// media is more error-prone, associate separately
|
||||||
await associateReleaseMedia(chaptersWithId, 'chapter');
|
await associateReleaseMedia(clipsWithId, 'clip');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function storeScenes(releases) {
|
async function storeScenes(releases) {
|
||||||
|
@ -318,7 +318,7 @@ async function storeScenes(releases) {
|
||||||
await scrapeActors(actors.map(actor => actor.name));
|
await scrapeActors(actors.map(actor => actor.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
await storeChapters(releasesWithId);
|
await storeClips(releasesWithId);
|
||||||
|
|
||||||
logger.info(`Stored ${storedReleaseEntries.length} releases`);
|
logger.info(`Stored ${storedReleaseEntries.length} releases`);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue