Improved actor profile flow. Added images.
|
@ -103,9 +103,7 @@
|
|||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="bio nolist">
|
||||
<li
|
||||
v-if="actor.ethnicity"
|
||||
class="bio-item ethnicity"
|
||||
|
@ -181,7 +179,7 @@
|
|||
<span v-else>Yes</span>
|
||||
</li>
|
||||
|
||||
<span class="scraped">Updated on {{ formatDate(actor.scrapedAt, 'YYYY-MM-DD HH:mm') }}</span>
|
||||
<li class="bio-item scraped">Updated on {{ formatDate(actor.scrapedAt, 'YYYY-MM-DD HH:mm') }}</li>
|
||||
</ul>
|
||||
|
||||
<div class="extra">
|
||||
|
@ -296,49 +294,56 @@ export default {
|
|||
background: $profile;
|
||||
color: $highlight-extreme;
|
||||
width: 100%;
|
||||
height: 18rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
padding: 1rem 0 0 0;
|
||||
|
||||
.avatar-link {
|
||||
font-size: 0;
|
||||
padding: 1rem 0 1rem 1rem;
|
||||
padding: 0 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
height: 15rem;
|
||||
width: 12rem;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
margin: 0 1rem 0 0;
|
||||
object-fit: cover;
|
||||
object-position: 50% 0;
|
||||
margin: 0 .5rem 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bio {
|
||||
flex-grow: 1;
|
||||
min-width: 20rem;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
margin: 0 2rem 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bio-header {
|
||||
width: calc(50% - 2rem);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0 0 1rem 0;
|
||||
padding: 0 .5rem .5rem 0;
|
||||
margin: 0 0 0 1rem;
|
||||
}
|
||||
|
||||
.bio-item {
|
||||
width: calc(50% - 2rem);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 0 .25rem 0;
|
||||
margin: 0 0 .25rem 0;
|
||||
box-sizing: border-box;
|
||||
padding: .25rem 0 ;
|
||||
margin: 0 0 .25rem 1rem;
|
||||
line-height: 1.75;
|
||||
text-align: right;
|
||||
font-size: .9rem;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: solid 1px $highlight-hint;
|
||||
|
@ -429,12 +434,12 @@ export default {
|
|||
|
||||
.scraped {
|
||||
color: $highlight-weak;
|
||||
margin: 1rem 0 0 0;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.extra {
|
||||
flex-grow: 1;
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
@ -442,7 +447,6 @@ export default {
|
|||
position: relative;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem 0 0 0;
|
||||
margin: 0 2rem 0 0;
|
||||
line-height: 1.5;
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
@ -70,8 +70,7 @@ export default {
|
|||
|
||||
.poster,
|
||||
.photo {
|
||||
height: 10rem;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
margin: 0 1rem 0 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
<div class="sidebar-content">
|
||||
<p
|
||||
v-if="description"
|
||||
class="description"
|
||||
v-html="description"
|
||||
/>
|
||||
|
|
|
@ -21,10 +21,12 @@
|
|||
<span
|
||||
v-else
|
||||
class="avatar"
|
||||
>No photo</span>
|
||||
><img
|
||||
:src="`/img/avatar_${actor.gender || 'female'}.png`"
|
||||
class="avatar-fallback"
|
||||
></span>
|
||||
|
||||
<span
|
||||
v-if="actor.age || actor.origin"
|
||||
class="details"
|
||||
>
|
||||
<span>
|
||||
|
@ -110,10 +112,17 @@ export default {
|
|||
object-position: 50% 0;
|
||||
}
|
||||
|
||||
.avatar-fallback {
|
||||
max-height: 75%;
|
||||
max-width: 80%;
|
||||
opacity: .1;
|
||||
}
|
||||
|
||||
.details {
|
||||
background: $shadow;
|
||||
color: $text-contrast;
|
||||
width: 100%;
|
||||
height: 1.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
|
|
@ -47,8 +47,10 @@
|
|||
>{{ `(${formatDate(release.dateAdded, 'MMM D, YYYY')})` }}</a>
|
||||
</span>
|
||||
|
||||
<router-link
|
||||
:to="`/${release.type || 'scene'}/${release.id}`"
|
||||
<a
|
||||
:href="`/${release.type || 'scene'}/${release.id}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="link"
|
||||
>
|
||||
<img
|
||||
|
@ -70,12 +72,14 @@
|
|||
:title="release.title"
|
||||
class="thumbnail"
|
||||
>No thumbnail available</div>
|
||||
</router-link>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<div class="info">
|
||||
<router-link
|
||||
:to="`/${release.type || 'scene'}/${release.id}`"
|
||||
<a
|
||||
:href="`/${release.type || 'scene'}/${release.id}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="row link"
|
||||
>
|
||||
<h3
|
||||
|
@ -88,7 +92,7 @@
|
|||
icon="film"
|
||||
/>{{ release.title }}
|
||||
</h3>
|
||||
</router-link>
|
||||
</a>
|
||||
|
||||
<span class="row">
|
||||
<ul class="actors nolist">
|
||||
|
|
|
@ -366,10 +366,16 @@
|
|||
-o-object-position: 50% 0;
|
||||
object-position: 50% 0;
|
||||
}
|
||||
.avatar-fallback[data-v-6989dc6f] {
|
||||
max-height: 75%;
|
||||
max-width: 80%;
|
||||
opacity: .1;
|
||||
}
|
||||
.details[data-v-6989dc6f] {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
height: 1.75rem;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
|
@ -1026,55 +1032,63 @@
|
|||
background: #222;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
width: 100%;
|
||||
height: 18rem;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
padding: 1rem 0 0 0;
|
||||
}
|
||||
.profile .avatar-link[data-v-ea0483c2] {
|
||||
font-size: 0;
|
||||
padding: 1rem 0 1rem 1rem;
|
||||
padding: 0 0 1rem 1rem;
|
||||
}
|
||||
.profile .avatar[data-v-ea0483c2] {
|
||||
height: 15rem;
|
||||
width: 12rem;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
margin: 0 1rem 0 0;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
-o-object-position: 50% 0;
|
||||
object-position: 50% 0;
|
||||
margin: 0 .5rem 0 0;
|
||||
}
|
||||
.bio[data-v-ea0483c2] {
|
||||
-webkit-box-flex: 1;
|
||||
flex-grow: 1;
|
||||
min-width: 20rem;
|
||||
height: 100%;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
margin: 0 2rem 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.bio-header[data-v-ea0483c2] {
|
||||
width: calc(50% - 2rem);
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
margin: 0 0 1rem 0;
|
||||
padding: 0 .5rem .5rem 0;
|
||||
margin: 0 0 0 1rem;
|
||||
}
|
||||
.bio-item[data-v-ea0483c2] {
|
||||
width: calc(50% - 2rem);
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
justify-content: space-between;
|
||||
padding: 0 0 .25rem 0;
|
||||
margin: 0 0 .25rem 0;
|
||||
box-sizing: border-box;
|
||||
padding: .25rem 0;
|
||||
margin: 0 0 .25rem 1rem;
|
||||
line-height: 1.75;
|
||||
text-align: right;
|
||||
font-size: .9rem;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
}
|
||||
.bio-item[data-v-ea0483c2]:not(:last-of-type) {
|
||||
border-bottom: solid 1px rgba(255, 255, 255, 0.075);
|
||||
|
@ -1148,19 +1162,18 @@
|
|||
}
|
||||
.scraped[data-v-ea0483c2] {
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
margin: 1rem 0 0 0;
|
||||
font-size: .8rem;
|
||||
}
|
||||
.extra[data-v-ea0483c2] {
|
||||
-webkit-box-flex: 1;
|
||||
flex-grow: 1;
|
||||
max-width: 40rem;
|
||||
}
|
||||
.description[data-v-ea0483c2] {
|
||||
max-height: 12rem;
|
||||
position: relative;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem 0 0 0;
|
||||
margin: 0 2rem 0 0;
|
||||
line-height: 1.5;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -1309,8 +1322,7 @@
|
|||
}
|
||||
.photos.compact .poster[data-v-9d950ba8],
|
||||
.photos.compact .photo[data-v-9d950ba8] {
|
||||
height: 10rem;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
margin: 0 1rem 0 0;
|
||||
}
|
||||
.poster[data-v-9d950ba8],
|
||||
|
|
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 851 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 601 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 712 KiB |
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 89 KiB |
|
@ -4,11 +4,11 @@ const tagPosters = Object.entries({
|
|||
'anal-creampie': ['poster'],
|
||||
'ass-to-mouth': ['poster', 'Alysa Gap and Logan in "Anal Buffet 4" for Evil Angel'],
|
||||
'da-tp': [0, 'Natasha Teen in LegalPorno SZ2164'],
|
||||
'double-anal': ['poster', 'Haley Reed in "Young Hot Ass" for Evil Angel'],
|
||||
'double-anal': [2, 'Lana Rhoades in "Gangbang Me 3" for HardX'],
|
||||
'double-penetration': ['poster', 'Mia Malkova in "DP!" for HardX'],
|
||||
'double-vaginal': ['poster'],
|
||||
'dv-tp': ['poster', 'Juelz Ventura in "Gangbanged 5" for Elegant Angel'],
|
||||
'oral-creampie': ['poster'],
|
||||
'oral-creampie': [1, 'Keisha Grey in Brazzers House'],
|
||||
'triple-anal': ['poster', 'Kristy Black in SZ1986 for LegalPorno'],
|
||||
airtight: [1, 'Jynx Maze in "Pump My Ass Full of Cum 3" for Jules Jordan'],
|
||||
anal: ['poster', 'Jynx Maze in "Anal Buffet 6" for Evil Angel'],
|
||||
|
@ -26,6 +26,7 @@ const tagPosters = Object.entries({
|
|||
mff: ['poster'],
|
||||
mfm: ['poster'],
|
||||
orgy: ['poster'],
|
||||
schoolgirl: [1, 'Eliza Ibarra for Brazzers'],
|
||||
swallowing: ['poster'],
|
||||
tattoo: ['poster', 'Kali Roses in "Goes All In For Anal" for Hussie Pass'],
|
||||
trainbang: ['poster', 'Kali Roses in "Passing Me Around" for Blacked'],
|
||||
|
@ -47,6 +48,7 @@ const tagPhotos = [
|
|||
['da-tp', 2, 'Angel Smalls in GIO408 for LegalPorno'],
|
||||
['da-tp', 3, 'Evelina Darling in GIO294'],
|
||||
['da-tp', 4, 'Ninel Mojado aka Mira Cuckold in GIO063 for LegalPorno'],
|
||||
['double-anal', 'poster', 'Haley Reed in "Young Hot Ass" for Evil Angel'],
|
||||
['double-anal', 0, 'Nicole Black doing double anal during a gangbang in GIO971 for LegalPorno'],
|
||||
['double-anal', 1, 'Ria Sunn in SZ1801 for LegalPorno'],
|
||||
['double-penetration', 0],
|
||||
|
@ -60,6 +62,7 @@ const tagPhotos = [
|
|||
['trainbang', 0, 'Nicole Black in GIO971 for LegalPorno'],
|
||||
['triple-anal', 1, 'Natasha Teen in SZ2098 for LegalPorno'],
|
||||
['triple-anal', 2, 'Kira Thorn in GIO1018 for LegalPorno'],
|
||||
['oral-creampie', 'poster', 'Khloe Kapri'],
|
||||
]
|
||||
.map(([slug, fileIndex, comment], index) => ({
|
||||
tagSlug: slug,
|
||||
|
|
|
@ -287,6 +287,7 @@ async function mergeProfiles(profiles, actor) {
|
|||
birthdate: Number.isNaN(Number(prevProfile.birthdate)) ? profile.birthdate : prevProfile.birthdate,
|
||||
birthPlace: prevProfile.birthPlace || profile.birthPlace,
|
||||
residencePlace: prevProfile.residencePlace || profile.residencePlace,
|
||||
nationality: prevProfile.nationality || profile.nationality, // used to derive country when not available
|
||||
ethnicity: prevProfile.ethnicity || profile.ethnicity,
|
||||
bust: prevProfile.bust || profile.bust,
|
||||
waist: prevProfile.waist || profile.waist,
|
||||
|
@ -316,6 +317,17 @@ async function mergeProfiles(profiles, actor) {
|
|||
mergedProfile.birthPlace = birthPlace;
|
||||
mergedProfile.residencePlace = residencePlace;
|
||||
|
||||
if (!mergedProfile.birthPlace && mergedProfile.nationality) {
|
||||
const country = await knex('countries')
|
||||
.where('nationality', 'ilike', `%${mergedProfile.nationality}%`)
|
||||
.orderBy('priority', 'desc')
|
||||
.first();
|
||||
|
||||
mergedProfile.birthPlace = {
|
||||
country: country.alpha2,
|
||||
};
|
||||
}
|
||||
|
||||
return mergedProfile;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,8 @@ async function storePhotos(photos, {
|
|||
concurrency: 10,
|
||||
}).filter(photo => photo);
|
||||
|
||||
const [hashDuplicates, hashOriginals] = await findDuplicates(metaFiles, 'hash', 'hash', label);
|
||||
const metaFilesByHash = metaFiles.reduce((acc, photo) => ({ ...acc, [photo.hash]: photo }), {}); // pre-filter hash duplicates within set; may occur through fallbacks
|
||||
const [hashDuplicates, hashOriginals] = await findDuplicates(Object.values(metaFilesByHash), 'hash', 'hash', label);
|
||||
|
||||
const savedPhotos = await savePhotos(hashOriginals, {
|
||||
domain,
|
||||
|
|
|
@ -119,17 +119,12 @@ async function scrapeProfile(html, _url, actorName) {
|
|||
const descriptionEl = document.querySelector('.description-box');
|
||||
const avatarEl = document.querySelector('.pornstar-details .card-img-top');
|
||||
|
||||
const country = await knex('countries')
|
||||
.where('nationality', 'ilike', `%${bio.Nationality}%`)
|
||||
.orderBy('priority', 'desc')
|
||||
.first();
|
||||
|
||||
const profile = {
|
||||
name: actorName,
|
||||
};
|
||||
|
||||
profile.birthdate = moment.utc(bio.Birthday, 'MMMM DD, YYYY').toDate();
|
||||
if (country) profile.birthPlace = country.name;
|
||||
if (bio.Nationality) profile.nationality = bio.Nationality;
|
||||
|
||||
if (bio['Bra size']) [profile.bust] = bio['Bra size'].match(/\d+\w+/);
|
||||
if (bio.Waist) profile.waist = Number(bio.Waist.match(/\d+/)[0]);
|
||||
|
|
|
@ -78,6 +78,11 @@ function scrapeProfile(html, url, actorName, siteSlug) {
|
|||
|
||||
const avatarEl = document.querySelector('img.actorPicture');
|
||||
const descriptionEl = document.querySelector('.actorBio p:not(.bioTitle)');
|
||||
const hairEl = document.querySelector('.actorProfile .attribute_hair_color');
|
||||
const heightEl = document.querySelector('.actorProfile .attribute_height');
|
||||
const weightEl = document.querySelector('.actorProfile .attribute_weight');
|
||||
const aliasEl = document.querySelector('.actorProfile .attribute_alternate_names');
|
||||
const nationalityEl = document.querySelector('.actorProfile .attribute_home');
|
||||
|
||||
const profile = {
|
||||
name: actorName,
|
||||
|
@ -96,6 +101,11 @@ function scrapeProfile(html, url, actorName, siteSlug) {
|
|||
}
|
||||
|
||||
if (descriptionEl) profile.description = descriptionEl.textContent.trim();
|
||||
if (hairEl) profile.hair = hairEl.textContent.split(':')[1].trim();
|
||||
if (heightEl) profile.height = Number(heightEl.textContent.match(/\d+/)[0]);
|
||||
if (weightEl) profile.weight = Number(weightEl.textContent.match(/\d+/)[0]);
|
||||
if (aliasEl) profile.aliases = aliasEl.textContent.split(':')[1].trim().split(', ');
|
||||
if (nationalityEl) profile.nationality = nationalityEl.textContent.split(':')[1].trim();
|
||||
|
||||
profile.releases = Array.from(document.querySelectorAll('.sceneList .scene a.imgLink'), el => `https://${siteSlug}.com${el.href}`);
|
||||
|
||||
|
|