diff --git a/public/img/logos/private/analintroductions.png b/public/img/logos/private/analintroductions.png new file mode 100644 index 00000000..c63d65d1 Binary files /dev/null and b/public/img/logos/private/analintroductions.png differ diff --git a/public/img/logos/private/blacksonsluts.png b/public/img/logos/private/blacksonsluts.png new file mode 100644 index 00000000..9aadeb84 Binary files /dev/null and b/public/img/logos/private/blacksonsluts.png differ diff --git a/public/img/logos/private/iconfessfiles.png b/public/img/logos/private/iconfessfiles.png new file mode 100644 index 00000000..b3c3a0fa Binary files /dev/null and b/public/img/logos/private/iconfessfiles.png differ diff --git a/public/img/logos/private/missionasspossible.png b/public/img/logos/private/missionasspossible.png new file mode 100644 index 00000000..25595f38 Binary files /dev/null and b/public/img/logos/private/missionasspossible.png differ diff --git a/public/img/logos/private/network.png b/public/img/logos/private/network.png new file mode 100644 index 00000000..f5d3aa32 Binary files /dev/null and b/public/img/logos/private/network.png differ diff --git a/public/img/logos/private/privateblack.png b/public/img/logos/private/privateblack.png new file mode 100644 index 00000000..dd7ba0ae Binary files /dev/null and b/public/img/logos/private/privateblack.png differ diff --git a/public/img/logos/private/privatecastings.png b/public/img/logos/private/privatecastings.png new file mode 100644 index 00000000..860def44 Binary files /dev/null and b/public/img/logos/private/privatecastings.png differ diff --git a/public/img/logos/private/privateclassics.png b/public/img/logos/private/privateclassics.png new file mode 100644 index 00000000..b0223739 Binary files /dev/null and b/public/img/logos/private/privateclassics.png differ diff --git a/public/img/logos/private/privatefetish.png b/public/img/logos/private/privatefetish.png new file mode 100644 index 00000000..bdee3afc Binary files /dev/null and b/public/img/logos/private/privatefetish.png differ diff --git a/public/img/logos/private/privatemilfs.png b/public/img/logos/private/privatemilfs.png new file mode 100644 index 00000000..2593d691 Binary files /dev/null and b/public/img/logos/private/privatemilfs.png differ diff --git a/public/img/logos/private/privatestars.png b/public/img/logos/private/privatestars.png new file mode 100644 index 00000000..fdc21bdb Binary files /dev/null and b/public/img/logos/private/privatestars.png differ diff --git a/public/img/logos/private/russianfakeagent.png b/public/img/logos/private/russianfakeagent.png new file mode 100644 index 00000000..63ffe967 Binary files /dev/null and b/public/img/logos/private/russianfakeagent.png differ diff --git a/public/img/logos/private/russianteenass.png b/public/img/logos/private/russianteenass.png new file mode 100644 index 00000000..09b41e5d Binary files /dev/null and b/public/img/logos/private/russianteenass.png differ diff --git a/public/img/logos/private/sexonthebeach.png b/public/img/logos/private/sexonthebeach.png new file mode 100644 index 00000000..02fa3b58 Binary files /dev/null and b/public/img/logos/private/sexonthebeach.png differ diff --git a/public/img/logos/private/tightandteen.png b/public/img/logos/private/tightandteen.png new file mode 100644 index 00000000..70b703b7 Binary files /dev/null and b/public/img/logos/private/tightandteen.png differ diff --git a/public/img/logos/private/trannytemptation.png b/public/img/logos/private/trannytemptation.png new file mode 100644 index 00000000..0a12a090 Binary files /dev/null and b/public/img/logos/private/trannytemptation.png differ diff --git a/seeds/01_sites.js b/seeds/01_sites.js index 30d8b8ba..2807f8bd 100644 --- a/seeds/01_sites.js +++ b/seeds/01_sites.js @@ -1759,7 +1759,6 @@ function getSites(networksMap) { network_id: networksMap['pervcity'], parameters: JSON.stringify({ tourId: 9 }), }, - // PORN PROS // PRIVATE { slug: 'analintroductions', @@ -1810,6 +1809,13 @@ function getSites(networksMap) { url: 'https://www.private.com/site/blacks-on-sluts', network_id: networksMap['private'], }, + { + slug: 'privateblack', + name: 'Private Black', + description: 'Private Black is number 1 for European Interracial Porn with exclusive interracial content in HD and Ultra 4K featuring the freshest young faces from Europe and the most popular European porn stars.', + url: 'https://www.privateblack.com', + network_id: networksMap['private'], + }, { slug: 'privatefetish', name: 'Private Fetish', diff --git a/seeds/02_tags.js b/seeds/02_tags.js index f0943267..8a82908e 100644 --- a/seeds/02_tags.js +++ b/seeds/02_tags.js @@ -867,6 +867,10 @@ function getTagAliases(tagsMap) { name: 'ball gag', alias_for: tagsMap['gag'], }, + { + name: 'boob fucking', + alias_for: tagsMap['titty-fuck'], + }, { name: 'mfm', alias_for: tagsMap['mfm'], diff --git a/src/fetch-releases.js b/src/fetch-releases.js index b4ecf5fd..b3206af6 100644 --- a/src/fetch-releases.js +++ b/src/fetch-releases.js @@ -128,7 +128,7 @@ async function storeRelease(release) { ? storePhotos(release, releaseEntry) : Promise.resolve(), release.poster ? storePoster(release, releaseEntry) : Promise.resolve(), - release.trailer + release.trailer && release.trailer.src ? storeTrailer(release, releaseEntry) : Promise.resolve(), ]); diff --git a/src/scrapers/brazzers.js b/src/scrapers/brazzers.js index 0940c47b..baa6bc19 100644 --- a/src/scrapers/brazzers.js +++ b/src/scrapers/brazzers.js @@ -75,7 +75,7 @@ async function scrapeScene(html, url, site) { const siteElement = $('.niche-site-logo'); const siteUrl = `https://www.brazzers.com${siteElement.attr('href').slice(0, -1)}`; const siteName = siteElement.attr('title'); - const siteSlug = siteName.replace(/\s+/g, ''); + const siteSlug = siteName.replace(/\s+/g, '').toLowerCase(); const rawTags = $('.tag-card-container a').map((tagIndex, tagElement) => $(tagElement).text()).toArray(); @@ -85,7 +85,13 @@ async function scrapeScene(html, url, site) { const [tags, channelSite] = await Promise.all([ matchTags(rawTags), - site.isFallback ? fetchSites(null, siteSlug, siteName, siteUrl) : site, + site.isFallback + ? [fetchSites({ + slug: siteSlug, + name: siteName, + url: siteUrl, + })] + : site, ]); return { diff --git a/src/scrapers/private.js b/src/scrapers/private.js index 59711eb7..4a60e633 100644 --- a/src/scrapers/private.js +++ b/src/scrapers/private.js @@ -5,11 +5,13 @@ const bhttp = require('bhttp'); const cheerio = require('cheerio'); const moment = require('moment'); -const knex = require('../knex'); +const fetchSites = require('../sites'); const { matchTags } = require('../tags'); -async function getPhotos(shootId) { - const res = await bhttp.get(`https://www.private.com/gallery.php?type=highres&id=${shootId}`); +async function getPhotos(shootId, site) { + const { hostname } = new URL(site.url); + + const res = await bhttp.get(`https://${hostname}/gallery.php?type=highres&id=${shootId}`); const html = res.body.toString(); const $ = cheerio.load(html, { normalizeWhitespace: true }); @@ -18,28 +20,49 @@ async function getPhotos(shootId) { return photos; } +async function getChannelSite($, site) { + const { hostname } = new URL(site.url); + + if (site.isFallback && hostname.match('private.com')) { + const siteElement = $('.content-wrapper .logos-sites a'); + const siteUrl = siteElement.attr('href').slice(0, -1); + const siteName = siteElement.text(); + const siteSlug = siteName.replace(/\s+/g, '').toLowerCase(); + + const channelSite = await fetchSites({ + slug: siteSlug, + name: siteName, + url: siteUrl, + }); + + return channelSite; + } + + return site; +} + function scrapeLatest(html, site) { const $ = cheerio.load(html, { normalizeWhitespace: true }); - const sceneElements = $('.content-wrapper.container .scene').toArray(); + const sceneElements = $('.content-wrapper .scene').toArray(); return sceneElements.map((element) => { - const sceneLinkElement = $(element).find('a[data-track="TITLE_LINK"]'); + const sceneLinkElement = $(element).find('h3 a'); const url = sceneLinkElement.attr('href'); const title = sceneLinkElement.text(); const shootId = url.split('/').slice(-1)[0]; - const thumbnailElement = $(element).find('img.thumbs_onhover'); + const date = moment.utc($(element).find('.scene-date'), 'MM/DD/YYYY').toDate(); + + const actors = $(element).find('.scene-models a').map((actorIndex, actorElement) => $(actorElement).text()).toArray(); + const likes = Number($(element).find('.scene-votes').text()); + + const thumbnailElement = $(element).find('img.img-responsive'); const photoCount = Number(thumbnailElement.attr('thumbs_num')); const poster = thumbnailElement.attr('src'); const photos = Array.from({ length: photoCount }, (val, index) => thumbnailElement.attr(`src${index + 1}`)); - const date = moment.utc($(element).find('.scene-date'), 'MM/DD/YYYY').toDate(); - - const actors = $(element).find('a[data-track="PORNSTAR_LINK"]').map((actorIndex, actorElement) => $(actorElement).text()).toArray(); - const likes = Number($(element).find('.scene-votes').text()); - - return { + const scene = { url, shootId, title, @@ -52,6 +75,8 @@ function scrapeLatest(html, site) { }, site, }; + + return scene; }); } @@ -70,25 +95,18 @@ async function scrapeScene(html, url, site) { const poster = $('meta[property="og:image"]').attr('content'); const trailer = $('meta[property="og:video"]').attr('content'); - const photos = await getPhotos(shootId); const likes = Number($('.content-desc #social-actions #likes').text()); - const siteElement = $('.content-wrapper .logos-sites a'); - const siteUrl = siteElement.attr('href').slice(0, -1); - const siteName = siteElement.text(); - const rawTags = $('.content-desc .scene-tags a').map((tagIndex, tagElement) => $(tagElement).text()).toArray(); - const [tags, channelSite] = await Promise.all([ + const [tags, photos, channelSite] = await Promise.all([ matchTags(rawTags), - knex('sites') - .where({ url: siteUrl }) - .orWhere({ name: siteName }) - .first(), + getPhotos(shootId, site), + getChannelSite($, site), ]); - return { + const scene = { url, shootId, title, @@ -107,10 +125,20 @@ async function scrapeScene(html, url, site) { }, site: channelSite || site, }; + + return scene; } async function fetchLatest(site, page = 1) { - const res = await bhttp.get(`${site.url}/${page}/`); + const { hostname } = new URL(site.url); + + if (hostname.match('private.com')) { + const res = await bhttp.get(`${site.url}/${page}/`); + + return scrapeLatest(res.body.toString(), site); + } + + const res = await bhttp.get(`${site.url}/scenes/${page}/`); return scrapeLatest(res.body.toString(), site); }