diff --git a/assets/components/actors/actor.vue b/assets/components/actors/actor.vue index 90555cec..dc807568 100644 --- a/assets/components/actors/actor.vue +++ b/assets/components/actors/actor.vue @@ -243,10 +243,33 @@ @click="expanded = true" > -

{{ actor.description }}

+
+
+

+ {{ description.text }} + + + + + +

+
+
profile.avatar) .filter(avatar => avatar && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash)); + const descriptions = actor.profiles.reduce((acc, profile) => ({ + ...acc, + ...(profile.description && { + [profile.descriptionHash]: { + text: profile.description, + network: profile.network, + site: profile.site, + }, + }), + }), {}); + curatedActor.photos = Object.values(photos.reduce((acc, photo) => ({ ...acc, [photo.hash]: photo }), {})); + curatedActor.descriptions = Object.values(descriptions); } if (release && release.date && curatedActor.birthdate) { diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index 1d7fd38f..38836a36 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -349,12 +349,13 @@ exports.up = knex => Promise.resolve() .defaultTo(1); table.string('real_name'); + table.string('gender', 18); table.date('date_of_birth'); table.date('date_of_death'); - table.string('gender', 18); table.text('description'); + table.string('description_hash'); table.string('birth_city'); table.string('birth_state'); diff --git a/package-lock.json b/package-lock.json index cb314521..74c6e730 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3401,6 +3401,11 @@ "domelementtype": "1" } }, + "dompurify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.11.tgz", + "integrity": "sha512-qVoGPjIW9IqxRij7klDQQ2j6nSe4UNWANBhZNLnsS7ScTtLb+3YdxkRY8brNTpkUiTtcXsCJO+jS0UCDfenLuA==" + }, "domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", diff --git a/package.json b/package.json index bacd4174..e17dad37 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "config": "^3.2.5", "csv-stringify": "^5.3.6", "dayjs": "^1.8.21", + "dompurify": "^2.0.11", "ejs": "^3.0.1", "express": "^4.17.1", "express-promise-router": "^3.0.3", diff --git a/public/img/tags/airtight/6.jpeg b/public/img/tags/airtight/6.jpeg index edf6917a..e3221224 100644 Binary files a/public/img/tags/airtight/6.jpeg and b/public/img/tags/airtight/6.jpeg differ diff --git a/public/img/tags/airtight/lazy/6.jpeg b/public/img/tags/airtight/lazy/6.jpeg index 9f7b9070..1ce0070f 100644 Binary files a/public/img/tags/airtight/lazy/6.jpeg and b/public/img/tags/airtight/lazy/6.jpeg differ diff --git a/public/img/tags/airtight/thumbs/6.jpeg b/public/img/tags/airtight/thumbs/6.jpeg index 4825e3da..524ca151 100644 Binary files a/public/img/tags/airtight/thumbs/6.jpeg and b/public/img/tags/airtight/thumbs/6.jpeg differ diff --git a/public/img/tags/double-dildo/0.jpeg b/public/img/tags/double-dildo/0.jpeg new file mode 100644 index 00000000..e4b7c9c1 Binary files /dev/null and b/public/img/tags/double-dildo/0.jpeg differ diff --git a/public/img/tags/double-dildo/lazy/0.jpeg b/public/img/tags/double-dildo/lazy/0.jpeg new file mode 100644 index 00000000..e3f23e63 Binary files /dev/null and b/public/img/tags/double-dildo/lazy/0.jpeg differ diff --git a/public/img/tags/double-dildo/thumbs/0.jpeg b/public/img/tags/double-dildo/thumbs/0.jpeg new file mode 100644 index 00000000..1fa0dc6c Binary files /dev/null and b/public/img/tags/double-dildo/thumbs/0.jpeg differ diff --git a/public/img/tags/facefucking/3.jpeg b/public/img/tags/facefucking/3.jpeg new file mode 100644 index 00000000..ded53393 Binary files /dev/null and b/public/img/tags/facefucking/3.jpeg differ diff --git a/public/img/tags/facefucking/lazy/3.jpeg b/public/img/tags/facefucking/lazy/3.jpeg new file mode 100644 index 00000000..a3081e72 Binary files /dev/null and b/public/img/tags/facefucking/lazy/3.jpeg differ diff --git a/public/img/tags/facefucking/thumbs/3.jpeg b/public/img/tags/facefucking/thumbs/3.jpeg new file mode 100644 index 00000000..88cbc1be Binary files /dev/null and b/public/img/tags/facefucking/thumbs/3.jpeg differ diff --git a/public/img/tags/femdom/0.jpeg b/public/img/tags/femdom/0.jpeg new file mode 100644 index 00000000..d488e9c0 Binary files /dev/null and b/public/img/tags/femdom/0.jpeg differ diff --git a/public/img/tags/femdom/lazy/0.jpeg b/public/img/tags/femdom/lazy/0.jpeg new file mode 100644 index 00000000..4570f1e7 Binary files /dev/null and b/public/img/tags/femdom/lazy/0.jpeg differ diff --git a/public/img/tags/femdom/thumbs/0.jpeg b/public/img/tags/femdom/thumbs/0.jpeg new file mode 100644 index 00000000..e683832a Binary files /dev/null and b/public/img/tags/femdom/thumbs/0.jpeg differ diff --git a/seeds/04_media.js b/seeds/04_media.js index 694be2fc..5cc729c8 100644 --- a/seeds/04_media.js +++ b/seeds/04_media.js @@ -22,6 +22,7 @@ const tagPosters = [ ['deepthroat', 0, 'Chanel Grey in "Deepthroating Is Fun" for Throated'], ['double-anal', 7, 'Adriana Chechik in "DP Masters 6" for Jules Jordan'], ['double-blowjob', 1, 'Veronica Rodriguez and Penny Pax in "Fucking Older Guys 5" for Penthouse'], + ['double-dildo', 0, 'Kali Roses in "Double Dildo Party" for KaliRoses.com'], ['double-dildo-blowjob', 0, 'Adriana Chechik and Vicki Chase in "Anal Savages 1" for Jules Jordan'], ['double-penetration', 2, 'Megan Rain in "DP Masters 4" for Jules Jordan'], ['double-vaginal', 'poster', 'Riley Reid in "Pizza That Ass" for Reid My Lips'], @@ -31,6 +32,7 @@ const tagPosters = [ ['facial', 0, 'Brooklyn Gray in "All About Ass 4" for Evil Angel'], ['fake-boobs', 1, 'Lela Star in "Thick" for Jules Jordan'], ['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'], ['interracial', 0, 'Jaye Summers and Prince Yahshua in "Platinum Pussy 3" for Jules Jordan'], @@ -100,6 +102,7 @@ const tagPhotos = [ ['dv-tp', 0, 'Luna Rival in LegalPorno SZ1490'], ['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', 0, 'Marsha May in "Once You Go Black 7" for Jules Jordan'], ['gangbang', 'poster', 'Kristen Scott in "Interracial Gangbang!" for Jules Jordan'], diff --git a/src/actors.js b/src/actors.js index 50129a50..84291c6d 100644 --- a/src/actors.js +++ b/src/actors.js @@ -3,6 +3,12 @@ const config = require('config'); const Promise = require('bluebird'); const moment = require('moment'); +const blake2 = require('blake2'); +const DOMPurify = require('dompurify'); +const { JSDOM } = require('jsdom'); + +const { window } = new JSDOM(''); +const domPurify = DOMPurify(window); // const logger = require('./logger')(__filename); const knex = require('./knex'); @@ -148,6 +154,7 @@ function curateProfileEntry(profile) { gender: profile.gender, ethnicity: profile.ethnicity, description: profile.description, + description_hash: profile.descriptionHash, birth_city: profile.placeOfBirth?.city || null, birth_state: profile.placeOfBirth?.state || null, birth_country_alpha2: profile.placeOfBirth?.country || null, @@ -189,7 +196,14 @@ async function curateProfile(profile) { update: profile.update, }; - curatedProfile.description = profile.description?.trim() || null; + curatedProfile.description = domPurify.sanitize(profile.description, { ALLOWED_TAGS: [] }).trim() || null; + + const hasher = curatedProfile.description && blake2 + .createHash('blake2b') + .update(Buffer.from(slugify(curatedProfile.description))); + + curatedProfile.descriptionHash = curatedProfile.description && hasher.digest('hex'); + curatedProfile.nationality = profile.nationality?.trim() || null; // used to derive country when country not available curatedProfile.ethnicity = ethnicities[profile.ethnicity?.trim().toLowerCase()] || null; diff --git a/src/scrapers/bang.js b/src/scrapers/bang.js index 46811fe9..e9bcde07 100644 --- a/src/scrapers/bang.js +++ b/src/scrapers/bang.js @@ -39,9 +39,8 @@ function decodeId(id) { .toString('hex'); } -function scrapeScene(scene, site) { +function scrapeScene(scene) { const release = { - site, entryId: scene.id, title: scene.name, description: scene.description, @@ -80,11 +79,11 @@ function scrapeScene(scene, site) { return release; } -function scrapeAll(scenes, site) { - return scenes.map(({ _source: scene }) => scrapeScene(scene, site)); +function scrapeAll(scenes) { + return scenes.map(({ _source: scene }) => scrapeScene(scene)); } -async function fetchActorReleases(actor, site) { +async function fetchActorReleases(actor) { const res = await bhttp.post(`https://${clusterId}.us-east-1.aws.found.io/videos/video/_search`, { size: 50, query: { @@ -138,11 +137,10 @@ async function fetchActorReleases(actor, site) { }, }); - return scrapeAll(res.body.hits.hits, site); + return scrapeAll(res.body.hits.hits); } - -async function scrapeProfile(actor, site, include) { +async function scrapeProfile(actor, include) { const profile = {}; profile.aliases = actor.aliases; @@ -174,7 +172,7 @@ async function scrapeProfile(actor, site, include) { if (actor.image) profile.avatar = `https://i.bang.com/pornstars/${actor.identifier}.jpg`; if (include.releases) { - profile.releases = await fetchActorReleases(actor, site); + profile.releases = await fetchActorReleases(actor); } return profile; @@ -267,7 +265,7 @@ async function fetchLatest(site, page = 1) { return scrapeAll(res.body.hits.hits, site); } -async function fetchScene(url, site) { +async function fetchScene(url) { const encodedId = new URL(url).pathname.split('/')[2]; const entryId = decodeId(encodedId); @@ -277,10 +275,10 @@ async function fetchScene(url, site) { }, }); - return scrapeScene(res.body._source, site); // eslint-disable-line no-underscore-dangle + return scrapeScene(res.body._source); // eslint-disable-line no-underscore-dangle } -async function fetchProfile(actorName, actorSlug, site, include) { +async function fetchProfile(actorName, context, include) { const res = await post(`https://${clusterId}.us-east-1.aws.found.io/actors/actor/_search`, { size: 5, sort: [{ @@ -315,7 +313,7 @@ async function fetchProfile(actorName, actorSlug, site, include) { const actor = res.body.hits.hits.find(hit => hit._source.name.toLowerCase() === actorName.toLowerCase()); if (actor) { - return scrapeProfile(actor._source, site, include); + return scrapeProfile(actor._source, include); } return null; diff --git a/src/scrapers/famedigital.js b/src/scrapers/famedigital.js index 97edf33c..531d3856 100644 --- a/src/scrapers/famedigital.js +++ b/src/scrapers/famedigital.js @@ -91,8 +91,8 @@ async function fetchClassicProfile(actorName, { site }) { } async function networkFetchProfile(actorName, context, include) { - const profile = await ((context.site.parameters.api && fetchApiProfile(actorName, context, include)) - || (context.site.parameters.classic && include.scenes && fetchClassicProfile(actorName, context, include)) // classic profiles only have scenes, no bio + const profile = await ((context.site.parameters?.api && fetchApiProfile(actorName, context, include)) + || (context.site.parameters?.classic && include.scenes && fetchClassicProfile(actorName, context, include)) // classic profiles only have scenes, no bio || fetchProfile(actorName, context, true, getActorReleasesUrl, include)); return profile;