From 85e55eebaf82306affd9dde51213dd740ecd53ff Mon Sep 17 00:00:00 2001 From: Niels Simenon Date: Tue, 10 Dec 2019 05:10:08 +0100 Subject: [PATCH] Added Kelly Madison Media (Teen Fidelity) release scraper. --- .../img/logos/kellymadison/kellymadison.png | Bin 0 -> 8804 bytes public/img/logos/kellymadison/network.png | Bin 0 -> 8804 bytes .../img/logos/kellymadison/pornfidelity.png | Bin 0 -> 6838 bytes .../img/logos/kellymadison/teenfidelity.png | Bin 0 -> 6549 bytes seeds/00_networks.js | 6 + seeds/01_sites.js | 22 +++ src/media.js | 6 +- src/scrape-release.js | 2 +- src/scrape-sites.js | 2 + src/scrapers/kellymadison.js | 147 ++++++++++++++++++ src/scrapers/scrapers.js | 2 + src/tags.js | 2 +- src/utils/pluck-photos.js | 9 +- 13 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 public/img/logos/kellymadison/kellymadison.png create mode 100644 public/img/logos/kellymadison/network.png create mode 100644 public/img/logos/kellymadison/pornfidelity.png create mode 100644 public/img/logos/kellymadison/teenfidelity.png create mode 100644 src/scrapers/kellymadison.js diff --git a/public/img/logos/kellymadison/kellymadison.png b/public/img/logos/kellymadison/kellymadison.png new file mode 100644 index 0000000000000000000000000000000000000000..ff73dde33effbac8fe943db9672440fb51ff8ec3 GIT binary patch literal 8804 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 literal 0 HcmV?d00001 diff --git a/public/img/logos/kellymadison/teenfidelity.png b/public/img/logos/kellymadison/teenfidelity.png new file mode 100644 index 0000000000000000000000000000000000000000..44f8b53b7aa3a4bc820f8cba73c9a31817bd57a4 GIT binary patch literal 6549 zcmXX~2Urtn6HW;2sK!DSP^$Ejqc;%{0#YuBfYgIfr6au;C3Fcbp?Xr3E+9=xf*=S) zQHpeeC_#!qsG$h|a`)$XlHF&syYtS>JMYZ*C7BxQF*9&6fIuK-xV{bo1cGz}=K=Jz zz%Oob;Q#~zC%9{Co5HoVZ}|HAxVU>dgFv@3BQw?Ydv9NVZ*Qh6dW}vMg+jhEX4BE_ zgIAj-F#PktZKCJLsI=SYv$8fNhB_KLO}1(lsZVcJ+8E*%=};-vSuawuDY&xF{QdFY zqdGed+rsJS_vOZF(q(UtdBJi}DcFswsr_V`JC|eej?xq)&P?O7g=0-0gZhmhV3QcKxP}fLOKVs}vj&#PZ|4EmL=g+;Nl@KRpaI5!j z>Vu-IjG{9cClopxoQ~8J8zC8giRVx|8_#qYr1aAU1<|*eZr;9spnLm)Y(fH(s=;*J6i!7$eVA-e z4kf>AkPsUZW@h-q@Ze}KLv>F}euaR{RSgbR=gT;XKZ;r@4qt#B4u=9q;~Q|aAiVw= zb{4FC?}dF$21=7#J5blyW=9;&llp>~o3?fLWGcgTcF9M3!-+R~pPiC}(F`Klm%G>% zU?p={)Kw4i5ot z)Oks%(SbriSt4tGXW6?f{Bc?&de8wAaBPv?JNAhbmT5u`xzc8~!=P-$s1r$@ z=+yM>v#LR_j#Zz6Nz!so{gbIC0~1G+VoQH2nd(n=sU7#FOXuF>%;lf=6xoAjgPhXr zimJ1JQs%fYLV<-_~IUp$r2srq58r}At%`DzWo^} z;`tyfq>`m%R|`J|d3;-ep2K*#XvQn{R}9Z9n;#w`i_LgmeBJFwtgTJzz6vtRFlmr? z)tI>U$??paiMytn{7av?q%|zS1J{^FQc*|p$DNv5%Wvrl8rgmCuH+5b(sx!k)Iczo zp(EB2Li@|-Tp2?x<$UP}Us^G`w$mI?6K?JK(2B3oK1Ev(QmGc0Iw6!qbbJW8bBhBNQ5GAO!`{>IZWR^0nU@VVQkUSUo-$Fd^Y?Q}A$1(rmjkBm$LbH~{Y zKW|)b4M|YePe#c@$xSGVfllEi=n2>dqQN=`@tjLdoMmrQg^ld*X~LO*2rioF4&U+( zT&e6lULWm%Y?q@&aW8hfW!UWDzkSPwt2wV)a3qw)$(_3C5YkWrv5~I|Kh4dDKWL#c zi}i6O*;R;Eg1`2i(;7=*cOEWMWzCcgR~BA-Bl;-TM6XXJrM~P;0#^cfoCv%{iiJ{~ zj&`uz_-AjhG$B?x*TE4?A#b=f<>H6DG#?t7Ab9E{t7ERj zN?;mczSwd_2u61~ovNTQdC0s_RiYbRHLG4}(;%IJjJ5KbR`QFy% zcPjuu9(KCru{{7kCBA1R#ssAJST@kc#aKZW9@x3?o9R}E{Eu*0fKAqWIp&b?K?)p7 z76Eb>Yxj;$TMB?3O6G)jDRazmK*wI$OqCHru}4x@vhEK^L89#BqM}^7>p0^+5F%s7 z3@T0obRq%*c*lUK^JQ30mv|)>dtO2xKL?dCOGscx4VDc?W-+;CDz+;MpsZMV8nYH^ z7sca1X1M@*8TMOm?FglK&VrM+3;uN`2NxDx$?fjBA-ErF7TaOi9}JOF5QYcZMDbC7 zlE&_w$6Vo3dpZIsW$0Il8HAGK01>H`{MPHX>SiKGxPy>prB_6>*S?Pz8q>(f^2tfU z13jg-dm9}w*l@+AbXSt59UxZpL(b#;IPN_I^GXug^G$10}<@$C}kE@R9_|2o&)eqXF{_S}uH<9p18hUz+9kMNNoV<8jqT z@YM%oxRO?4rfJL$%6G^ajNERmBXr493(ahl$2v9ZtMMo40LJO3ZdfNK^zqN<+bW9# zLT3H0q(}D*00sxx(|Ai`<`D$~5RxS)OYlWPA_FIBFDvV~-n zJ!IFQ;(8Ib^gnAOAd#GVp#r`Sind7QcqtmE>KM_YlJFLaL6x}bXv4SR{u`AUHY}Z{ z{)OMW`h+IJkGih3RU(JV2oVhUXi$u_i7qnCvnY`}HWDBi&++Vr=5q-fkpG6TAh`4U3{=0fBVV7j~Xqif6im z;A{H_>B+k2Ab=hRNr8sE*8`kgHch{m2Ooa=eXCK1zk6bGwwYqUrKEM6Fai`mj0xWL z(3n4p<@5z|2wEWsNatI5JklYuC)?t$v-as&sV>R;8pVy~J=sJm*Mor;Nx-?cr`@qo z?N2azcqD+3c*vPiMk|VA1?A=3QNkch_Ye>WYK!tn(%1+kVc!X?ts7Md* zdMy6=FPRo=mrW-fG*{m>d?T7H?Lw++4s6Twp)!`n`aA2)P1?`40vJP}wQqjJ74DV9 zGixJ8^3ayxY@R=P91YN1$gWxa;@O76W-6BpxGnJ>e|UfcIfaV-L4jSnE`5}!V_SRW|R z!hhe7Am(GWQ}q!LENcV~d0I$__&xyw+`X&>wX~9PHUt`ewJ593D$m{Jt1DVGW>Fv;>$H`np7OGX z);+9?N!Bj`CfiXm&<(9z07P+|2^Gw+0%*Aeka|~Bj3QfVEw%Aai7mjM(XCy^>7ey> zAkCUriLDn=m%ydGvYGDw;0g=4AIQ40GmkGri@prZJ*WbvovNOR0?DNGP}-Z7iJOv~ zyFB*rv^C`7YFxuj{G5mF$_-d6Z5{0khaohotv&x6&=n@C4ww7Nzo%&-SS4Qi=X^E_ zbz1R~7p(k8r>`W|UC8VJY+OA$*3Q9UC3B$XaJPB40kC3=&0A@kwfDM&R@hyvhfr*L ze8pcUio!iU?{9f8K1GX;$pxIBsYeX6g86`UB+p+A5ODOoZXwlS`}h&y467PKuH_|J z-^1Z01Sie$h=znDZAXc9sZv>F-?O>|C32!nftpeX(EUyvoU?o{nf|dw=-h1^4O|>= zMumVeRFAW3VqFi%NcEr~F{`{0-d8pk540XF==J58FZ`TPJ|ecj!r_rXY8}+jT%D(9 z)EHa2a!DBL+L%BeAp@Mq&g26U*6TBb&GvvMkR|x^0Li9OCzg@+m8;Vl(5WRf$x-~TE zbYHLCn@$^=$P2d)iyx{@X%WTvYx+*#Ubz@Bo8G^PB(TP=*@aZahblXNc~Bu;$$f?- z=OB;L?5XmAF738rjtO_V?Ca1o)L%_S#<~a|uKXzx{=x{dj4)5cs@Ax2|jX z#?%qZ6G8d->X;LQ{(1s|_jkO5OE*}l8adPsC7VhnH~=PhdBZ-+O5Yyt6Y~i&Ft$84 z9?QG`Rzug5I(hSoGCjxN2Izb@^+KjjOPTU&>r2;i79NPXo->PMcGMlBYJV)guNB<) zmi6NMU0c{jQ9+T-XB-(Nr;E+DLJSEip0&7G-baH3o_wTzNg9eJdf8}I*#XcG9)skD z`uc7%LZ?Q7wo-U#%LlgWnXLKfkVm-qyy znhmTYu2fGJ=`Pd$TEouACKe#=59y-T>pMkj#W`o+OGN@5jQN~+@(haJ)wOJe;EbkwX2Pqr#Qp~G;`q^_S_hh|lG{AD~$ZvEwYj1IGm zNCawDc#l(TtKWM_0Y71D3%LnPqzZ`Xp)vDLLRouw4FGz1T#@*RFH(HFS}Sjl?iCqQQ#*hfS4)F86WRoq6O29sJ( z(^d^<5*is7nJ>t>adojWuHhSAzR1EW%6WC30b@IQb5>v}y!mY}U@+1;YIY!k#}d)S z+(mWMCS+lrH14Vtwg4D@?Z|wi5;M+Qiro%ymE8rh~0!0LbIlV z`{lD*I;vUo)z1g>_iR+KM>bBB`GXD=#oEai>kz@|tE;|I4Kz;8I+@xm{o;DZBXx;cw&-_@LV+`Hk%V9%(uk;N27(y2 z(X8jt{)K2LSo4LAydAUP4dgL8ruIUHB-tUjIYNoDDnD;!9?u(q ziuS*pNO#Vjhk2<6JrA6hh|e3>CI4yHj6nl!K|6>ml}{ZNHAJTE@D=#bIu2>w+! z_jnuI_i0grB2wz3d*!4YthT7e#L*Edq$gW&^*o!njMtsV%uLii15D;WzG*9S3`N7L zBc{TQjE}#zR7lI$78&-Rxv8Pwz%3w$L9(uQb=1s#R7sH$+z1UCa^lP*P4c5%kA%)J zw;vesP{-9Tc%r#`N=K%&9m73;qi6Y})xewIv?rE)$;8@Iv$5Z^;)NQn`4J_$nWw|s zMP~*I9WRm0%@|jezhss?lq>$)S%Lz#8aDb0-|SV(`s^K^GV2?;DgxBr*PmXAn4DNQ z4y|e`TgxG?4@ih8;i|YlrXMM85DqYBEm(H_ zbu)69`UA_@v+;ogan4=7xqr=?OW=O#Ein4!!1dRhqV45^aAbY-dkb{cT$J@l%xRjI zeiee;HSizCiC$lEa!8%F2~_;i>x~Gp}0Fj|`yY)1^yto>+X(ywI761WW*> z32ChG2fRQ4Mr7_RcjKTu6@_282y1maTtchZf;KD_c%gQj zcIffYTb2D+m_GWY=#9S*i1hnC({_ZJAerlhGLP50Z%*k2j4q925_WW@#JO^aOCrPsd|^hcKP8!G9CNMSSWt zLUT5JqwK9@XC`(4d`P7i^j(k5v>jufxccuc`FAALLYQU1qwx-vX9ip0F+Nll;MpMA zNOfO?P9YbR+sNdi2*z!egU>L0kfwWgstVqnbQ3zcDHe;r<|&!i@IO%$*RlUV*UR^s zi0rn~-kk89=D}jeV7nssHA*|86{Gif7rUT-^`ZtBM9F_Rw;jv=Pv8rJI&I-QnlEfaYB+#%tL*&~seFK~upEVXS^_UFq1vj`qfI2S?eWod1$&Mp~`H%qs literal 0 HcmV?d00001 diff --git a/seeds/00_networks.js b/seeds/00_networks.js index 135cc90b..e737f7e7 100644 --- a/seeds/00_networks.js +++ b/seeds/00_networks.js @@ -50,6 +50,12 @@ const networks = [ name: 'Jules Jordan', url: 'https://www.julesjordan.com', }, + { + slug: 'kellymadison', + name: 'Kelly Madison Media', + url: 'https://www.kellymadison.com', + description: 'Home of Kelly Madison and Ryan Madison', + }, { slug: 'kink', name: 'Kink', diff --git a/seeds/01_sites.js b/seeds/01_sites.js index da501ca9..705df1a4 100644 --- a/seeds/01_sites.js +++ b/seeds/01_sites.js @@ -1048,6 +1048,28 @@ function getSites(networksMap) { parameters: JSON.stringify({ independent: true }), network_id: networksMap.julesjordan, }, + // KELLY MADISON MEDIA + { + slug: 'teenfidelity', + name: 'Teen Fidelity', + url: 'https://www.teenfidelity.com', + description: 'Home of Kelly Madison and Ryan Madison', + network_id: networksMap.kellymadison, + }, + { + slug: 'pornfidelity', + name: 'Porn Fidelity', + url: 'https://www.pornfidelity.com', + description: 'Home of Kelly Madison and Ryan Madison', + network_id: networksMap.kellymadison, + }, + { + slug: 'kellymadison', + name: 'Kelly Madison', + url: 'https://www.pornfidelity.com', + description: 'Home of Kelly Madison and Ryan Madison', + network_id: networksMap.kellymadison, + }, // KINK { slug: 'thirtyminutesoftorment', diff --git a/src/media.js b/src/media.js index 6365ebc2..010e1a27 100644 --- a/src/media.js +++ b/src/media.js @@ -179,8 +179,6 @@ async function storePhotos(release, releaseId) { const pluckedPhotos = pluckPhotos(release.photos, release); - console.log(release.photos, pluckedPhotos); - const newPhotos = await filterSourceDuplicates(pluckedPhotos, 'releases', 'photo', `(${release.site.name}, ${releaseId}) "${release.title}"`); if (newPhotos.length === 0) return; @@ -201,7 +199,9 @@ async function storePhotos(release, releaseId) { async function storeTrailer(release, releaseId) { // support scrapers supplying multiple qualities - const trailer = Array.isArray(release.trailer) ? release.trailer[0] : release.trailer; + const trailer = Array.isArray(release.trailer) + ? (release.trailer.find(trailerX => [1080, 720].includes(trailerX.quality) || release.trailer[0])) + : release.trailer; if (!trailer || !trailer.src) { console.warn(`No trailer available for (${release.site.name}, ${releaseId}}) "${release.title}"`); diff --git a/src/scrape-release.js b/src/scrape-release.js index 31d5fe71..c39641a0 100644 --- a/src/scrape-release.js +++ b/src/scrape-release.js @@ -45,7 +45,7 @@ async function scrapeRelease(url, release, deep = false) { throw new Error(`The '${site.name}'-scraper cannot fetch individual releases`); } - const scene = await scraper.fetchScene(url, site); + const scene = await scraper.fetchScene(url, site, release); if (!deep && argv.save) { // don't store release when called by site scraper diff --git a/src/scrape-sites.js b/src/scrape-sites.js index 9df808c3..f03dfbb2 100644 --- a/src/scrape-sites.js +++ b/src/scrape-sites.js @@ -78,6 +78,8 @@ async function deepFetchReleases(baseReleases) { deep: true, }; } catch (error) { + console.error(error); + return { ...release, deep: false, diff --git a/src/scrapers/kellymadison.js b/src/scrapers/kellymadison.js new file mode 100644 index 00000000..4fa64fbf --- /dev/null +++ b/src/scrapers/kellymadison.js @@ -0,0 +1,147 @@ +'use strict'; + +const bhttp = require('bhttp'); +const { JSDOM } = require('jsdom'); +const moment = require('moment'); + +const siteMapByKey = { + PF: 'pornfidelity', + TF: 'teenfidelity', + KM: 'kellymadison', +}; + +const siteMapBySlug = Object.entries(siteMapByKey).reduce((acc, [key, value]) => ({ ...acc, [value]: key }), {}); + +function extractTextNode(parentEl) { + return Array.from(parentEl).reduce((acc, el) => (el.nodeType === 3 ? `${acc}${el.textContent.trim()}` : acc), ''); +} + +function scrapeLatest(html, site) { + const { document } = new JSDOM(html).window; + + return Array.from(document.querySelectorAll('.episode'), (scene) => { + const release = { site }; + + release.shootId = scene.querySelector('.card-meta .text-right').textContent.trim(); + + const siteId = release.shootId.match(/\w{2}/)[0]; + const siteSlug = siteMapByKey[siteId]; + + if (site.slug !== siteSlug) { + // using generic network overview, scene is not from the site we want + return null; + } + + const durationEl = scene.querySelector('.content a'); + + [release.entryId] = durationEl.href.match(/\d+$/); + release.url = `${site.url}/episodes/${release.entryId}`; + + release.title = scene.querySelector('h5 a').textContent.trim(); + + const dateEl = scene.querySelector('.card-meta .text-left').childNodes; + const dateString = extractTextNode(dateEl); + + release.date = moment.utc(dateString, ['MMM D', 'MMM D, YYYY']).toDate(); + release.actors = Array.from(scene.querySelectorAll('.models a'), el => el.textContent); + + const durationString = durationEl.textContent.match(/\d+ min/); + if (durationString) release.duration = Number(durationString[0].match(/\d+/)[0]) * 60; + + release.poster = scene.querySelector('.card-img-top').src; + release.trailer = { + src: scene.querySelector('video').src, + }; + + return release; + }).filter(scene => scene); +} + +function scrapeScene(html, url, site, shallowRelease) { + const { document } = new JSDOM(html).window; + const release = { url, site }; + + const titleEl = document.querySelector('.card-header.row h4').childNodes; + const titleString = extractTextNode(titleEl); + + if (!shallowRelease) [release.entryId] = url.match(/\d+/); + + release.title = titleString + .replace('Trailer: ', '') + .replace(/- \w+ #\d+$/, '') + .trim(); + + release.channel = titleString.match(/\w+ #\d+$/)[0].match(/\w+/)[0].toLowerCase(); + + const episode = titleString.match(/#\d+$/)[0]; + const siteKey = siteMapBySlug[release.channel]; + + release.shootId = `${siteKey} ${episode}`; + release.description = document.querySelector('p.card-text').textContent.trim(); + + const dateEl = document.querySelector('.card-body h4.card-title:nth-child(3)').childNodes; + const dateString = extractTextNode(dateEl); + + release.date = moment.utc(dateString, 'YYYY-MM-DD').toDate(); + release.actors = Array.from(document.querySelectorAll('.card-body h4.card-title:nth-child(4) a'), el => el.textContent); + + const durationRaw = document.querySelector('.card-body h4.card-title:nth-child(1)').textContent; + const durationString = durationRaw.match(/\d+:\d+/)[0]; + + release.duration = moment.duration(`00:${durationString}`).asSeconds(); + + const trailerStart = document.body.innerHTML.indexOf('player.updateSrc'); + const trailerString = document.body.innerHTML.slice(trailerStart, document.body.innerHTML.indexOf(');', trailerStart)); + + const trailers = trailerString.match(/https:\/\/.*.mp4/g); + const resolutions = trailerString.match(/res: '\d+'/g).map((res) => { + const resolution = Number(res.match(/\d+/)[0]); + + return resolution === 4000 ? 2160 : resolution; // 4k is not 4000 pixels high + }); + + release.trailer = trailers.map((trailer, index) => ({ + src: trailer, + quality: resolutions[index], + })); + + [release.poster] = document.body.innerHTML + .match(/poster: .*\.jpg/)[0] + .match(/https:\/\/.*\.jpg/); + + if (shallowRelease) release.photos = [shallowRelease.poster]; // deep poster different from shallow poster, use shallow poster as additional photo + + return release; +} + +async function fetchLatest(site, page = 1) { + const url = `https://kellymadison.com/episodes/search?page=${page}`; // TLS issues with teenfidelity.com, same overview on all sites + const res = await bhttp.get(url, { + headers: { + 'X-Requested-With': 'XMLHttpRequest', + }, + }); + + if (res.statusCode === 200 && res.body.status === 'success') { + return scrapeLatest(res.body.html, site); + } + + return null; +} + +async function fetchScene(url, site, shallowRelease) { + const { pathname } = new URL(url); + + const res = await bhttp.get(`https://www.kellymadison.com${pathname}`, { + headers: { + 'X-Requested-With': 'XMLHttpRequest', + }, + }); + + return scrapeScene(res.body.toString(), url, site, shallowRelease); +} + +module.exports = { + fetchLatest, + fetchScene, +}; diff --git a/src/scrapers/scrapers.js b/src/scrapers/scrapers.js index 77d0872b..6b26678c 100644 --- a/src/scrapers/scrapers.js +++ b/src/scrapers/scrapers.js @@ -6,6 +6,7 @@ const bangbros = require('./bangbros'); const blowpass = require('./blowpass'); const dogfart = require('./dogfart'); const evilangel = require('./evilangel'); +const kellymadison = require('./kellymadison'); const kink = require('./kink'); const mikeadriano = require('./mikeadriano'); const mofos = require('./mofos'); @@ -37,6 +38,7 @@ module.exports = { dogfartnetwork: dogfart, evilangel, julesjordan, + kellymadison, kink, legalporno, mikeadriano, diff --git a/src/tags.js b/src/tags.js index a4c95e85..6499d15d 100644 --- a/src/tags.js +++ b/src/tags.js @@ -58,7 +58,7 @@ async function matchTags(rawTags) { async function associateTags(release, releaseId) { if (!release.tags || release.tags.length === 0) { - console.warn(`No tags available for (${release.site.name}, ${releaseId}}) "${release.title}"`); + console.warn(`No tags available for (${release.site.name}, ${releaseId}) "${release.title}"`); return; } diff --git a/src/utils/pluck-photos.js b/src/utils/pluck-photos.js index fcdbdedf..e6cb1a1c 100644 --- a/src/utils/pluck-photos.js +++ b/src/utils/pluck-photos.js @@ -5,14 +5,17 @@ const config = require('config'); // pick {photoLimit} photos evenly distributed photos from a set with {photoTotal} photos, return array of indexes starting at 1 function pluckPhotos(photos, release, specifiedLimit) { const limit = specifiedLimit || config.media.limit; - console.log(limit); + + if (photos.length <= limit) { + return photos; + } const plucked = [1] .concat( - Array.from({ length: limit - 1 }, (value, index) => Math.round((index + 1) * (photos.length / (limit)))), + Array.from({ length: limit }, (value, index) => Math.round((index + 1) * (photos.length / (limit)))), ); - return Array.from(new Set(plucked)).map(photoIndex => photos[photoIndex]); // remove duplicates, may happen when photo total and photo limit are close + return Array.from(new Set(plucked)).map(photoIndex => photos[photoIndex - 1]); // remove duplicates, may happen when photo total and photo limit are close } module.exports = pluckPhotos;