Improved actor profile flow. Added images.

This commit is contained in:
ThePendulum 2020-01-23 03:52:12 +01:00
parent c9b8a18db5
commit 9db0e97512
23 changed files with 104 additions and 54 deletions

View File

@ -103,9 +103,7 @@
</span> </span>
</span> </span>
</li> </li>
</ul>
<ul class="bio nolist">
<li <li
v-if="actor.ethnicity" v-if="actor.ethnicity"
class="bio-item ethnicity" class="bio-item ethnicity"
@ -181,7 +179,7 @@
<span v-else>Yes</span> <span v-else>Yes</span>
</li> </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> </ul>
<div class="extra"> <div class="extra">
@ -296,49 +294,56 @@ export default {
background: $profile; background: $profile;
color: $highlight-extreme; color: $highlight-extreme;
width: 100%; width: 100%;
height: 18rem;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-shrink: 0; flex-shrink: 0;
padding: 1rem 0 0 0;
.avatar-link { .avatar-link {
font-size: 0; font-size: 0;
padding: 1rem 0 1rem 1rem; padding: 0 0 1rem 1rem;
} }
.avatar { .avatar {
height: 15rem; height: 100%;
width: 12rem;
flex-shrink: 0; flex-shrink: 0;
margin: 0 1rem 0 0; margin: 0 .5rem 0 0;
object-fit: cover;
object-position: 50% 0;
} }
} }
.bio { .bio {
flex-grow: 1; flex-grow: 1;
min-width: 20rem; height: 100%;
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-wrap: wrap;
box-sizing: border-box; box-sizing: border-box;
padding: 1rem; overflow: hidden;
margin: 0 2rem 0 0;
} }
.bio-header { .bio-header {
width: calc(50% - 2rem);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin: 0 0 1rem 0; padding: 0 .5rem .5rem 0;
margin: 0 0 0 1rem;
} }
.bio-item { .bio-item {
width: calc(50% - 2rem);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0 0 .25rem 0; box-sizing: border-box;
margin: 0 0 .25rem 0; padding: .25rem 0 ;
margin: 0 0 .25rem 1rem;
line-height: 1.75; line-height: 1.75;
text-align: right; text-align: right;
font-size: .9rem; font-size: .9rem;
font-weight: 600; font-weight: 600;
overflow: hidden;
&:not(:last-of-type) { &:not(:last-of-type) {
border-bottom: solid 1px $highlight-hint; border-bottom: solid 1px $highlight-hint;
@ -429,12 +434,12 @@ export default {
.scraped { .scraped {
color: $highlight-weak; color: $highlight-weak;
margin: 1rem 0 0 0;
font-size: .8rem; font-size: .8rem;
} }
.extra { .extra {
flex-grow: 1; flex-grow: 1;
max-width: 40rem;
} }
.description { .description {
@ -442,7 +447,6 @@ export default {
position: relative; position: relative;
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
padding: 1rem 0 0 0;
margin: 0 2rem 0 0; margin: 0 2rem 0 0;
line-height: 1.5; line-height: 1.5;
text-overflow: ellipsis; text-overflow: ellipsis;

View File

@ -70,8 +70,7 @@ export default {
.poster, .poster,
.photo { .photo {
height: 10rem; width: 100%;
width: auto;
margin: 0 1rem 0 0; margin: 0 1rem 0 0;
} }
} }

View File

@ -24,6 +24,7 @@
<div class="sidebar-content"> <div class="sidebar-content">
<p <p
v-if="description"
class="description" class="description"
v-html="description" v-html="description"
/> />

View File

@ -21,10 +21,12 @@
<span <span
v-else v-else
class="avatar" class="avatar"
>No photo</span> ><img
:src="`/img/avatar_${actor.gender || 'female'}.png`"
class="avatar-fallback"
></span>
<span <span
v-if="actor.age || actor.origin"
class="details" class="details"
> >
<span> <span>
@ -110,10 +112,17 @@ export default {
object-position: 50% 0; object-position: 50% 0;
} }
.avatar-fallback {
max-height: 75%;
max-width: 80%;
opacity: .1;
}
.details { .details {
background: $shadow; background: $shadow;
color: $text-contrast; color: $text-contrast;
width: 100%; width: 100%;
height: 1.75rem;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;

View File

@ -47,8 +47,10 @@
>{{ `(${formatDate(release.dateAdded, 'MMM D, YYYY')})` }}</a> >{{ `(${formatDate(release.dateAdded, 'MMM D, YYYY')})` }}</a>
</span> </span>
<router-link <a
:to="`/${release.type || 'scene'}/${release.id}`" :href="`/${release.type || 'scene'}/${release.id}`"
target="_blank"
rel="noopener noreferrer"
class="link" class="link"
> >
<img <img
@ -70,12 +72,14 @@
:title="release.title" :title="release.title"
class="thumbnail" class="thumbnail"
>No thumbnail available</div> >No thumbnail available</div>
</router-link> </a>
</span> </span>
<div class="info"> <div class="info">
<router-link <a
:to="`/${release.type || 'scene'}/${release.id}`" :href="`/${release.type || 'scene'}/${release.id}`"
target="_blank"
rel="noopener noreferrer"
class="row link" class="row link"
> >
<h3 <h3
@ -88,7 +92,7 @@
icon="film" icon="film"
/>{{ release.title }} />{{ release.title }}
</h3> </h3>
</router-link> </a>
<span class="row"> <span class="row">
<ul class="actors nolist"> <ul class="actors nolist">

View File

@ -366,10 +366,16 @@
-o-object-position: 50% 0; -o-object-position: 50% 0;
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] { .details[data-v-6989dc6f] {
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
color: #fff; color: #fff;
width: 100%; width: 100%;
height: 1.75rem;
display: -webkit-box; display: -webkit-box;
display: flex; display: flex;
-webkit-box-align: center; -webkit-box-align: center;
@ -1026,55 +1032,63 @@
background: #222; background: #222;
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
width: 100%; width: 100%;
height: 18rem;
display: -webkit-box; display: -webkit-box;
display: flex; display: flex;
-webkit-box-orient: horizontal; -webkit-box-orient: horizontal;
-webkit-box-direction: normal; -webkit-box-direction: normal;
flex-direction: row; flex-direction: row;
flex-shrink: 0; flex-shrink: 0;
padding: 1rem 0 0 0;
} }
.profile .avatar-link[data-v-ea0483c2] { .profile .avatar-link[data-v-ea0483c2] {
font-size: 0; font-size: 0;
padding: 1rem 0 1rem 1rem; padding: 0 0 1rem 1rem;
} }
.profile .avatar[data-v-ea0483c2] { .profile .avatar[data-v-ea0483c2] {
height: 15rem; height: 100%;
width: 12rem;
flex-shrink: 0; flex-shrink: 0;
margin: 0 1rem 0 0; margin: 0 .5rem 0 0;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: 50% 0;
object-position: 50% 0;
} }
.bio[data-v-ea0483c2] { .bio[data-v-ea0483c2] {
-webkit-box-flex: 1; -webkit-box-flex: 1;
flex-grow: 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; box-sizing: border-box;
padding: 1rem; overflow: hidden;
margin: 0 2rem 0 0;
} }
.bio-header[data-v-ea0483c2] { .bio-header[data-v-ea0483c2] {
width: calc(50% - 2rem);
display: -webkit-box; display: -webkit-box;
display: flex; display: flex;
-webkit-box-pack: justify; -webkit-box-pack: justify;
justify-content: space-between; justify-content: space-between;
-webkit-box-align: center; -webkit-box-align: center;
align-items: center; align-items: center;
margin: 0 0 1rem 0; padding: 0 .5rem .5rem 0;
margin: 0 0 0 1rem;
} }
.bio-item[data-v-ea0483c2] { .bio-item[data-v-ea0483c2] {
width: calc(50% - 2rem);
display: -webkit-box; display: -webkit-box;
display: flex; display: flex;
-webkit-box-pack: justify; -webkit-box-pack: justify;
justify-content: space-between; justify-content: space-between;
padding: 0 0 .25rem 0; box-sizing: border-box;
margin: 0 0 .25rem 0; padding: .25rem 0;
margin: 0 0 .25rem 1rem;
line-height: 1.75; line-height: 1.75;
text-align: right; text-align: right;
font-size: .9rem; font-size: .9rem;
font-weight: 600; font-weight: 600;
overflow: hidden;
} }
.bio-item[data-v-ea0483c2]:not(:last-of-type) { .bio-item[data-v-ea0483c2]:not(:last-of-type) {
border-bottom: solid 1px rgba(255, 255, 255, 0.075); border-bottom: solid 1px rgba(255, 255, 255, 0.075);
@ -1148,19 +1162,18 @@
} }
.scraped[data-v-ea0483c2] { .scraped[data-v-ea0483c2] {
color: rgba(255, 255, 255, 0.2); color: rgba(255, 255, 255, 0.2);
margin: 1rem 0 0 0;
font-size: .8rem; font-size: .8rem;
} }
.extra[data-v-ea0483c2] { .extra[data-v-ea0483c2] {
-webkit-box-flex: 1; -webkit-box-flex: 1;
flex-grow: 1; flex-grow: 1;
max-width: 40rem;
} }
.description[data-v-ea0483c2] { .description[data-v-ea0483c2] {
max-height: 12rem; max-height: 12rem;
position: relative; position: relative;
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
padding: 1rem 0 0 0;
margin: 0 2rem 0 0; margin: 0 2rem 0 0;
line-height: 1.5; line-height: 1.5;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -1309,8 +1322,7 @@
} }
.photos.compact .poster[data-v-9d950ba8], .photos.compact .poster[data-v-9d950ba8],
.photos.compact .photo[data-v-9d950ba8] { .photos.compact .photo[data-v-9d950ba8] {
height: 10rem; width: 100%;
width: auto;
margin: 0 1rem 0 0; margin: 0 1rem 0 0;
} }
.poster[data-v-9d950ba8], .poster[data-v-9d950ba8],

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -4,11 +4,11 @@ const tagPosters = Object.entries({
'anal-creampie': ['poster'], 'anal-creampie': ['poster'],
'ass-to-mouth': ['poster', 'Alysa Gap and Logan in "Anal Buffet 4" for Evil Angel'], 'ass-to-mouth': ['poster', 'Alysa Gap and Logan in "Anal Buffet 4" for Evil Angel'],
'da-tp': [0, 'Natasha Teen in LegalPorno SZ2164'], '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-penetration': ['poster', 'Mia Malkova in "DP!" for HardX'],
'double-vaginal': ['poster'], 'double-vaginal': ['poster'],
'dv-tp': ['poster', 'Juelz Ventura in "Gangbanged 5" for Elegant Angel'], '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'], 'triple-anal': ['poster', 'Kristy Black in SZ1986 for LegalPorno'],
airtight: [1, 'Jynx Maze in "Pump My Ass Full of Cum 3" for Jules Jordan'], 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'], anal: ['poster', 'Jynx Maze in "Anal Buffet 6" for Evil Angel'],
@ -26,6 +26,7 @@ const tagPosters = Object.entries({
mff: ['poster'], mff: ['poster'],
mfm: ['poster'], mfm: ['poster'],
orgy: ['poster'], orgy: ['poster'],
schoolgirl: [1, 'Eliza Ibarra for Brazzers'],
swallowing: ['poster'], swallowing: ['poster'],
tattoo: ['poster', 'Kali Roses in "Goes All In For Anal" for Hussie Pass'], tattoo: ['poster', 'Kali Roses in "Goes All In For Anal" for Hussie Pass'],
trainbang: ['poster', 'Kali Roses in "Passing Me Around" for Blacked'], 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', 2, 'Angel Smalls in GIO408 for LegalPorno'],
['da-tp', 3, 'Evelina Darling in GIO294'], ['da-tp', 3, 'Evelina Darling in GIO294'],
['da-tp', 4, 'Ninel Mojado aka Mira Cuckold in GIO063 for LegalPorno'], ['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', 0, 'Nicole Black doing double anal during a gangbang in GIO971 for LegalPorno'],
['double-anal', 1, 'Ria Sunn in SZ1801 for LegalPorno'], ['double-anal', 1, 'Ria Sunn in SZ1801 for LegalPorno'],
['double-penetration', 0], ['double-penetration', 0],
@ -60,6 +62,7 @@ const tagPhotos = [
['trainbang', 0, 'Nicole Black in GIO971 for LegalPorno'], ['trainbang', 0, 'Nicole Black in GIO971 for LegalPorno'],
['triple-anal', 1, 'Natasha Teen in SZ2098 for LegalPorno'], ['triple-anal', 1, 'Natasha Teen in SZ2098 for LegalPorno'],
['triple-anal', 2, 'Kira Thorn in GIO1018 for LegalPorno'], ['triple-anal', 2, 'Kira Thorn in GIO1018 for LegalPorno'],
['oral-creampie', 'poster', 'Khloe Kapri'],
] ]
.map(([slug, fileIndex, comment], index) => ({ .map(([slug, fileIndex, comment], index) => ({
tagSlug: slug, tagSlug: slug,

View File

@ -287,6 +287,7 @@ async function mergeProfiles(profiles, actor) {
birthdate: Number.isNaN(Number(prevProfile.birthdate)) ? profile.birthdate : prevProfile.birthdate, birthdate: Number.isNaN(Number(prevProfile.birthdate)) ? profile.birthdate : prevProfile.birthdate,
birthPlace: prevProfile.birthPlace || profile.birthPlace, birthPlace: prevProfile.birthPlace || profile.birthPlace,
residencePlace: prevProfile.residencePlace || profile.residencePlace, residencePlace: prevProfile.residencePlace || profile.residencePlace,
nationality: prevProfile.nationality || profile.nationality, // used to derive country when not available
ethnicity: prevProfile.ethnicity || profile.ethnicity, ethnicity: prevProfile.ethnicity || profile.ethnicity,
bust: prevProfile.bust || profile.bust, bust: prevProfile.bust || profile.bust,
waist: prevProfile.waist || profile.waist, waist: prevProfile.waist || profile.waist,
@ -316,6 +317,17 @@ async function mergeProfiles(profiles, actor) {
mergedProfile.birthPlace = birthPlace; mergedProfile.birthPlace = birthPlace;
mergedProfile.residencePlace = residencePlace; 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; return mergedProfile;
} }

View File

@ -182,7 +182,8 @@ async function storePhotos(photos, {
concurrency: 10, concurrency: 10,
}).filter(photo => photo); }).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, { const savedPhotos = await savePhotos(hashOriginals, {
domain, domain,

View File

@ -119,17 +119,12 @@ async function scrapeProfile(html, _url, actorName) {
const descriptionEl = document.querySelector('.description-box'); const descriptionEl = document.querySelector('.description-box');
const avatarEl = document.querySelector('.pornstar-details .card-img-top'); 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 = { const profile = {
name: actorName, name: actorName,
}; };
profile.birthdate = moment.utc(bio.Birthday, 'MMMM DD, YYYY').toDate(); 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['Bra size']) [profile.bust] = bio['Bra size'].match(/\d+\w+/);
if (bio.Waist) profile.waist = Number(bio.Waist.match(/\d+/)[0]); if (bio.Waist) profile.waist = Number(bio.Waist.match(/\d+/)[0]);

View File

@ -78,6 +78,11 @@ function scrapeProfile(html, url, actorName, siteSlug) {
const avatarEl = document.querySelector('img.actorPicture'); const avatarEl = document.querySelector('img.actorPicture');
const descriptionEl = document.querySelector('.actorBio p:not(.bioTitle)'); 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 = { const profile = {
name: actorName, name: actorName,
@ -96,6 +101,11 @@ function scrapeProfile(html, url, actorName, siteSlug) {
} }
if (descriptionEl) profile.description = descriptionEl.textContent.trim(); 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}`); profile.releases = Array.from(document.querySelectorAll('.sceneList .scene a.imgLink'), el => `https://${siteSlug}.com${el.href}`);