Merge branch 'experimental'
|
@ -43,7 +43,7 @@
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="date"
|
||||
>{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
|
||||
><Icon icon="share2" />{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
|
||||
|
||||
<a
|
||||
v-else
|
||||
|
@ -104,22 +104,16 @@ export default {
|
|||
padding: .5rem;
|
||||
color: var(--text-light);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*
|
||||
.date {
|
||||
&.new:before {
|
||||
content: '';
|
||||
background: var(--primary);
|
||||
width: .5rem;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -.5rem;
|
||||
}
|
||||
.icon {
|
||||
fill: var(--lighten-weak);
|
||||
margin: 0 .25rem 0 0;
|
||||
}
|
||||
|
||||
&:hover .icon {
|
||||
fill: var(--text-light);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
.site-link {
|
||||
display: flex;
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
>
|
||||
<h3
|
||||
v-if="release.title"
|
||||
v-tooltip.top="release.title"
|
||||
v-tooltip.bottom="release.title"
|
||||
:title="release.title"
|
||||
class="title"
|
||||
>{{ release.title }}</h3>
|
||||
|
|
|
@ -89,6 +89,7 @@ async function mounted() {
|
|||
],
|
||||
roleplay: [
|
||||
'family',
|
||||
'parody',
|
||||
'schoolgirl',
|
||||
'nurse',
|
||||
'maid',
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<router-link
|
||||
:to="{ name: 'tag', params: { tagSlug: tag.slug, range: 'latest' } }"
|
||||
:title="tag.name"
|
||||
<div
|
||||
v-if="tag.poster"
|
||||
class="tile"
|
||||
>
|
||||
<template v-if="tag.poster">
|
||||
<router-link
|
||||
:to="{ name: 'tag', params: { tagSlug: tag.slug, range: 'latest' } }"
|
||||
:title="tag.name"
|
||||
class="poster-link"
|
||||
>
|
||||
<img
|
||||
v-if="!lazy && !sfw"
|
||||
:src="`/img/${tag.poster.thumbnail}`"
|
||||
|
@ -38,10 +41,19 @@
|
|||
:alt="tag.name"
|
||||
class="poster"
|
||||
>
|
||||
</template>
|
||||
</router-link>
|
||||
|
||||
<span class="title">{{ tag.name }}</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
class="title"
|
||||
:to="{ name: 'tag', params: { tagSlug: tag.slug, range: 'latest' } }"
|
||||
:title="tag.name"
|
||||
>{{ tag.name }}</router-link>
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-else
|
||||
class="title"
|
||||
>{{ tag.name }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -70,51 +82,35 @@ export default {
|
|||
@import 'theme';
|
||||
|
||||
.tile {
|
||||
color: var(--text-light);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 0 3px var(--darken-weak);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.poster {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: 50% 100%;
|
||||
box-shadow: 0 0 3px var(--darken-weak);
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
padding: .5rem 1rem;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background: var(--darken);
|
||||
padding: .25rem .5rem .25rem 1rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
font-size: 1rem;
|
||||
color: var(--shadow-strong);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
text-transform: capitalize;
|
||||
text-shadow: 0 0 3px var(--darken-strong);
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media(max-width: $breakpoint) {
|
||||
.tile {
|
||||
position: initial;
|
||||
}
|
||||
.poster-link:hover + .title,
|
||||
.title:hover {
|
||||
color: var(--primary)
|
||||
}
|
||||
|
||||
.title {
|
||||
position: initial;
|
||||
color: var(--text);
|
||||
background: var(--background);
|
||||
text-shadow: none;
|
||||
}
|
||||
.poster-link:hover .poster {
|
||||
box-shadow: 0 0 3px var(--darken);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -249,6 +249,8 @@ exports.up = knex => Promise.resolve()
|
|||
.references('id')
|
||||
.inTable('entities');
|
||||
|
||||
table.text('entry_id');
|
||||
|
||||
table.integer('alias_for', 12)
|
||||
.references('id')
|
||||
.inTable('actors');
|
||||
|
@ -802,7 +804,7 @@ exports.up = knex => Promise.resolve()
|
|||
.then(() => { // eslint-disable-line arrow-body-style
|
||||
// allow vim fold
|
||||
return knex.raw(`
|
||||
CREATE UNIQUE INDEX unique_actor_slugs_network ON actors (slug, entity_id);
|
||||
CREATE UNIQUE INDEX unique_actor_slugs_network ON actors (slug, entity_id, entry_id);
|
||||
CREATE UNIQUE INDEX unique_actor_slugs ON actors (slug, (entity_id IS NULL));
|
||||
|
||||
CREATE UNIQUE INDEX releases_search_unique ON releases_search (release_id);
|
||||
|
|
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 644 KiB After Width: | Height: | Size: 612 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 882 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 929 KiB After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 471 KiB |
After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 803 KiB |
After Width: | Height: | Size: 413 KiB |
After Width: | Height: | Size: 764 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 802 KiB After Width: | Height: | Size: 872 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 637 KiB After Width: | Height: | Size: 355 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 5.7 MiB After Width: | Height: | Size: 6.9 MiB |
Before Width: | Height: | Size: 652 KiB |
Before Width: | Height: | Size: 655 KiB |
Before Width: | Height: | Size: 613 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 35 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: 212 KiB |
After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 645 KiB After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 759 KiB |
After Width: | Height: | Size: 446 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 557 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 39 KiB |
|
@ -1295,6 +1295,10 @@ const aliases = [
|
|||
for: 'femdom',
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
name: 'dp',
|
||||
for: 'dp',
|
||||
},
|
||||
{
|
||||
name: 'double penetration (dp)',
|
||||
for: 'dp',
|
||||
|
|
|
@ -585,19 +585,20 @@ const sfw = Object.entries({
|
|||
.flat();
|
||||
|
||||
const tagPosters = [
|
||||
['69', 0, 'Abby Lee Brazil and Ramon Nomar for Wicked'],
|
||||
['airtight', 6, 'Remy Lacroix in "Ass Worship 14" for Jules Jordan'],
|
||||
['anal', 0, 'Adriana Chechik in "Manuel Creampies Their Asses 3" for Jules Jordan'],
|
||||
['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'],
|
||||
['asian', 0, 'Alina Li in "Slut Puppies 8" for Jules Jordan'],
|
||||
['asian', 0, 'Jade Kush for Erotica X'],
|
||||
['atm', 2, 'Jureka Del Mar in "Stretched Out" for Her Limit'],
|
||||
['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'],
|
||||
['behind-the-scenes', 0, 'Janice Griffith in "Day With A Pornstar: Janice" for Brazzers'],
|
||||
['blonde', 0, 'Anikka Albrite in "Black Owned 4" for Jules Jordan'],
|
||||
['blonde', 1, 'Marsha May in "Once You Go Black 7" for Jules Jordan'],
|
||||
['blowbang', 0, 'Lacy Lennon in "Lacy Lennon\'s First Blowbang" for HardX'],
|
||||
['blowjob', 0, 'Adriana Chechik in "The Dinner Party" for Real Wife Stories (Brazzers)'],
|
||||
['brunette', 0, 'Nicole Black in GIO971 for LegalPorno'],
|
||||
['brunette', 0, 'Liv Wild in "Dirty Talk 9" for Manuel Ferrara'],
|
||||
['bukkake', 0, 'Jaye Summers in "Facialized 5" for HardX'],
|
||||
['caucasian', 0, 'Remy Lacroix for HardX'],
|
||||
['creampie', 'poster', 'ALina Lopez in "Making Yourself Unforgettable" for Blacked'],
|
||||
|
@ -612,27 +613,28 @@ const tagPosters = [
|
|||
['dp', 2, 'Megan Rain in "DP Masters 4" for Jules Jordan'],
|
||||
['dvp', 'poster', 'Riley Reid in "Pizza That Ass" for Reid My Lips'],
|
||||
['dv-tp', 'poster', 'Juelz Ventura in "Gangbanged 5" for Elegant Angel'],
|
||||
['ebony', 1, 'Ana Foxxx in "DP Me 4" for HardX'],
|
||||
['ebony', 2, 'Nia Nacci for Sweetheart Video'],
|
||||
['facefucking', 2, 'Jynx Maze for Throated'],
|
||||
['facial', 0, 'Brooklyn Gray in "All About Ass 4" for Evil Angel'],
|
||||
['fake-boobs', 2, 'Gia Milana in "Hot Anal Latina" for HardX'],
|
||||
['fake-boobs', 4, 'Capri Cavanni for Big Tits in Sports'],
|
||||
['family', 0, 'Teanna Trump in "A Family Appear: Part One" for Brazzers'],
|
||||
['femdom', 0, 'Alina Li in "Asian Domination… She Holds Jules Jordan\'s Cock Hostage!" for Jules Jordan'],
|
||||
['gangbang', 5, 'Carter Cruise\'s first gangbang in "Slut Puppies 9" for Jules Jordan'],
|
||||
['gaping', 1, 'Vina Sky in "Vina Sky Does Anal" for HardX'],
|
||||
['indian', 0, 'Resha in "Casting Resha" for Watch 4 Beauty'],
|
||||
['interracial', 0, 'Jaye Summers and Prince Yahshua in "Platinum Pussy 3" for Jules Jordan'],
|
||||
['latina', 1, 'Jynx Maze in "Big Anal Asses 2" for HardX'],
|
||||
['latina', 0, 'Vienna Black for Spizoo'],
|
||||
['lesbian', 0, 'Jenna Sativa and Alina Lopez in "Opposites Attract" for Girl Girl'],
|
||||
['maid', 0, 'Whitney Wright in "Dredd Up Your Ass 2" for Jules Jordan'],
|
||||
['milf', 0, 'Olivia Austin in "Dredd 3" for Jules Jordan'],
|
||||
['mff', 1, 'Anikka Albrite, Kelsi Monroe and Mick Blue for HardX'],
|
||||
['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'],
|
||||
['mfm', 0, 'Vina Sky in "Jules Jordan\'s Three Ways" for Jules Jordan'],
|
||||
['natural-boobs', 1, 'Nia Nacci for First Class POV'],
|
||||
['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', 2, 'Jade Kush for Passion HD'],
|
||||
['oral-creampie', 0, 'Henessy in "B(ass)t Friends" for Asshole Fever'],
|
||||
['orgy', 1, 'Megan Rain (DP), Morgan Lee (anal), Jessa Rhodes, Melissa Moore and Kimmy Granger in "Orgy Masters 8" for Jules Jordan'],
|
||||
['parody', 0, 'Capri Cavanni and Dani Daniels in "The Whore of Wall Street" for Brazzers'],
|
||||
['piercings', 0, 'Kaegune in "When The Sun Goes Down" for Suicide Girls'],
|
||||
['piss-drinking', 0, 'Scarlet Domingo in LegalPorno GL227'],
|
||||
['pussy-eating', 1, 'Anikka Albrite and Riley Reid for In The Crack'],
|
||||
|
@ -665,7 +667,6 @@ const tagPhotos = [
|
|||
['atm', 3, 'Natasha Teen in "Work That Ass!" for Her Limit'],
|
||||
['atm', 0, 'Roxy Lips in "Under Her Coat" for 21 Naturals'],
|
||||
['atm', 6, 'Jane Wilde in "Teen Anal" for Evil Angel'],
|
||||
['asian', 'poster', 'Vina Sky in "Slut Puppies 15" 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', 4, 'Lana Roy in "Anal In The Club" for 21Naturals'],
|
||||
|
@ -673,6 +674,7 @@ const tagPhotos = [
|
|||
// ['anal', 1, 'Veronica Leal and Tina Kay in "Agents On Anal Mission" for Asshole Fever'],
|
||||
// ['anal', 0, 'Veronica Leal'],
|
||||
['behind-the-scenes', 1, 'Madison Ivy in "Day With A Pornstar" for Brazzers'],
|
||||
['blonde', 0, 'Anikka Albrite in "Black Owned 4" for Jules Jordan'],
|
||||
['blowbang', 'poster', 'Marsha May in "Feeding Frenzy 12" for Jules Jordan'],
|
||||
// ['bukkake', 'poster', 'Mia Malkova in "Facialized 2" for HardX'],
|
||||
['caucasian', 1, 'Sheena Shaw for Brazzers'],
|
||||
|
@ -696,25 +698,28 @@ const tagPhotos = [
|
|||
['dvp', 0, 'Aaliyah Hadid in "Squirting From Double Penetration With Anal" for Bang Bros'],
|
||||
['dv-tp', 1, 'Adriana Chechik in "Adriana\'s Triple Anal Penetration!"'],
|
||||
['dv-tp', 0, 'Luna Rival in LegalPorno SZ1490'],
|
||||
['ebony', 1, 'Ana Foxxx in "DP Me 4" for HardX'],
|
||||
['facial', 1, 'Ella Knox in "Mr Saltys Adult Emporium Adventure 2" for Aziani'],
|
||||
['facial', 'poster', 'Jynx Maze'],
|
||||
['facefucking', 3, 'Adriana Chechik in "Performing Magic Butt Tricks With Jules Jordan. What Will Disappear In Her Ass?" for Jules Jordan'],
|
||||
['facefucking', 1, 'Carrie for Young Throats'],
|
||||
['fake-boobs', 2, 'Gia Milana in "Hot Anal Latina" for HardX'],
|
||||
['fake-boobs', 1, 'Lela Star in "Thick" for Jules Jordan'],
|
||||
['fake-boobs', 3, 'Ashly Anderson for Passion HD'],
|
||||
// ['fake-boobs', 0, 'Marsha May in "Once You Go Black 7" for Jules Jordan'],
|
||||
['gangbang', 'poster', 'Kristen Scott in "Interracial Gangbang!" for Jules Jordan'],
|
||||
['gangbang', 0, '"4 On 1 Gangbangs" for Doghouse Digital'],
|
||||
['gangbang', 4, 'Marley Brinx in "The Gangbang of Marley Brinx" for Jules Jordan'],
|
||||
['gangbang', 1, 'Ginger Lynn in "Gangbang Mystique", a photoset shot by Suze Randall for Puritan No. 10, 1984. This photo pushed the boundaries of pornography at the time, as depicting a woman \'fully occupied\' was unheard of.'],
|
||||
['gaping', 'poster', 'Zoey Monroe in "Manuel DPs Them All 5" for Jules Jordan'],
|
||||
['gaping', 2, 'Alex Grey in "DP Masters 5" for Jules Jordan'],
|
||||
['latina', 0, 'Abby Lee Brazil for Bang Bros'],
|
||||
['latina', 1, 'Jynx Maze in "Big Anal Asses 2" for HardX'],
|
||||
['latina', 2, 'Alexis Love for Penthouse'],
|
||||
['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'],
|
||||
['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'],
|
||||
['oil', 1, 'Emily Willis in "Emily Willis Has A Squirting Anal Orgasm" 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'],
|
||||
['oil', 3, 'Vienna Black for Passion HD'],
|
||||
['oil', 0, 'Jada Stevens in "Jada Stevens Anal Ass Oiled Up For James Deen\'s Cock" for Jules Jordan'],
|
||||
['oil', 1, 'Kissa Sins in "Oil Overload 14" for JulesJordan'],
|
||||
['orgy', 'poster', 'Zoey Mornoe (DP), Jillian Janson (sex), Frida Sante, Katerina Kay and Natasha Starr in "Orgy Masters 6" for Jules Jordan'],
|
||||
['pussy-eating', 0, 'Kali Roses licking Emily Willis\' pussy in "Peeping On My Neighbor" for Girl Girl'],
|
||||
['redhead', 0, 'Penny Pax in "The Submission of Emma Marx: Boundaries" for New Sensations'],
|
||||
|
|
|
@ -28,7 +28,7 @@ async function init() {
|
|||
const actors = actorNames.length > 0 && await scrapeActors(actorNames);
|
||||
const actorBaseScenes = argv.actors && argv.actorScenes && actors.map(actor => actor.releases).flat().filter(Boolean);
|
||||
|
||||
const updateBaseScenes = (argv.all || argv.channels || argv.networks) && await fetchUpdates();
|
||||
const updateBaseScenes = (argv.all || argv.channels || argv.networks || argv.movies) && await fetchUpdates();
|
||||
|
||||
const scenesFromFile = argv.scenesFile && await getFileEntries(argv.scenesFile);
|
||||
const sceneUrls = (argv.scenes || []).concat(scenesFromFile || []);
|
||||
|
|
|
@ -25,6 +25,10 @@ const { argv } = yargs
|
|||
type: 'array',
|
||||
alias: 'channel',
|
||||
})
|
||||
.option('movies', {
|
||||
describe: 'Scrape movies from channels',
|
||||
type: 'array',
|
||||
})
|
||||
.option('actors', {
|
||||
describe: 'Scrape actors by name or slug',
|
||||
type: 'array',
|
||||
|
@ -91,10 +95,10 @@ const { argv } = yargs
|
|||
type: 'boolean',
|
||||
default: true,
|
||||
})
|
||||
.option('redownload', {
|
||||
.option('force', {
|
||||
describe: 'Don\'t ignore duplicates, update existing entries',
|
||||
type: 'boolean',
|
||||
alias: 'force',
|
||||
alias: 'redownload',
|
||||
})
|
||||
.option('after', {
|
||||
describe: 'Don\'t fetch scenes older than',
|
||||
|
|
|
@ -112,8 +112,8 @@ async function scrapeRelease(baseRelease, entities, type = 'scene') {
|
|||
logger.verbose(`Fetching ${type} ${baseRelease.url}`);
|
||||
|
||||
const scrapedRelease = type === 'scene'
|
||||
? await scraper.fetchScene(baseRelease.url, entity, baseRelease, null, include)
|
||||
: await scraper.fetchMovie(baseRelease.url, entity, baseRelease, null, include);
|
||||
? await scraper.fetchScene(baseRelease.url, entity, baseRelease, include, null)
|
||||
: await scraper.fetchMovie(baseRelease.url, entity, baseRelease, include, null);
|
||||
|
||||
const mergedRelease = {
|
||||
...baseRelease,
|
||||
|
|
|
@ -37,8 +37,8 @@ async function fetchLatestWrap(site, page = 1) {
|
|||
return latest.map(scene => extractActors(scene));
|
||||
}
|
||||
|
||||
async function fetchSceneWrap(url, site) {
|
||||
const scene = await fetchScene(url, site);
|
||||
async function fetchSceneWrap(url, channel, baseRelease, include) {
|
||||
const scene = await fetchScene(url, channel, baseRelease, include);
|
||||
|
||||
return extractActors(scene);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ function scrapeLatest(scenes, site, models) {
|
|||
});
|
||||
}
|
||||
|
||||
function scrapeScene({ html, qu }, url, site, models) {
|
||||
function scrapeScene({ html, qu }, url, site, include, models) {
|
||||
const release = { url };
|
||||
|
||||
[release.entryId] = url.split('/').slice(-1);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const qu = require('../utils/q');
|
||||
const slugify = require('../utils/slugify');
|
||||
|
||||
function scrapeAll(scenes, channel) {
|
||||
return scenes.map(({ query }) => {
|
||||
|
@ -75,20 +74,25 @@ async function scrapeScene({ query, html }, url) {
|
|||
return release;
|
||||
}
|
||||
|
||||
function scrapeProfile({ query, el }, actorName, entity, include) {
|
||||
const profile = {};
|
||||
function scrapeMovies(movies, channel) {
|
||||
return movies.map(({ query }) => {
|
||||
const release = {};
|
||||
|
||||
profile.description = query.cnt('.bio-text');
|
||||
profile.birthPlace = query.cnt('.birth-place span');
|
||||
release.url = query.url('.boxcover', 'href', { origin: channel.url });
|
||||
release.entryId = new URL(release.url).pathname.match(/\/(\d+)/)[1];
|
||||
|
||||
profile.avatar = query.img('.actor-photo img');
|
||||
release.title = query.cnt('span');
|
||||
|
||||
if (include.releases) {
|
||||
return scrapeAll(qu.initAll(el, '.scene'));
|
||||
}
|
||||
const cover = query.img('picture img');
|
||||
|
||||
console.log(profile);
|
||||
return profile;
|
||||
release.covers = [
|
||||
// filename is ignored, back-cover has suffix after media ID
|
||||
cover.replace('_sq.jpg', '/front.jpg').replace(/\/product\/\d+/, '/product/500'),
|
||||
cover.replace('_sq.jpg', 'b/back.jpg').replace(/\/product\/\d+/, '/product/500'),
|
||||
];
|
||||
|
||||
return release;
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchLatest(channel, page = 1) {
|
||||
|
@ -118,12 +122,14 @@ async function fetchScene(url, channel) {
|
|||
return res.status;
|
||||
}
|
||||
|
||||
async function fetchProfile(actorName, entity, include) {
|
||||
const url = `${entity.url}/actors/${slugify(actorName, '_')}`;
|
||||
const res = await qu.get(url);
|
||||
async function fetchMovies(channel, page = 1) {
|
||||
const res = await qu.getAll(`https://www.elegantangel.com/streaming-elegant-angel-dvds-on-video.html?page=${page}`, '.grid-item', null, {
|
||||
// invalid certificate
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return scrapeProfile(res.item, actorName, entity, include);
|
||||
return scrapeMovies(res.items, channel);
|
||||
}
|
||||
|
||||
return res.status;
|
||||
|
@ -132,5 +138,5 @@ async function fetchProfile(actorName, entity, include) {
|
|||
module.exports = {
|
||||
fetchLatest,
|
||||
fetchScene,
|
||||
fetchProfile,
|
||||
fetchMovies,
|
||||
};
|
||||
|
|
|
@ -356,7 +356,7 @@ function scrapeProfileTour({ el, qu }, site) {
|
|||
return profile;
|
||||
}
|
||||
|
||||
async function fetchLatest(site, page = 1, _beforeFetchLatest, accSiteReleases) {
|
||||
async function fetchLatest(site, page = 1, include, preflight, accSiteReleases) {
|
||||
const url = (site.parameters?.latest && util.format(site.parameters.latest, page))
|
||||
|| (site.parameters?.t1 && `${site.url}/t1/categories/movies_${page}_d.html`)
|
||||
|| `${site.url}/categories/movies_${page}_d.html`;
|
||||
|
|
|
@ -139,8 +139,8 @@ function scrapeAll(scenes, site) {
|
|||
|
||||
release.entryId = el.dataset.setid || qu.q('.rating_box')?.dataset.id;
|
||||
|
||||
release.url = qu.url('.update_title, .dvd_info > a, a ~ a');
|
||||
release.title = qu.q('.update_title, .dvd_info > a, a ~ a', true);
|
||||
release.url = qu.url('.update_title a, .dvd_info > a, a ~ a');
|
||||
release.title = qu.q('.update_title a, .dvd_info > a, a ~ a', true);
|
||||
release.date = qu.date('.update_date', 'MM/DD/YYYY');
|
||||
|
||||
release.actors = qu.all('.update_models a', true);
|
||||
|
@ -249,7 +249,8 @@ async function scrapeScene({ html, qu }, url, site, include) {
|
|||
|
||||
if (trailerLines.length) {
|
||||
release.trailer = trailerLines.map((trailerLine) => {
|
||||
const src = trailerLine.match(/path:"([\w:/.&=?%]+)"/)?.[1];
|
||||
// const src = trailerLine.match(/path:"([\w-:/.&=?%]+)"/)?.[1];
|
||||
const src = trailerLine.match(/path:"(.+)"/)?.[1];
|
||||
const quality = trailerLine.match(/movie_height:'(\d+)/)?.[1];
|
||||
|
||||
return src && {
|
||||
|
@ -368,7 +369,7 @@ async function fetchUpcoming(site) {
|
|||
return res.statusCode;
|
||||
}
|
||||
|
||||
async function fetchScene(url, site, baseRelease, preflight, include) {
|
||||
async function fetchScene(url, site, baseRelease, include) {
|
||||
const res = await get(url);
|
||||
|
||||
return res.ok ? scrapeScene(res.item, url, site, include) : res.status;
|
||||
|
|
|
@ -80,8 +80,8 @@ function needNextPage(uniqueReleases, pageAccReleases) {
|
|||
async function scrapeReleases(scraper, entity, preData, upcoming = false) {
|
||||
const scrapePage = async (page = 1, accReleases = []) => {
|
||||
const latestReleases = upcoming
|
||||
? await scraper.fetchUpcoming(entity, page, preData, include)
|
||||
: await scraper.fetchLatest(entity, page, preData, include);
|
||||
? await scraper.fetchUpcoming(entity, page, include, preData)
|
||||
: await scraper.fetchLatest(entity, page, include, preData);
|
||||
|
||||
if (!Array.isArray(latestReleases)) {
|
||||
// scraper is unable to fetch the releases and returned a HTTP code or null
|
||||
|
@ -171,6 +171,10 @@ async function scrapeChannelReleases(scraper, channelEntity, preData) {
|
|||
: [],
|
||||
]);
|
||||
|
||||
if (scraper.fetchMovies) {
|
||||
await scraper.fetchMovies(channelEntity);
|
||||
}
|
||||
|
||||
logger.info(`Fetching ${latestReleases.length} latest and ${upcomingReleases.length} upcoming updates for '${channelEntity.name}' (${channelEntity.parent?.name})`);
|
||||
|
||||
return [...latestReleases, ...upcomingReleases];
|
||||
|
|