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>
</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;

View File

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

View File

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

View File

@ -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;

View File

@ -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">

View File

@ -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],

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'],
'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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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]);

View File

@ -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}`);