Skip to content

Instantly share code, notes, and snippets.

@aegyed91
Created October 19, 2017 17:09
Show Gist options
  • Save aegyed91/c72e530419842f4facb4387081014448 to your computer and use it in GitHub Desktop.
Save aegyed91/c72e530419842f4facb4387081014448 to your computer and use it in GitHub Desktop.
pornhub nodejs adapter
var { URL, URLSearchParams } = require('url');
var request = require('request-promise-native');
var _ = require('lodash');
/**
* PornHUB adapter
*
* @url https://www.hubtraffic.com/resources/api?site_id=3
*
* - searchVideos https://www.hubtraffic.com/resources/api?site_id=3#searchVideos
* - getVideoById https://www.hubtraffic.com/resources/api?site_id=3#getVideoById
* - isVideoActive https://www.hubtraffic.com/resources/api?site_id=3#isVideoActive
* - getVideoEmbedCode https://www.hubtraffic.com/resources/api?site_id=3#getVideoEmbedCode
* - getDeletedVideos https://www.hubtraffic.com/resources/api?site_id=3#getDeletedVideos
*
* - getCategoriesList https://www.hubtraffic.com/resources/api?site_id=3#getCategoriesList
* - getTagsList https://www.hubtraffic.com/resources/api?site_id=3#getTagsList
* - getStarList https://www.hubtraffic.com/resources/api?site_id=3#getStarList
* - getStarDetailedList https://www.hubtraffic.com/resources/api?site_id=3#getStarDetailedList
*/
class PornHUBAdapter {
/**
* @constructor
*/
constructor() {
this.apiUrl = 'https://www.pornhub.com/webmasters';
this.embedUrl = 'https://www.pornhub.com/embed';
}
/**
* @method searchVideos
* @url https://www.hubtraffic.com/resources/api?site_id=3#searchVideos
* @param {Object} params
* @param {string} [params.category]
* @param {number} [params.page=1]
* @param {string} [params.search]
* @param {string[]} [params.tags]
* @param {string[]} [params.stars]
* @param {enum} [params.thumbsize='small','medium','large,small_hd','medium_hd','large_hd']
* @param {enum} [params.ordering='newest','mostviewed','rating']
* @param {enum} [params.period='weekly','monthly','alltime']
* @returns {Promise.<Object[]>}
*/
async searchVideos(params) {
var url = new URL(this.apiUrl + '/search') + '?' + this._genParams(params);
var result = JSON.parse(await request(url));
// TODO: map to a normalized form amongst providers
var mapped = result.videos.map(video => ({
publish_date: video.publish_date,
duration: video.duration,
views: video.views,
video_id: video.video_id,
rating: video.rating,
ratings: video.ratings,
title: video.title,
url: video.url,
embedUrl: `${this.embedUrl}/${video.video_id}`,
streamUrl: null,
thumb: video.thumb,
thumbs: video.thumbs,
default_thumb: video.default_thumb,
tags: video.thumbs,
pornstars: video.pornstars,
categories: video.categories,
segment: video.segment,
}));
var matches = await Promise.all(mapped.map(video => this._grabStreamUrl(video.embedUrl)));
matches.forEach((streamUrl, idx) => {
mapped[idx].streamUrl = streamUrl;
});
return mapped;
}
/**
* @method getVideoById
* @url https://www.hubtraffic.com/resources/api?site_id=3#getVideoById
* @param {Object} params
* @param {number} params.video_id,
* @param {enum} [params.thumbsize='small','medium','large,small_hd','medium_hd','large_hd']
* @returns {Promise.<Object>}
*/
async getVideoById(params) {
var url = new URL(this.apiUrl + '/video_by_id') + '?' + this._genParams(params);
var result = JSON.parse(await request(url));
// TODO: map to a normalized form amongst providers
var mapped = {
publish_date: result.video.publish_date,
duration: result.video.duration,
views: result.video.views,
video_id: result.video.video_id,
rating: result.video.rating,
ratings: result.video.ratings,
title: result.video.title,
url: result.video.url,
embedUrl: `${this.embedUrl}/${result.video.video_id}`,
streamUrl: null,
thumb: result.video.thumb,
thumbs: result.video.thumbs,
default_thumb: result.video.default_thumb,
tags: result.video.thumbs,
pornstars: result.video.pornstars,
categories: result.video.categories,
segment: result.video.segment,
};
mapped.streamUrl = await this._grabStreamUrl(mapped.embedUrl);
return mapped;
}
/**
* @method getCategoriesList
* @url https://www.hubtraffic.com/resources/api?site_id=3#getCategoriesList
* @returns {Promise.<Array<string>>}
*/
async getCategoriesList() {
var url = new URL(this.apiUrl + '/categories');
var result = JSON.parse(await request(url.toString()));
return result.categories.map(category => category.category);
}
/**
* @method getTagsList
* @url https://www.hubtraffic.com/resources/api?site_id=3#getTagsList
* @param {Object} params
* @param {string} params.list
* @returns {Promise.<Array<string>>}
*/
async getTagsList(params) {
var url = new URL(this.apiUrl + '/tags') + '?' + this._genParams(params);
var result = JSON.parse(await request(url.toString()));
return result.tags.map(tag => tag.tag.tag_name);
}
/**
* @method _genParams
* @description make query params consumable for provider
* @param {Object} params
* @returns {URLSearchParams}
* @private
*/
_genParams(params) {
var _params = _.omitBy(params, _.isEmpty);
Object.keys(_params).forEach((key) => {
// replace `?key=1,2` to `?key[]=1,2`
if (Array.isArray(_params[key]) && !key.endsWith('[]')) {
_params[key + '[]'] = _params[key];
delete _params[key];
}
});
return new URLSearchParams(_params);
}
/**
* @method _grabStreamUrl
* @param {string} embedUrl
* @returns {Promise.<string|null>}
* @private
*/
async _grabStreamUrl(embedUrl) {
var source = await request(embedUrl);
var re = /"videoUrl":"(.*?)"/ig;
var match = re.exec(source)[1];
// TODO: figure out what to do with 403 urls, avg 8-15 per page (30 record)
// - maybe use thumbnail images and rotate a gallery if stream not available
// - contact tech support
// console.log(match);
// if (match.length > 300 || match.match(/ce.phncdn.com/)) {
// console.log('ABOVE URL IS ABNORMAL, will return http 403');
// }
return match;
}
}
module.exports = PornHUBAdapter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment