From 21d4dd6bfaa336c1b7726944b8ce02336a3d967e Mon Sep 17 00:00:00 2001 From: Niels Simenon Date: Fri, 15 May 2020 04:40:59 +0200 Subject: [PATCH] Scraping and storing actor profiles. --- assets/js/actors/actions.js | 4 +- assets/js/fragments.js | 2 +- migrations/20190325001339_releases.js | 17 +- .../modelcentro/misc/spank-monster_tld.png | Bin 0 -> 30121 bytes public/img/logos/modelcentro/spankmonster.png | Bin 0 -> 27979 bytes src/actors.js | 240 +++++++++++++++++- src/deep.js | 1 + src/utils/posters.js | 41 ++- src/utils/resolve-place.js | 31 ++- 9 files changed, 311 insertions(+), 25 deletions(-) create mode 100644 public/img/logos/modelcentro/misc/spank-monster_tld.png create mode 100644 public/img/logos/modelcentro/spankmonster.png diff --git a/assets/js/actors/actions.js b/assets/js/actors/actions.js index ee2de9c9..91bf3fa0 100644 --- a/assets/js/actors/actions.js +++ b/assets/js/actors/actions.js @@ -76,7 +76,7 @@ function initActorActions(store, _router) { name slug gender - birthdate + birthdate: dateOfBirth age ethnicity bust @@ -229,7 +229,7 @@ function initActorActions(store, _router) { name slug age - birthdate + birthdate: dateOfBirth gender network { id diff --git a/assets/js/fragments.js b/assets/js/fragments.js index d89c7bdc..420519e9 100644 --- a/assets/js/fragments.js +++ b/assets/js/fragments.js @@ -34,7 +34,7 @@ const actorFields = ` id name slug - birthdate + birthdate: dateOfBirth age gender network { diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index 043c8add..fcdf76e8 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -272,7 +272,9 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('actors'); - table.date('birthdate'); + table.date('date_of_birth'); + table.date('date_of_death'); + table.string('gender', 18); table.text('description'); @@ -290,7 +292,8 @@ exports.up = knex => Promise.resolve() table.string('ethnicity'); - table.string('bust', 10); + table.string('cup', 4); + table.integer('bust', 3); table.integer('waist', 3); table.integer('hip', 3); table.boolean('natural_boobs'); @@ -330,10 +333,11 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('sites'); - table.unique(['actor_id', 'network_id']); - table.unique(['actor_id', 'site_id']); + table.unique(['actor_id', 'network_id', 'site_id']); + + table.date('date_of_birth'); + table.date('date_of_death'); - table.date('birthdate'); table.string('gender', 18); table.text('description'); @@ -351,7 +355,8 @@ exports.up = knex => Promise.resolve() table.string('ethnicity'); - table.string('bust', 10); + table.string('cup', 4); + table.integer('bust', 3); table.integer('waist', 3); table.integer('hip', 3); table.boolean('natural_boobs'); diff --git a/public/img/logos/modelcentro/misc/spank-monster_tld.png b/public/img/logos/modelcentro/misc/spank-monster_tld.png new file mode 100644 index 0000000000000000000000000000000000000000..d71d476f090ed4c79bdb8ee95a3618c2401d2ab7 GIT binary patch literal 30121 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 literal 0 HcmV?d00001 diff --git a/public/img/logos/modelcentro/spankmonster.png b/public/img/logos/modelcentro/spankmonster.png new file mode 100644 index 0000000000000000000000000000000000000000..1f91af7af0064bd7fd1c27e3a469729d81510d29 GIT binary patch literal 27979 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 { @@ -46,6 +51,224 @@ function curateActorEntries(baseActors, batchId) { return baseActors.map(baseActor => curateActorEntry(baseActor, batchId)); } +function curateProfileEntry(profile) { + const curatedProfileEntry = { + actor_id: profile.id, + site_id: profile.site?.id || null, + network_id: profile.network?.id || null, + date_of_birth: profile.dateOfBirth, + date_of_death: profile.dateOfDeath, + gender: profile.gender, + ethnicity: profile.ethnicity, + description: profile.description, + birth_city: profile.placeOfBirth?.city || null, + birth_state: profile.placeOfBirth?.state || null, + birth_country_alpha2: profile.placeOfBirth?.country?.alpha2 || null, + residence_city: profile.placeOfResidence?.city || null, + residence_state: profile.placeOfResidence?.state || null, + residence_country_alpha2: profile.placeOfResidence?.country?.alpha2 || null, + cup: profile.cup, + bust: profile.bust, + waist: profile.waist, + hip: profile.hip, + natural_boobs: profile.naturalBoobs, + height: profile.height, + weight: profile.weight, + hair: profile.hair, + eyes: profile.eyes, + has_tattoos: profile.hasTattoos, + has_piercings: profile.hasPiercings, + piercings: profile.piercings, + tattoos: profile.tattoos, + }; + + return curatedProfileEntry; +} + +async function curateProfile(profile) { + try { + const curatedProfile = { + id: profile.id, + name: profile.name, + avatar: profile.avatar, + }; + + curatedProfile.site = profile.site.isNetwork ? null : profile.site; + curatedProfile.network = profile.site.isNetwork ? profile.site : null; + + curatedProfile.description = profile.description?.trim() || null; + curatedProfile.nationality = profile.nationality?.trim() || null; // used to derive country when country not available + curatedProfile.ethnicity = profile.ethnicity?.trim() || null; + curatedProfile.hair = profile.hair?.trim() || null; + curatedProfile.eyes = profile.eyes?.trim() || null; + curatedProfile.tattoos = profile.tattoos?.trim() || null; + curatedProfile.piercings = profile.piercings?.trim() || null; + + curatedProfile.gender = (/female/i.test(profile.gender) && 'female') + || (/shemale/i.test(profile.gender) && 'transsexual') + || (/male/i.test(profile.gender) && 'male') + || (/trans/i.test(profile.gender) && 'transsexual') + || null; + + curatedProfile.dateOfBirth = (!Number.isNaN(Number(profile.dateOfBirth || profile.birthdate)) // possibly valid date + && new Date() - profile.birthdate > 567648000000 // over 18 + && profile.birthdate) + || null; + + curatedProfile.dateOfDeath = Number.isNaN(Number(profile.dateOfDeath)) ? null : profile.dateOfDeath; + + curatedProfile.cup = profile.cup || profile.bust?.match(/[a-zA-Z]+/)?.[0] || null; + curatedProfile.bust = Number(profile.bust) || profile.bust?.match(/\d+/)?.[0] || null; + curatedProfile.waist = Number(profile.waist) || profile.waist?.match(/\d+/)?.[0] || null; + curatedProfile.hip = Number(profile.hip) || profile.hip?.match(/\d+/)?.[0] || null; + curatedProfile.height = Number(profile.height) || profile.height?.match(/\d+/)?.[0] || null; + curatedProfile.weight = Number(profile.weight) || profile.weight?.match(/\d+/)?.[0] || null; + + curatedProfile.naturalBoobs = typeof profile.naturalBoobs === 'boolean' ? profile.naturalBoobs : null; + curatedProfile.hasTattoos = typeof profile.hasTattoos === 'boolean' ? profile.hasTattoos : null; + curatedProfile.hasPiercings = typeof profile.hasPiercings === 'boolean' ? profile.hasPiercings : null; + + const [placeOfBirth, placeOfResidence] = await Promise.all([ + resolvePlace(profile.birthPlace), + resolvePlace(profile.residencePlace), + ]); + + curatedProfile.placeOfBirth = placeOfBirth; + curatedProfile.placeOfResidence = placeOfResidence; + + if (!curatedProfile.placeOfBirth && curatedProfile.nationality) { + const country = await knex('countries') + .where('nationality', 'ilike', `%${curatedProfile.nationality}%`) + .orderBy('priority', 'desc') + .first(); + + curatedProfile.placeOfBirth = { + country: country.alpha2, + }; + } + + curatedProfile.social = Array.isArray(profile.social) + ? profile.social.map((social) => { + try { + const { href } = new URL(); + return href; + } catch (error) { + logger.warn(`Profile scraper for '${profile.site.name}' returned invalid social link: ${social}`); + return null; + } + }).filter(Boolean) + : []; + + curatedProfile.releases = toBaseReleases(profile.releases); + + return curatedProfile; + } catch (error) { + logger.error(`Failed to curate '${profile.name}': ${error.message}`); + + return null; + } +} + +async function scrapeProfiles(actor, sources, networksBySlug, sitesBySlug) { + const profiles = Promise.map(sources, async (source) => { + try { + return await [].concat(source).reduce(async (outcome, scraperSlug) => outcome.catch(async () => { + const scraper = scrapers[scraperSlug]; + const siteOrNetwork = networksBySlug[scraperSlug] || sitesBySlug[scraperSlug]; + + if (!scraper?.fetchProfile) { + logger.warn(`No profile profile scraper available for ${scraperSlug}`); + throw new Error(`No profile profile scraper available for ${scraperSlug}`); + } + + if (!siteOrNetwork) { + logger.warn(`No site or network found for ${scraperSlug}`); + throw new Error(`No site or network found for ${scraperSlug}`); + } + + logger.verbose(`Searching profile for '${actor.name}' on '${scraperSlug}'`); + + const profile = await scraper.fetchProfile(actor.name, scraperSlug, siteOrNetwork, include); + + if (!profile || typeof profile === 'number') { // scraper returns HTTP code on request failure + logger.verbose(`Profile for '${actor.name}' not available on ${scraperSlug}, scraper returned ${profile}`); + throw Object.assign(new Error(`Profile for '${actor.name}' not available on ${scraperSlug}`), { code: 'PROFILE_NOT_AVAILABLE' }); + } + + return { + ...actor, + ...profile, + site: siteOrNetwork, + }; + }), Promise.reject(new Error())); + } catch (error) { + if (error.code !== 'PROFILE_NOT_AVAILABLE') { + logger.error(`Failed to fetch profile for '${actor.name}': ${error.message}`); + } + } + + return null; + }); + + return profiles.filter(Boolean); +} + +async function upsertProfiles(curatedProfileEntries) { + const existingProfiles = await knex('actors_profiles') + .whereIn(['actor_id', 'network_id'], curatedProfileEntries.map(entry => [entry.actor_id, entry.network_id])) + .orWhereIn(['actor_id', 'site_id'], curatedProfileEntries.map(entry => [entry.actor_id, entry.site_id])); + + const existingProfilesByActorNetworkSiteIds = existingProfiles.reduce((acc, profile) => ({ + ...acc, + [profile.actor_id]: { + ...acc[profile.actor_id], + [profile.network_id]: { + ...acc[profile.actor_id]?.[profile.network_id], + [profile.site_id]: profile, + }, + }, + }), {}); + + const { updatingProfileEntries, newProfileEntries } = curatedProfileEntries.reduce((acc, profile) => { + const existingProfile = existingProfilesByActorNetworkSiteIds[profile.actor_id]?.[profile.network_id]?.[profile.site_id]; + + if (existingProfile) { + return { + ...acc, + updatingProfileEntries: [...acc.updatingProfileEntries, { + ...profile, + id: existingProfile.id, + }], + }; + } + + return { + ...acc, + newProfileEntries: [...acc.newProfileEntries, profile], + }; + }, { + updatingProfileEntries: [], + newProfileEntries: [], + }); + + if (newProfileEntries.length > 0) { + await knex('actors_profiles').insert(newProfileEntries); + } + + if (argv.force && updatingProfileEntries.length > 0) { + knex.transaction(async (transaction) => { + const queries = updatingProfileEntries.map(profileEntry => knex('actors_profiles') + .where('id', profileEntry.id) + .update(profileEntry) + .transacting(transaction)); + + return Promise.all(queries) + .then(transaction.commit) + .catch(transaction.rollback); + }); + } +} + async function scrapeActors(actorNames) { const baseActors = toBaseActors(actorNames); @@ -71,9 +294,20 @@ async function scrapeActors(actorNames) { const curatedActorEntries = batchId && curateActorEntries(newBaseActors, batchId); const newActorEntries = batchId && await knex('actors').insert(curatedActorEntries).returning(['id', 'name', 'slug']); - const actorEntries = existingActorEntries.concat(Array.isArray(newActorEntries) ? newActorEntries : []); + const actors = existingActorEntries.concat(Array.isArray(newActorEntries) ? newActorEntries : []); - console.log(actorEntries, newActorEntries, actorEntries); + // TODO: don't fetch existing profiles unless --force is used + + const profilesPerActor = await Promise.map( + actors, + async actor => scrapeProfiles(actor, sources, networksBySlug, sitesBySlug), + { concurrency: 10 }, + ); + + const profiles = await Promise.all(profilesPerActor.flat().map(profile => curateProfile(profile))); + const curatedProfileEntries = profiles.map(profile => curateProfileEntry(profile)); + + await upsertProfiles(curatedProfileEntries); } async function getOrCreateActors(baseActors, batchId) { diff --git a/src/deep.js b/src/deep.js index c648e6cf..c862bf85 100644 --- a/src/deep.js +++ b/src/deep.js @@ -167,4 +167,5 @@ module.exports = { fetchReleases, fetchScenes, fetchMovies, + toBaseReleases, }; diff --git a/src/utils/posters.js b/src/utils/posters.js index 541aec0f..178af2c6 100644 --- a/src/utils/posters.js +++ b/src/utils/posters.js @@ -8,10 +8,10 @@ const moment = require('moment'); const argv = require('../argv'); const knex = require('../knex'); -async function init() { +async function actorPosters(actorNames) { const posters = await knex('actors') .select('actors.name as actor_name', 'releases.title', 'releases.date', 'media.path', 'media.index', 'sites.name as site_name', 'networks.name as network_name') - .whereIn('actors.name', (argv.actors || []).concat(argv._)) + .whereIn('actors.name', actorNames) .join('releases_actors', 'releases_actors.actor_id', 'actors.id') .join('releases', 'releases_actors.release_id', 'releases.id') .join('sites', 'sites.id', 'releases.site_id') @@ -37,4 +37,41 @@ async function init() { knex.destroy(); } +async function sitePosters(siteSlugs) { + const posters = await knex('sites') + .select('sites.name as site_name', 'releases.title', 'releases.date', 'media.path') + .whereIn('sites.slug', siteSlugs) + .join('releases', 'releases.site_id', 'sites.id') + .join('releases_posters', 'releases_posters.release_id', 'releases.id') + .join('media', 'releases_posters.media_id', 'media.id'); + // .where('releases.date', '<', '2020-01-01'); + + const files = await Promise.all(posters.map(async (poster) => { + const directory = path.join(config.media.path, 'extracted', poster.site_name); + + const source = path.join(config.media.path, poster.path); + const target = path.join(directory, `${poster.site_name} - ${moment.utc(poster.date).format('YYYY-MM-DD')} - ${poster.title.replace(/[/.]/g, '_')}.jpeg`); + + await fs.mkdir(directory, { recursive: true }); + await fs.copyFile(source, target); + + return target; + })); + + console.log(files); + + knex.destroy(); +} + +async function init() { + if (argv.actors) { + await actorPosters(argv.actors); + return; + } + + if (argv.sites) { + await sitePosters(argv.sites); + } +} + init(); diff --git a/src/utils/resolve-place.js b/src/utils/resolve-place.js index 7470e872..e572f38b 100644 --- a/src/utils/resolve-place.js +++ b/src/utils/resolve-place.js @@ -1,25 +1,34 @@ 'use strict'; -const bhttp = require('bhttp'); +const logger = require('../logger')(__filename); +const http = require('./http'); async function resolvePlace(query) { if (!query) { return null; } - const res = await bhttp.get(`https://nominatim.openstreetmap.org/search/${encodeURI(query)}?format=json&accept-language=en&addressdetails=1`); - const [item] = res.body; + try { + // https://operations.osmfoundation.org/policies/nominatim/ + const res = await http.get(`https://nominatim.openstreetmap.org/search/${encodeURI(query)}?format=json&accept-language=en&addressdetails=1`, { + 'User-Agent': 'contact at moonloop.adult@protonmail.com', + }); - if (item && item.address) { - const rawPlace = item.address; - const place = {}; + const [item] = res.body; - if (rawPlace.city) place.city = rawPlace.city; - if (rawPlace.state) place.state = rawPlace.state; - if (rawPlace.country_code) place.country = rawPlace.country_code.toUpperCase(); - if (rawPlace.continent) place.continent = rawPlace.continent; + if (item && item.address) { + const rawPlace = item.address; + const place = {}; - return place; + if (rawPlace.city) place.city = rawPlace.city; + if (rawPlace.state) place.state = rawPlace.state; + if (rawPlace.country_code) place.country = rawPlace.country_code.toUpperCase(); + if (rawPlace.continent) place.continent = rawPlace.continent; + + return place; + } + } catch (error) { + logger.error(`Failed to resolve place '${query}': ${error.message}`); } return null;