Enabled pagination on network page.
|
@ -100,6 +100,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
flex-grow: 1;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
v-if="network"
|
v-if="network"
|
||||||
class="content"
|
class="content"
|
||||||
>
|
>
|
||||||
<FilterBar :fetch-releases="fetchNetwork" />
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="network"
|
class="network"
|
||||||
:class="{ nosites: sites.length === 0 && networks.length === 0 }"
|
:class="{ nosites: sites.length === 0 && networks.length === 0 }"
|
||||||
|
@ -89,6 +87,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
|
<FilterBar
|
||||||
|
:fetch-releases="fetchNetwork"
|
||||||
|
:items-total="totalCount"
|
||||||
|
:items-per-page="10"
|
||||||
|
/>
|
||||||
|
|
||||||
<template v-if="sites.length > 0 || networks.length > 0">
|
<template v-if="sites.length > 0 || networks.length > 0">
|
||||||
<span
|
<span
|
||||||
v-show="expanded"
|
v-show="expanded"
|
||||||
|
@ -128,11 +132,16 @@ import Sites from '../sites/sites.vue';
|
||||||
import Network from '../tile/network.vue';
|
import Network from '../tile/network.vue';
|
||||||
|
|
||||||
async function fetchNetwork() {
|
async function fetchNetwork() {
|
||||||
this.network = await this.$store.dispatch('fetchNetworkBySlug', {
|
const { network, totalCount } = await this.$store.dispatch('fetchNetworkBySlug', {
|
||||||
networkSlug: this.$route.params.networkSlug,
|
networkSlug: this.$route.params.networkSlug,
|
||||||
|
limit: this.limit,
|
||||||
range: this.$route.params.range,
|
range: this.$route.params.range,
|
||||||
|
pageNumber: Number(this.$route.params.pageNumber),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.network = network;
|
||||||
|
this.totalCount = totalCount;
|
||||||
|
|
||||||
if (this.network.studios) {
|
if (this.network.studios) {
|
||||||
this.studios = this.network.studios.map(studio => ({
|
this.studios = this.network.studios.map(studio => ({
|
||||||
...studio,
|
...studio,
|
||||||
|
@ -170,6 +179,8 @@ export default {
|
||||||
networks: [],
|
networks: [],
|
||||||
studios: [],
|
studios: [],
|
||||||
releases: [],
|
releases: [],
|
||||||
|
totalCount: null,
|
||||||
|
limit: 10,
|
||||||
pageTitle: null,
|
pageTitle: null,
|
||||||
expanded: false,
|
expanded: false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!loading && actors.length > 0"
|
v-if="!loading && actors.length > 0"
|
||||||
|
v-lazy-container="{ selector: '.lazy' }"
|
||||||
class="tiles"
|
class="tiles"
|
||||||
>
|
>
|
||||||
<Actor
|
<Actor
|
||||||
|
@ -95,7 +96,7 @@ export default {
|
||||||
.summary {
|
.summary {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 0 1rem 0;
|
margin: 0 0 1rem 0;
|
||||||
color: $shadow;
|
color: var(--shadow);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ async function mounted() {
|
||||||
'blowbang',
|
'blowbang',
|
||||||
'pussy-eating',
|
'pussy-eating',
|
||||||
'ass-eating',
|
'ass-eating',
|
||||||
'ass-to-mouth',
|
'atm',
|
||||||
],
|
],
|
||||||
extreme: [
|
extreme: [
|
||||||
'airtight',
|
'airtight',
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
v-if="alias"
|
v-if="alias"
|
||||||
v-tooltip="`Alias for ${alias.name}`"
|
v-tooltip="`Alias of ${alias.name}`"
|
||||||
icon="users3"
|
icon="users3"
|
||||||
class="favicon alias"
|
class="favicon alias"
|
||||||
/>
|
/>
|
||||||
|
@ -179,7 +179,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.alias {
|
.alias {
|
||||||
fill: var(--highlight);
|
fill: var(--shadow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.died {
|
&.died {
|
||||||
fill: var(--lighten);
|
fill: var(--shadow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +271,11 @@ export default {
|
||||||
margin: 0 0 0 .5rem;
|
margin: 0 0 0 .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.age-now,
|
||||||
|
.age-death {
|
||||||
|
margin: 0 .25rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
.age-then {
|
.age-then {
|
||||||
color: var(--lighten);
|
color: var(--lighten);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,10 @@ function curateActor(actor, release, curateActorRelease) {
|
||||||
curatedActor.releases = actor.releases.map(actorRelease => curateActorRelease(actorRelease.release));
|
curatedActor.releases = actor.releases.map(actorRelease => curateActorRelease(actorRelease.release));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actor.aliasFor) {
|
||||||
|
curatedActor.aliasFor = curateActor(curatedActor.aliasFor);
|
||||||
|
}
|
||||||
|
|
||||||
return curatedActor;
|
return curatedActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ function initNetworksActions(store, _router) {
|
||||||
}) {
|
}) {
|
||||||
const { before, after, orderBy } = getDateRange(range);
|
const { before, after, orderBy } = getDateRange(range);
|
||||||
|
|
||||||
const { network, releases } = await graphql(`
|
const { network, connection: { releases, totalCount } } = await graphql(`
|
||||||
query Network(
|
query Network(
|
||||||
$networkSlug: String!
|
$networkSlug: String!
|
||||||
$limit:Int = 10,
|
$limit:Int = 10,
|
||||||
|
@ -71,7 +71,7 @@ function initNetworksActions(store, _router) {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
releases(
|
connection: releasesConnection(
|
||||||
first: $limit
|
first: $limit
|
||||||
offset: $offset
|
offset: $offset
|
||||||
orderBy: $orderBy
|
orderBy: $orderBy
|
||||||
|
@ -110,8 +110,11 @@ function initNetworksActions(store, _router) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
releases: nodes {
|
||||||
${releaseFields}
|
${releaseFields}
|
||||||
}
|
}
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`, {
|
`, {
|
||||||
networkSlug,
|
networkSlug,
|
||||||
|
@ -125,7 +128,10 @@ function initNetworksActions(store, _router) {
|
||||||
exclude: store.state.ui.filter,
|
exclude: store.state.ui.filter,
|
||||||
});
|
});
|
||||||
|
|
||||||
return curateNetwork(network, releases);
|
return {
|
||||||
|
network: curateNetwork(network, releases),
|
||||||
|
totalCount,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchNetworks({ _commit }) {
|
async function fetchNetworks({ _commit }) {
|
||||||
|
|
|
@ -101,11 +101,12 @@ const routes = [
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
range: 'latest',
|
range: 'latest',
|
||||||
|
pageNumber: 1,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/network/:networkSlug/:range',
|
path: '/network/:networkSlug/:range/:pageNumber?',
|
||||||
component: Network,
|
component: Network,
|
||||||
name: 'networkRange',
|
name: 'networkRange',
|
||||||
},
|
},
|
||||||
|
|
|
@ -92,14 +92,18 @@ function initUiActions(_store, _router) {
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
age
|
age
|
||||||
|
ageAtDeath
|
||||||
dateOfBirth
|
dateOfBirth
|
||||||
|
dateOfDeath
|
||||||
gender
|
gender
|
||||||
aliasFor: actorByAliasFor {
|
aliasFor: actorByAliasFor {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
age
|
age
|
||||||
|
ageAtDeath
|
||||||
dateOfBirth
|
dateOfBirth
|
||||||
|
dateOfDeath
|
||||||
gender
|
gender
|
||||||
network {
|
network {
|
||||||
id
|
id
|
||||||
|
|
Before Width: | Height: | Size: 873 KiB |
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 298 KiB |
Before Width: | Height: | Size: 600 KiB After Width: | Height: | Size: 600 KiB |
After Width: | Height: | Size: 942 KiB |
After Width: | Height: | Size: 481 KiB |
After Width: | Height: | Size: 852 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 4.1 MiB |
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 33 KiB |
|
@ -128,7 +128,7 @@ const tags = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ass to mouth',
|
name: 'ass to mouth',
|
||||||
slug: 'ass-to-mouth',
|
slug: 'atm',
|
||||||
priority: 6,
|
priority: 6,
|
||||||
description: 'Sucking off a cock right after it fucked your ass. If it has been in someone else\'s ass, it may be called [ATOGM](/tag/atogm).',
|
description: 'Sucking off a cock right after it fucked your ass. If it has been in someone else\'s ass, it may be called [ATOGM](/tag/atogm).',
|
||||||
group: 'oral',
|
group: 'oral',
|
||||||
|
@ -137,7 +137,7 @@ const tags = [
|
||||||
name: 'ass to other girl\'s mouth',
|
name: 'ass to other girl\'s mouth',
|
||||||
slug: 'atogm',
|
slug: 'atogm',
|
||||||
priority: 6,
|
priority: 6,
|
||||||
description: '[Ass to mouth](/tag/ass-to-mouth) with a cock that has been in someone else\'s ass. ATOGM may also be the gay variation "ass to other guy\'s mouth".',
|
description: '[Ass to mouth](/tag/atm) with a cock that has been in someone else\'s ass. ATOGM may also be the gay variation "ass to other guy\'s mouth".',
|
||||||
group: 'oral',
|
group: 'oral',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -795,6 +795,7 @@ const tags = [
|
||||||
{
|
{
|
||||||
name: 'threesome',
|
name: 'threesome',
|
||||||
slug: 'threesome',
|
slug: 'threesome',
|
||||||
|
priority: 8,
|
||||||
group: 'group',
|
group: 'group',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -961,13 +962,13 @@ const aliases = [
|
||||||
for: 'atom',
|
for: 'atom',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'atm',
|
name: 'ass to mouth',
|
||||||
for: 'ass-to-mouth',
|
for: 'atm',
|
||||||
secondary: true,
|
secondary: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'a2m',
|
name: 'a2m',
|
||||||
for: 'ass-to-mouth',
|
for: 'atm',
|
||||||
secondary: true,
|
secondary: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1446,6 +1447,10 @@ const aliases = [
|
||||||
name: 'mature & milf',
|
name: 'mature & milf',
|
||||||
for: 'milf',
|
for: 'milf',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'milfs',
|
||||||
|
for: 'milf',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'natural',
|
name: 'natural',
|
||||||
for: 'natural-boobs',
|
for: 'natural-boobs',
|
||||||
|
|
|
@ -591,7 +591,7 @@ const tagPosters = [
|
||||||
['anal-creampie', 1, 'Aleska Diamond in "Aleska Wants More" for Asshole Fever'],
|
['anal-creampie', 1, 'Aleska Diamond in "Aleska Wants More" for Asshole Fever'],
|
||||||
['ass-eating', 0, 'Angelica Heart and Leanna Sweet in "ATM Bitches" for Asshole Fever'],
|
['ass-eating', 0, 'Angelica Heart and Leanna Sweet in "ATM Bitches" for Asshole Fever'],
|
||||||
['asian', 0, 'Alina Li in "Slut Puppies 8" for Jules Jordan'],
|
['asian', 0, 'Alina Li in "Slut Puppies 8" for Jules Jordan'],
|
||||||
['ass-to-mouth', 0, 'Helena Sweet in "Teen Tryout" for Asshole Fever'],
|
['atm', 2, 'Jureka Del Mar in "Stretched Out" for Her Limit'],
|
||||||
['atogm', 0, 'Alysa Gap and Logan in "Anal Buffet 4" for Evil Angel'],
|
['atogm', 0, 'Alysa Gap and Logan in "Anal Buffet 4" for Evil Angel'],
|
||||||
['bdsm', 0, 'Dani Daniels in "The Traning of Dani Daniels, Day 2" for The Training of O at Kink'],
|
['bdsm', 0, 'Dani Daniels in "The Traning of Dani Daniels, Day 2" for The Training of O at Kink'],
|
||||||
['behind-the-scenes', 0, 'Janice Griffith in "Day With A Pornstar: Janice" for Brazzers'],
|
['behind-the-scenes', 0, 'Janice Griffith in "Day With A Pornstar: Janice" for Brazzers'],
|
||||||
|
@ -626,7 +626,7 @@ const tagPosters = [
|
||||||
['maid', 0, 'Whitney Wright in "Dredd Up Your Ass 2" for Jules Jordan'],
|
['maid', 0, 'Whitney Wright in "Dredd Up Your Ass 2" for Jules Jordan'],
|
||||||
['milf', 0, 'Olivia Austin in "Dredd 3" for Jules Jordan'],
|
['milf', 0, 'Olivia Austin in "Dredd 3" for Jules Jordan'],
|
||||||
['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'],
|
['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'],
|
||||||
['mfm', 5, 'Vina Sky in "Slut Puppies 15" for Jules Jordan'],
|
['mfm', 6, 'Honey Gold in "Slut Puppies 12" for Jules Jordan'],
|
||||||
['natural-boobs', 0, 'Autumn Falls in "Manuel Ferrara\'s Ripe 7" for Jules Jordan'],
|
['natural-boobs', 0, 'Autumn Falls in "Manuel Ferrara\'s Ripe 7" for Jules Jordan'],
|
||||||
['nurse', 0, 'Sarah Vandella in "Cum For Nurse Sarah" for Brazzers'],
|
['nurse', 0, 'Sarah Vandella in "Cum For Nurse Sarah" for Brazzers'],
|
||||||
['oil', 0, 'Jada Stevens in "Jada Stevens Anal Ass Oiled Up For James Deen\'s Cock" for Jules Jordan'],
|
['oil', 0, 'Jada Stevens in "Jada Stevens Anal Ass Oiled Up For James Deen\'s Cock" for Jules Jordan'],
|
||||||
|
@ -659,6 +659,8 @@ const tagPhotos = [
|
||||||
['airtight', 2, 'Dakota Skye in "Dakota Goes Nuts" for ArchAngel'],
|
['airtight', 2, 'Dakota Skye in "Dakota Goes Nuts" for ArchAngel'],
|
||||||
['airtight', 3, 'Anita Bellini in "Triple Dick Gangbang" for Hands On Hardcore (DDF Network)'],
|
['airtight', 3, 'Anita Bellini in "Triple Dick Gangbang" for Hands On Hardcore (DDF Network)'],
|
||||||
['anal-creampie', 0, 'Gina Valentina and Jane Wilde in "A Very Special Anniversary" for Tushy'],
|
['anal-creampie', 0, 'Gina Valentina and Jane Wilde in "A Very Special Anniversary" for Tushy'],
|
||||||
|
['atm', 0, 'Roxy Lips in "Under Her Coat" for 21 Naturals'],
|
||||||
|
['atm', 3, 'Natasha Teen in "Work That Ass!" for Her Limit'],
|
||||||
['asian', 'poster', 'Vina Sky in "Slut Puppies 15" for Jules Jordan'],
|
['asian', 'poster', 'Vina Sky in "Slut Puppies 15" for Jules Jordan'],
|
||||||
// ['asian', 1, 'Alina Li in "Oil Overload 11" for Jules Jordan'],
|
// ['asian', 1, 'Alina Li in "Oil Overload 11" for Jules Jordan'],
|
||||||
// ['anal', 'poster', 'Jynx Maze in "Anal Buffet 6" for Evil Angel'],
|
// ['anal', 'poster', 'Jynx Maze in "Anal Buffet 6" for Evil Angel'],
|
||||||
|
@ -700,7 +702,7 @@ const tagPhotos = [
|
||||||
['gaping', 'poster', 'Zoey Monroe in "Manuel DPs Them All 5" for Jules Jordan'],
|
['gaping', 'poster', 'Zoey Monroe in "Manuel DPs Them All 5" for Jules Jordan'],
|
||||||
['gaping', 2, 'Alex Grey in "DP Masters 5" for Jules Jordan'],
|
['gaping', 2, 'Alex Grey in "DP Masters 5" for Jules Jordan'],
|
||||||
['latina', 0, 'Abby Lee Brazil for Bang Bros'],
|
['latina', 0, 'Abby Lee Brazil for Bang Bros'],
|
||||||
// ['mfm', 0, 'Vina Sky in "Jules Jordan\'s Three Ways" for Jules Jordan'],
|
['mfm', 4, 'Vina Sky in "Jules Jordan\'s Three Ways" for Jules Jordan'],
|
||||||
['mfm', 1, 'Jynx Maze in "Don\'t Make Me Beg 4" for Evil Angel'],
|
['mfm', 1, 'Jynx Maze in "Don\'t Make Me Beg 4" for Evil Angel'],
|
||||||
['oil', 1, 'Emily Willis in "Emily Willis Has A Squirting Anal Orgasm" for Jules Jordan'],
|
['oil', 1, 'Emily Willis in "Emily Willis Has A Squirting Anal Orgasm" for Jules Jordan'],
|
||||||
['orgy', 'poster', 'Zoey Mornoe (DP), Jillian Janson (sex), Frida Sante, Katerina Kay and Natasha Starr in "Orgy Masters 6" for Jules Jordan'],
|
['orgy', 'poster', 'Zoey Mornoe (DP), Jillian Janson (sex), Frida Sante, Katerina Kay and Natasha Starr in "Orgy Masters 6" for Jules Jordan'],
|
||||||
|
|
|
@ -16,7 +16,7 @@ function scrape(html, site) {
|
||||||
return sceneElements.map((element) => {
|
return sceneElements.map((element) => {
|
||||||
const sceneLinkElement = $(element).find('.thmb_lnk');
|
const sceneLinkElement = $(element).find('.thmb_lnk');
|
||||||
const title = sceneLinkElement.attr('title');
|
const title = sceneLinkElement.attr('title');
|
||||||
const url = site.legacy
|
const url = site.parameters?.legacy
|
||||||
? `https://${site.url}{sceneLinkElement.attr('href')}`
|
? `https://${site.url}{sceneLinkElement.attr('href')}`
|
||||||
: `https://bangbros.com${sceneLinkElement.attr('href')}`;
|
: `https://bangbros.com${sceneLinkElement.attr('href')}`;
|
||||||
const shootId = sceneLinkElement.attr('id') && sceneLinkElement.attr('id').split('-')[1];
|
const shootId = sceneLinkElement.attr('id') && sceneLinkElement.attr('id').split('-')[1];
|
||||||
|
@ -150,14 +150,14 @@ function scrapeSceneLegacy({ qu }, url) {
|
||||||
return release;
|
return release;
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrapeProfile(html) {
|
function scrapeProfile(html, scope) {
|
||||||
const { q } = ex(html);
|
const { q } = ex(html);
|
||||||
const profile = {};
|
const profile = {};
|
||||||
|
|
||||||
const avatar = q('.profilePic img', 'src');
|
const avatar = q('.profilePic img', 'src');
|
||||||
if (avatar) profile.avatar = `https:${avatar}`;
|
if (avatar) profile.avatar = `https:${avatar}`;
|
||||||
|
|
||||||
profile.releases = scrape(html);
|
profile.releases = scrape(html, scope.network);
|
||||||
|
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ async function fetchScene(url, site, release) {
|
||||||
return scrapeScene(res.item.html, url, site);
|
return scrapeScene(res.item.html, url, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchProfile(actorName) {
|
async function fetchProfile(actorName, scope) {
|
||||||
const actorSlug = slugify(actorName);
|
const actorSlug = slugify(actorName);
|
||||||
const url = `https://bangbros.com/search/${actorSlug}`;
|
const url = `https://bangbros.com/search/${actorSlug}`;
|
||||||
const res = await bhttp.get(url);
|
const res = await bhttp.get(url);
|
||||||
|
@ -233,7 +233,7 @@ async function fetchProfile(actorName) {
|
||||||
const actorRes = await bhttp.get(actorUrl);
|
const actorRes = await bhttp.get(actorUrl);
|
||||||
|
|
||||||
if (actorRes.statusCode === 200) {
|
if (actorRes.statusCode === 200) {
|
||||||
return scrapeProfile(actorRes.body.toString());
|
return scrapeProfile(actorRes.body.toString(), scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ async function scrapeScene(html, url, _site) {
|
||||||
const siteElement = $('.niche-site-logo');
|
const siteElement = $('.niche-site-logo');
|
||||||
// const siteUrl = `https://www.brazzers.com${siteElement.attr('href').slice(0, -1)}`;
|
// const siteUrl = `https://www.brazzers.com${siteElement.attr('href').slice(0, -1)}`;
|
||||||
const siteName = siteElement.attr('title');
|
const siteName = siteElement.attr('title');
|
||||||
release.channel = siteName.replace(/\s+/g, '').toLowerCase();
|
release.channel = slugify(siteName, '');
|
||||||
|
|
||||||
release.tags = $('.tag-card-container a').map((tagIndex, tagElement) => $(tagElement).text()).toArray();
|
release.tags = $('.tag-card-container a').map((tagIndex, tagElement) => $(tagElement).text()).toArray();
|
||||||
release.photos = $('.carousel-thumb a').map((photoIndex, photoElement) => `https:${$(photoElement).attr('href')}`).toArray();
|
release.photos = $('.carousel-thumb a').map((photoIndex, photoElement) => `https:${$(photoElement).attr('href')}`).toArray();
|
||||||
|
|
|
@ -59,16 +59,17 @@ function scrapeScene(html, url, site) {
|
||||||
const originalUrl = `${protocol}//${hostname}${pathname}`;
|
const originalUrl = `${protocol}//${hostname}${pathname}`;
|
||||||
|
|
||||||
const entryId = originalUrl.split('-').slice(-1)[0];
|
const entryId = originalUrl.split('-').slice(-1)[0];
|
||||||
const title = sceneElement.find('h1.scene-title.grey-text').text();
|
const title = sceneElement.find('h1.scene-title').text();
|
||||||
const description = sceneElement.find('.synopsis').contents().slice(2).text().replace(/[\s\n]+/g, ' ').trim();
|
const description = sceneElement.find('.synopsis').contents().slice(2).text().replace(/[\s\n]+/g, ' ').trim();
|
||||||
|
|
||||||
const date = moment.utc(sceneElement.find('span.entry-date').text(), 'MMM D, YYYY').toDate();
|
const date = moment.utc(sceneElement.find('span.entry-date').text()?.match(/\w+ \d{1,2}, \d{4}/), 'MMM D, YYYY').toDate();
|
||||||
const actors = $('a.scene-title.grey-text.link').map((actorIndex, actorElement) => $(actorElement).text()).toArray();
|
const actors = $('.performer-list a, h1 a.scene-title').map((actorIndex, actorElement) => $(actorElement).text()).toArray();
|
||||||
|
|
||||||
const duration = Number(sceneElement.find('.duration-ratings .duration').text().slice(10, -4)) * 60;
|
const duration = Number(sceneElement.find('.duration-ratings .duration').text().slice(10, -4)) * 60;
|
||||||
|
|
||||||
const poster = `https:${$('video, dl8-video').attr('poster')}`;
|
const posterPath = $('video, dl8-video').attr('poster') || $('img.start-card').attr('src');
|
||||||
const photos = $('.contain-scene-images.desktop-only a').map((index, el) => `https:${$(el).attr('href')}`).toArray();
|
const poster = posterPath && `https:${posterPath}`;
|
||||||
|
const photos = $('.contain-scene-images.desktop-only a').map((index, el) => $(el).attr('href')).toArray().filter(Boolean).map(photo => `https:${photo}`);
|
||||||
|
|
||||||
const trailerEl = $('source');
|
const trailerEl = $('source');
|
||||||
const trailerSrc = trailerEl.attr('src');
|
const trailerSrc = trailerEl.attr('src');
|
||||||
|
@ -90,10 +91,10 @@ function scrapeScene(html, url, site) {
|
||||||
tags,
|
tags,
|
||||||
photos,
|
photos,
|
||||||
poster,
|
poster,
|
||||||
trailer: {
|
trailer: trailerSrc ? {
|
||||||
src: trailerSrc,
|
src: trailerSrc,
|
||||||
type: trailerType,
|
type: trailerType,
|
||||||
},
|
} : null,
|
||||||
rating: null,
|
rating: null,
|
||||||
site,
|
site,
|
||||||
channel,
|
channel,
|
||||||
|
|
|
@ -25,7 +25,7 @@ function curateReleaseEntry(release, batchId, existingRelease) {
|
||||||
shoot_id: release.shootId || null,
|
shoot_id: release.shootId || null,
|
||||||
studio_id: release.studio?.id || null,
|
studio_id: release.studio?.id || null,
|
||||||
url: release.url,
|
url: release.url,
|
||||||
date: release.date,
|
date: Number(release.date) ? release.date : null,
|
||||||
slug,
|
slug,
|
||||||
description: release.description,
|
description: release.description,
|
||||||
duration: release.duration,
|
duration: release.duration,
|
||||||
|
@ -47,7 +47,7 @@ function curateReleaseEntry(release, batchId, existingRelease) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function attachChannelSites(releases) {
|
async function attachChannelSites(releases) {
|
||||||
const releasesWithoutSite = releases.filter(release => release.channel && (!release.site || release.site.isNetwork));
|
const releasesWithoutSite = releases.filter(release => release.channel && (!release.site || release.site.isNetwork || release.site.slug !== release.channel));
|
||||||
|
|
||||||
const channelSites = await knex('sites')
|
const channelSites = await knex('sites')
|
||||||
.leftJoin('networks', 'networks.id', 'sites.network_id')
|
.leftJoin('networks', 'networks.id', 'sites.network_id')
|
||||||
|
@ -58,10 +58,6 @@ async function attachChannelSites(releases) {
|
||||||
|
|
||||||
const releasesWithChannelSite = await Promise.all(releases
|
const releasesWithChannelSite = await Promise.all(releases
|
||||||
.map(async (release) => {
|
.map(async (release) => {
|
||||||
if (release.site && !release.site.isNetwork) {
|
|
||||||
return release;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (release.channel && channelSitesBySlug[release.channel]) {
|
if (release.channel && channelSitesBySlug[release.channel]) {
|
||||||
const curatedSite = await curateSite(channelSitesBySlug[release.channel]);
|
const curatedSite = await curateSite(channelSitesBySlug[release.channel]);
|
||||||
|
|
||||||
|
@ -71,6 +67,11 @@ async function attachChannelSites(releases) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (release.site && !release.site.isNetwork) {
|
||||||
|
return release;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (release.site && release.site.isNetwork) {
|
if (release.site && release.site.isNetwork) {
|
||||||
return {
|
return {
|
||||||
...release,
|
...release,
|
||||||
|
@ -129,6 +130,10 @@ function attachReleaseIds(releases, storedReleases) {
|
||||||
|
|
||||||
function filterInternalDuplicateReleases(releases) {
|
function filterInternalDuplicateReleases(releases) {
|
||||||
const releasesBySiteIdAndEntryId = releases.reduce((acc, release) => {
|
const releasesBySiteIdAndEntryId = releases.reduce((acc, release) => {
|
||||||
|
if (!release.site) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
if (!acc[release.site.id]) {
|
if (!acc[release.site.id]) {
|
||||||
acc[release.site.id] = {};
|
acc[release.site.id] = {};
|
||||||
}
|
}
|
||||||
|
@ -221,7 +226,7 @@ async function storeReleases(releases) {
|
||||||
|
|
||||||
const curatedNewReleaseEntries = uniqueReleases.map(release => curateReleaseEntry(release, batchId));
|
const curatedNewReleaseEntries = uniqueReleases.map(release => curateReleaseEntry(release, batchId));
|
||||||
|
|
||||||
const storedReleases = await knex('releases').insert(curatedNewReleaseEntries).returning('*');
|
const storedReleases = await knex.batchInsert('releases', curatedNewReleaseEntries).returning('*');
|
||||||
// TODO: update duplicate releases
|
// TODO: update duplicate releases
|
||||||
|
|
||||||
const storedReleaseEntries = Array.isArray(storedReleases) ? storedReleases : [];
|
const storedReleaseEntries = Array.isArray(storedReleases) ? storedReleases : [];
|
||||||
|
|
|
@ -25,7 +25,7 @@ async function actorPosters(actorNames) {
|
||||||
const source = path.join(config.media.path, poster.path);
|
const source = path.join(config.media.path, poster.path);
|
||||||
|
|
||||||
const directory = path.join(config.media.path, 'extracted', poster.actor_name);
|
const directory = path.join(config.media.path, 'extracted', poster.actor_name);
|
||||||
const target = path.join(directory, `${poster.actor_name} - ${poster.network_name}: ${poster.site_name} - ${poster.title.replace(/[/.]/g, '_')} (${moment.utc(poster.date).format('YYYY-MM-DD')})-${poster.index}.jpeg`);
|
const target = path.join(directory, `${poster.actor_name} - ${poster.network_name}: ${poster.site_name} - ${poster.title.replace(/[/.]/g, '_') || poster.actor_name} (${moment.utc(poster.date).format('YYYY-MM-DD')})-${poster.index}.jpeg`);
|
||||||
await fs.mkdir(path.join(directory), { recursive: true });
|
await fs.mkdir(path.join(directory), { recursive: true });
|
||||||
|
|
||||||
const file = await fs.readFile(source);
|
const file = await fs.readFile(source);
|
||||||
|
|
|
@ -1,14 +1,45 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const substitutes = {
|
||||||
|
à: 'a',
|
||||||
|
á: 'a',
|
||||||
|
ä: 'a',
|
||||||
|
å: 'a',
|
||||||
|
æ: 'ae',
|
||||||
|
ç: 'c',
|
||||||
|
è: 'e',
|
||||||
|
é: 'e',
|
||||||
|
ë: 'e',
|
||||||
|
ì: 'i',
|
||||||
|
í: 'i',
|
||||||
|
ï: 'i',
|
||||||
|
ǹ: 'n',
|
||||||
|
ń: 'n',
|
||||||
|
ñ: 'n',
|
||||||
|
ò: 'o',
|
||||||
|
ó: 'o',
|
||||||
|
ö: 'o',
|
||||||
|
ø: 'o',
|
||||||
|
œ: 'oe',
|
||||||
|
ß: 'ss',
|
||||||
|
ù: 'u',
|
||||||
|
ú: 'u',
|
||||||
|
ü: 'u',
|
||||||
|
ỳ: 'y',
|
||||||
|
ý: 'y',
|
||||||
|
ÿ: 'y',
|
||||||
|
};
|
||||||
|
|
||||||
function slugify(string, delimiter = '-', {
|
function slugify(string, delimiter = '-', {
|
||||||
encode = false,
|
encode = false,
|
||||||
|
removeAccents = true,
|
||||||
limit = 1000,
|
limit = 1000,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (!string || typeof string !== 'string') {
|
if (!string || typeof string !== 'string') {
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const slugComponents = string.trim().toLowerCase().match(/\w+/g);
|
const slugComponents = string.trim().toLowerCase().match(/[A-Za-zÀ-ÖØ-öø-ÿ]+/g);
|
||||||
|
|
||||||
if (!slugComponents) {
|
if (!slugComponents) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -18,6 +49,12 @@ function slugify(string, delimiter = '-', {
|
||||||
const accSlug = `${acc}${index > 0 ? delimiter : ''}${component}`;
|
const accSlug = `${acc}${index > 0 ? delimiter : ''}${component}`;
|
||||||
|
|
||||||
if (accSlug.length < limit) {
|
if (accSlug.length < limit) {
|
||||||
|
if (removeAccents) {
|
||||||
|
return accSlug.replace(/[à-ÿ]/g, (match) => {
|
||||||
|
return substitutes[match] || '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return accSlug;
|
return accSlug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|