mot-ph 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cache/replit/env/latest +63 -0
- package/.cache/replit/env/latest.json +1 -0
- package/.cache/replit/modules/nodejs-20.res +1 -0
- package/.cache/replit/modules/replit-rtld-loader.res +1 -0
- package/.cache/replit/modules/replit.res +1 -0
- package/.cache/replit/modules.stamp +0 -0
- package/.cache/replit/nix/dotreplitenv.json +1 -0
- package/.cache/replit/toolchain.json +1 -0
- package/.cache/typescript/5.8/package.json +1 -0
- package/.codeclimate.yml +4 -0
- package/.config/configstore/update-notifier-ava.json +4 -0
- package/.gitattributes +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +17 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
- package/.github/ISSUE_TEMPLATE/questions.md +12 -0
- package/.local/state/replit/agent/.agent_state_6fa31f60be98e5d6fb0c67811b64cd555a363f53.bin +0 -0
- package/.local/state/replit/agent/.agent_state_e44addd1339e914cd4e864c650d4d7069b3f5d4e.bin +0 -0
- package/.local/state/replit/agent/.agent_state_f567f1857ae17f372d3c99c01eb473389bc6019d.bin +0 -0
- package/.local/state/replit/agent/.agent_state_main.bin +0 -0
- package/.local/state/replit/agent/.latest.json +1 -0
- package/.local/state/replit/agent/repl_state.bin +0 -0
- package/.replit +29 -0
- package/.travis.yml +6 -0
- package/.xo-config.js +8 -0
- package/LICENSE +21 -0
- package/README.md +378 -0
- package/example.js +31 -0
- package/imgs/pornhub-api.jpg +0 -0
- package/package.json +51 -0
- package/replit.md +48 -0
- package/src/constants/consts_global.js +95 -0
- package/src/constants/consts_model.js +23 -0
- package/src/constants/consts_page.js +83 -0
- package/src/constants/consts_queries.js +11 -0
- package/src/constants/consts_sanitizer.js +14 -0
- package/src/constants/consts_scrap.js +10 -0
- package/src/constants/consts_search.js +22 -0
- package/src/constants/consts_search_gifs.js +15 -0
- package/src/constants/consts_search_pornstars.js +25 -0
- package/src/constants/consts_search_videos.js +29 -0
- package/src/helpers/utils_global.js +36 -0
- package/src/helpers/utils_sanitizer.js +144 -0
- package/src/helpers/utils_scrap.js +65 -0
- package/src/index.js +101 -0
- package/src/model.js +44 -0
- package/src/packages/postinstall.js +1 -0
- package/src/page.js +66 -0
- package/src/search.js +31 -0
- package/src/utils.js +197 -0
- package/tests/datas/page_model.html +6056 -0
- package/tests/datas/page_pornhub.html +7809 -0
- package/tests/datas/page_pornhub_exception.html +7699 -0
- package/tests/datas/search_pornhub_aa_actor_1.html +4446 -0
- package/tests/datas/search_pornhub_aa_page_1.html +4440 -0
- package/tests/datas/search_pornhub_aa_page_2.html +4044 -0
- package/tests/datas/search_pornhub_doggy_gifs.html +3390 -0
- package/tests/dynamic/tests_page.js +104 -0
- package/tests/dynamic/tests_search.js +14 -0
- package/tests/dynamic/tests_video.js +22 -0
- package/tests/static/tests_model.js +76 -0
- package/tests/static/tests_page.js +107 -0
- package/tests/static/tests_search.js +59 -0
- package/tests/static/tests_utils.js +134 -0
- package/tests/static/tests_video.js +13 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const consts_global = require('./../constants/consts_global');
|
|
2
|
+
const consts_page = require('./../constants/consts_page');
|
|
3
|
+
const consts_scrap = require('./../constants/consts_scrap');
|
|
4
|
+
const utils_global = require('./utils_global');
|
|
5
|
+
const utils_sanitizer = require('./utils_sanitizer');
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
scraper_content_informations: (doc, keys, selectors, element_attributs) => {
|
|
9
|
+
const selectors_restricted = utils_global.selectors_restriction(keys, selectors);
|
|
10
|
+
return module.exports.scrap(doc, selectors_restricted, element_attributs);
|
|
11
|
+
},
|
|
12
|
+
is_data_available: (object, key) => {
|
|
13
|
+
return object.querySelector(key) !== null;
|
|
14
|
+
},
|
|
15
|
+
is_array_available: array => {
|
|
16
|
+
return array !== null && array.length > 0;
|
|
17
|
+
},
|
|
18
|
+
scrap_object_selected: (object, keys, key, attribut) => {
|
|
19
|
+
return module.exports.is_data_available(object, keys[key]) ? object.querySelector(keys[key])[attribut] : consts_global.NO_DATA;
|
|
20
|
+
},
|
|
21
|
+
scrap_inner_html: (object, keys, key) => {
|
|
22
|
+
return module.exports.scrap_object_selected(object, keys, key, 'innerHTML');
|
|
23
|
+
},
|
|
24
|
+
scrap_data_content: (object, keys, key) => {
|
|
25
|
+
return module.exports.is_data_available(object, keys[key]) ? object.querySelector(keys[key]).getAttribute('content') : consts_global.NO_DATA;
|
|
26
|
+
},
|
|
27
|
+
scrap_text_content: (object, keys, key) => {
|
|
28
|
+
return module.exports.scrap_object_selected(object, keys, key, 'textContent');
|
|
29
|
+
},
|
|
30
|
+
scrap_multi_text_content: (object, keys, key) => {
|
|
31
|
+
const elm = [...object.querySelectorAll(keys[key])];
|
|
32
|
+
|
|
33
|
+
return module.exports.is_array_available(elm) ? elm.map(node => node.textContent) : consts_global.NO_DATA;
|
|
34
|
+
},
|
|
35
|
+
scrap_javascript: (object, keys, key) => {
|
|
36
|
+
return JSON.parse(object.querySelector(keys[key]).textContent)[consts_page.javascript[key]];
|
|
37
|
+
},
|
|
38
|
+
scrap_null: (object, keys, key) => {
|
|
39
|
+
return module.exports.is_data_available(object, keys[key]);
|
|
40
|
+
},
|
|
41
|
+
scrap_default: (object, keys, key, attributs) => {
|
|
42
|
+
return object.querySelector(keys[key]).getAttribute(attributs[key]);
|
|
43
|
+
},
|
|
44
|
+
scrap: (object, keys, attributs) => {
|
|
45
|
+
return Object.fromEntries(Object.keys(keys).map(key => {
|
|
46
|
+
const scrap = consts_scrap.scrap_by_attribut_type[attributs[key]];
|
|
47
|
+
|
|
48
|
+
let scrap_data = null;
|
|
49
|
+
if (utils_global.is_parameter_missing(scrap)) {
|
|
50
|
+
scrap_data = module.exports.scrap_default(object, keys, key, attributs);
|
|
51
|
+
} else {
|
|
52
|
+
scrap_data = module.exports[scrap](object, keys, key);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return [key, scrap_data];
|
|
56
|
+
}));
|
|
57
|
+
},
|
|
58
|
+
scraper_array: (doc, global, selectors, attributs) => {
|
|
59
|
+
const elements = [...doc.querySelectorAll(global)];
|
|
60
|
+
return elements.map((element, index) => {
|
|
61
|
+
const temporary = module.exports.scrap(element, selectors, attributs);
|
|
62
|
+
return utils_sanitizer.sanitizer(temporary);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('./utils');
|
|
4
|
+
const utils_sanitizer = require('./helpers/utils_sanitizer');
|
|
5
|
+
const consts_global = require('./constants/consts_global');
|
|
6
|
+
const page = require('./page');
|
|
7
|
+
const page_search = require('./search');
|
|
8
|
+
const page_model = require('./model');
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
/**
|
|
12
|
+
* Scrap the content of a video page of pornhub
|
|
13
|
+
*
|
|
14
|
+
* @params {string} url The url of the page you wanna scrap
|
|
15
|
+
* @params {array} key The array of key of value that you want to scrap
|
|
16
|
+
* @return {Object} The result of the scrap in an object containing only the key choosen
|
|
17
|
+
* @throws {Object} If an error happen
|
|
18
|
+
**/
|
|
19
|
+
page: async (url, key) => {
|
|
20
|
+
try {
|
|
21
|
+
const keys = utils.options_to_keys(key);
|
|
22
|
+
const source = await utils.url_to_source(url);
|
|
23
|
+
const datas = page.scraping_page(source, keys);
|
|
24
|
+
return utils_sanitizer.sanitizer(datas);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
return utils.error_message(error);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* Scrap the content of a model page of pornhub
|
|
31
|
+
*
|
|
32
|
+
* @params {string} name The exact name of the model
|
|
33
|
+
* @params {array} key The array of key of value that you want to scrap
|
|
34
|
+
* @params {string} type The type of the result (pornstar or model)
|
|
35
|
+
* @return {Object} The result of the scrap in an object containing only the key choosen
|
|
36
|
+
* @throws {Object} If an error happen
|
|
37
|
+
**/
|
|
38
|
+
model: async (name, key, type = consts_global.types.MODEL) => {
|
|
39
|
+
try {
|
|
40
|
+
const keys = utils.options_to_keys(key);
|
|
41
|
+
const url = utils.name_to_url(name, type);
|
|
42
|
+
const source = await utils.url_to_source(url);
|
|
43
|
+
const datas = page_model.scrap(source, keys);
|
|
44
|
+
const datas_filtered = page_model.filter_value(datas, keys);
|
|
45
|
+
return utils_sanitizer.sanitizer(datas_filtered);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return utils.error_message(error);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
/**
|
|
51
|
+
* Scrap the content of the featured videos of pornhub
|
|
52
|
+
*
|
|
53
|
+
* @params {array} [key=null] The array of key of value that you want to scrap
|
|
54
|
+
* @params {object} [options=null] The options for display the video of a selected page
|
|
55
|
+
* @return {Object} The result of the scrap in an object containing only the key choosen
|
|
56
|
+
* @throws {Object} If an error happen
|
|
57
|
+
**/
|
|
58
|
+
video: async (key = null, options = null) => {
|
|
59
|
+
try {
|
|
60
|
+
const request_start_time = process.hrtime();
|
|
61
|
+
const usage_start = process.memoryUsage();
|
|
62
|
+
|
|
63
|
+
const keys = utils.options_to_keys(key);
|
|
64
|
+
if (!options || !options.page) {
|
|
65
|
+
options = options ? options : {};
|
|
66
|
+
options.page = 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const source = await utils.multi_url_to_source(options);
|
|
70
|
+
const datas = page_search.scraping_search(source, keys, options);
|
|
71
|
+
const datas_sanitize = utils_sanitizer.sanitizer(datas);
|
|
72
|
+
return {...datas_sanitize, ...utils.performance_calculation(request_start_time, usage_start)};
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return utils.error_message(error);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Scrap the content of a search page of pornhub
|
|
79
|
+
*
|
|
80
|
+
* @params {string} search The exact terms of the search
|
|
81
|
+
* @params {array} key The array of key of value that you want to scrap
|
|
82
|
+
* @params {object} options The options for display the video of a selected page
|
|
83
|
+
* @return {object} The result of the scrap in an object containing only the key choosen
|
|
84
|
+
* @throws {object} If an error happen
|
|
85
|
+
**/
|
|
86
|
+
search: async (search, key, options) => {
|
|
87
|
+
try {
|
|
88
|
+
const keys = utils.options_to_keys(key);
|
|
89
|
+
if (!options || !options.page) {
|
|
90
|
+
options = options ? options : {};
|
|
91
|
+
options.page = 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const source = await utils.multi_url_to_source(options, search);
|
|
95
|
+
const datas = page_search.scraping_search(source, keys, options);
|
|
96
|
+
return utils_sanitizer.sanitizer(datas);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return utils.error_message(error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
package/src/model.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const utils = require('./utils');
|
|
2
|
+
const utils_sanitizer = require('./helpers/utils_sanitizer');
|
|
3
|
+
const utils_scrap = require('./helpers/utils_scrap');
|
|
4
|
+
const utils_global = require('./helpers/utils_global');
|
|
5
|
+
const consts_global = require('./constants/consts_global');
|
|
6
|
+
const consts_model = require('./constants/consts_model');
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
extract_informations_model: (doc, selector_elements) => {
|
|
10
|
+
const elements = [...doc.querySelectorAll(selector_elements)];
|
|
11
|
+
|
|
12
|
+
return Object.fromEntries(elements.map(element => {
|
|
13
|
+
const element_key = element.querySelector('span:nth-child(1)');
|
|
14
|
+
const element_key_text = utils_sanitizer.sanitizer_key(element_key.innerHTML);
|
|
15
|
+
|
|
16
|
+
const element_value = element.querySelector('span:nth-child(2)');
|
|
17
|
+
const element_value_text = element_value === null ? consts_global.NO_DATA : utils_sanitizer.sanitizer_string(element_value.innerHTML);
|
|
18
|
+
|
|
19
|
+
return [element_key_text, element_value_text];
|
|
20
|
+
}));
|
|
21
|
+
},
|
|
22
|
+
scrap_unfixed_content_informations: (doc, keys, selectors, attributs) => {
|
|
23
|
+
const informations = module.exports.extract_informations_model(doc, consts_model.PROFIL_INFOS_LIST);
|
|
24
|
+
const informations_restricted = utils_global.selectors_restriction(keys, informations);
|
|
25
|
+
return informations_restricted;
|
|
26
|
+
},
|
|
27
|
+
scrap: (source, keys) => {
|
|
28
|
+
const doc = utils.source_to_dom(source);
|
|
29
|
+
|
|
30
|
+
let datas = {};
|
|
31
|
+
datas = {...datas, ...utils_scrap.scraper_content_informations(doc, keys, consts_model.model_selectors, consts_model.model_element_attributs)};
|
|
32
|
+
datas = {...datas, ...module.exports.scrap_unfixed_content_informations(doc, keys, consts_model.model_selectors, consts_model.model_element_attributs)};
|
|
33
|
+
|
|
34
|
+
return datas;
|
|
35
|
+
},
|
|
36
|
+
filter_value: (datas, keys) => {
|
|
37
|
+
if (datas.VIDEO_NUMBER) {
|
|
38
|
+
const match = datas.VIDEO_NUMBER.match(/(?<=of )\d+/gi, '');
|
|
39
|
+
datas.VIDEO_NUMBER = match[0];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return datas;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('Thanks for using my API! If you like it, please visit my github ;)');
|
package/src/page.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const utils = require('./utils');
|
|
2
|
+
const utils_scrap = require('./helpers/utils_scrap');
|
|
3
|
+
const consts_global = require('./constants/consts_global');
|
|
4
|
+
const consts_page = require('./constants/consts_page');
|
|
5
|
+
|
|
6
|
+
const scraper_comments_options = {
|
|
7
|
+
key: consts_global.keys.COMMENTS,
|
|
8
|
+
list: consts_page.COMMENTS_LIST,
|
|
9
|
+
selectors: consts_page.comment_selectors,
|
|
10
|
+
attributs: consts_page.page_element_attributs
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const scraper_related_videos_options = {
|
|
14
|
+
key: consts_global.keys.RELATED_VIDEOS,
|
|
15
|
+
list: consts_page.RELATED_VIDEOS_LIST,
|
|
16
|
+
selectors: consts_page.related_videos_selectors,
|
|
17
|
+
attributs: consts_page.page_related_videos_element_attributs
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
scraper_video_informations: (source, keys) => {
|
|
22
|
+
let rsl = {};
|
|
23
|
+
|
|
24
|
+
if (keys.includes(consts_global.keys.DOWNLOAD_URLS)) {
|
|
25
|
+
const matches = source.match(/(?<=\*\/)\w+/g);
|
|
26
|
+
const urls = [];
|
|
27
|
+
for (const match of matches) {
|
|
28
|
+
const regex = new RegExp('(?<=' + match + '=")[^;]+(?=")', 'g');
|
|
29
|
+
const value = source.match(regex)[0].replace(/[" +]/g, '');
|
|
30
|
+
|
|
31
|
+
if (value.startsWith('https')) {
|
|
32
|
+
if (urls.length === 4) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
urls.push(value);
|
|
37
|
+
} else {
|
|
38
|
+
urls[urls.length - 1] += value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
rsl = urls.map(x => {
|
|
43
|
+
// Sometime PH does not provide a resolution, meaning the link is broken
|
|
44
|
+
const resolution = x.match(/(?<=_|\/)\d*P(?=_)/g);
|
|
45
|
+
return resolution !== null && resolution.length > 0 ? [x.match(/(?<=_|\/)\d*P(?=_)/g)[0], x] : null;
|
|
46
|
+
}).filter(x => x !== null);
|
|
47
|
+
rsl = Object.fromEntries(rsl);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return Object.keys(rsl).length > 0 ? rsl : null;
|
|
51
|
+
},
|
|
52
|
+
scraper_block_informations: (doc, keys, scrap_options) => {
|
|
53
|
+
return keys.includes(scrap_options.key) ? {[scrap_options.key]: utils_scrap.scraper_array(doc, scrap_options.list, scrap_options.selectors, scrap_options.attributs)} : {};
|
|
54
|
+
},
|
|
55
|
+
scraping_page: (source, keys) => {
|
|
56
|
+
const doc = utils.source_to_dom(source);
|
|
57
|
+
let datas = {};
|
|
58
|
+
|
|
59
|
+
datas = {...datas, ...utils_scrap.scraper_content_informations(doc, keys, consts_page.page_selectors, consts_page.page_element_attributs)};
|
|
60
|
+
datas = {...datas, DOWNLOAD_URLS: module.exports.scraper_video_informations(source, keys)};
|
|
61
|
+
datas = {...datas, ...module.exports.scraper_block_informations(doc, keys, scraper_comments_options)};
|
|
62
|
+
datas = {...datas, ...module.exports.scraper_block_informations(doc, keys, scraper_related_videos_options)};
|
|
63
|
+
|
|
64
|
+
return datas;
|
|
65
|
+
}
|
|
66
|
+
};
|
package/src/search.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const utils = require('./utils');
|
|
2
|
+
const utils_scrap = require('./helpers/utils_scrap');
|
|
3
|
+
const consts_global = require('./constants/consts_global');
|
|
4
|
+
const consts_search = require('./constants/consts_search');
|
|
5
|
+
const consts_search_gifs = require('./constants/consts_search_gifs');
|
|
6
|
+
const consts_search_pornstars = require('./constants/consts_search_pornstars');
|
|
7
|
+
const consts_search_videos = require('./constants/consts_search_videos');
|
|
8
|
+
const jsdom = require('jsdom');
|
|
9
|
+
const {JSDOM} = jsdom;
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
scraping_search: (source, keys, options) => {
|
|
13
|
+
const doc = utils.source_to_dom(source);
|
|
14
|
+
|
|
15
|
+
let datas = {};
|
|
16
|
+
datas = {...datas, ...utils_scrap.scraper_content_informations(doc, keys, consts_search.primary_search_selectors, consts_search.page_search_element_attributs)};
|
|
17
|
+
if (!options.search || options.search === 'video') {
|
|
18
|
+
datas[consts_global.keys.RESULTS] = utils_scrap.scraper_array(doc, consts_search_videos.VIDEOS_LIST, consts_search_videos.videos_search_selectors, consts_search_videos.videos_element_attributs);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (options.search === 'pornstars') {
|
|
22
|
+
datas[consts_global.keys.RESULTS] = utils_scrap.scraper_array(doc, consts_search_pornstars.PORNSTARS_LIST, consts_search_pornstars.pornstars_search_selectors, consts_search_pornstars.pornstars_element_attributs);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (options.search === 'gifs') {
|
|
26
|
+
datas[consts_global.keys.RESULTS] = utils_scrap.scraper_array(doc, consts_search_gifs.GIFS_LIST, consts_search_gifs.gifs_search_selectors, consts_search_gifs.gifs_element_attributs);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return datas;
|
|
30
|
+
}
|
|
31
|
+
};
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
const consts_global = require('./constants/consts_global');
|
|
2
|
+
const consts_page = require('./constants/consts_page');
|
|
3
|
+
const consts_queries = require('./constants/consts_queries');
|
|
4
|
+
const utils_sanitizer = require('./helpers/utils_sanitizer');
|
|
5
|
+
const Entities = require('html-entities').AllHtmlEntities;
|
|
6
|
+
const entities = new Entities();
|
|
7
|
+
const jsdom = require('jsdom');
|
|
8
|
+
const {JSDOM} = jsdom;
|
|
9
|
+
const got = require('got');
|
|
10
|
+
const promise = require('promise');
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
/**
|
|
14
|
+
* Check if the parameter is defined and exist
|
|
15
|
+
*
|
|
16
|
+
* @params {string} parameter The parameter we want to test
|
|
17
|
+
* @return {boolean} True if the parameter exist or else false
|
|
18
|
+
**/
|
|
19
|
+
is_parameter_missing: parameter => {
|
|
20
|
+
return parameter === null || parameter === '' || parameter === undefined;
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* Read the keys passed and sanitize them in uppercase.
|
|
24
|
+
* If there is no key passed, we define a simple key `title`
|
|
25
|
+
* If the key passed is a string instead of an array, we put that key inside an array
|
|
26
|
+
*
|
|
27
|
+
* @params {(string|array)} key The single or multiples key passed with the call
|
|
28
|
+
* @return {array} The key in uppercase in an array
|
|
29
|
+
* @throws {Error} If the array passed in the call is empty
|
|
30
|
+
**/
|
|
31
|
+
options_to_keys: key => {
|
|
32
|
+
if (module.exports.is_parameter_missing(key)) {
|
|
33
|
+
return ['TITLE'];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const array_keys = Array.isArray(key) ? key : [key];
|
|
37
|
+
const array_keys_uppercase = array_keys.map(x => x.toUpperCase());
|
|
38
|
+
|
|
39
|
+
if (array_keys_uppercase.length === 0) {
|
|
40
|
+
throw new Error('A key need to be used with this call');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return array_keys_uppercase;
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Transform the value of a filter from the package to his equivalent for pornhub
|
|
47
|
+
* By example is really not easy to remember that `mv` is the value for pornhub for `MOST_VIEWED`
|
|
48
|
+
* So the user of the api can just enter MOST_VIEWED and I will search for the pornhub value
|
|
49
|
+
*
|
|
50
|
+
* @params {string} value The query parameter that he wan to translate
|
|
51
|
+
* @return {string|null} The value translated if it exists or else null
|
|
52
|
+
**/
|
|
53
|
+
transform_filter: value => {
|
|
54
|
+
return module.exports.is_parameter_missing(value) ? null : consts_queries.filter[value];
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Search in the array `values_allowed` if the `value` exist
|
|
58
|
+
* This function is used for checking the value available for a query parameter
|
|
59
|
+
*
|
|
60
|
+
* @params {string} value The value of the parameter to check
|
|
61
|
+
* @params {array} values_allowed The array that we will check into if the value is allowed
|
|
62
|
+
* @return {boolean} True if the value is allowed or else false
|
|
63
|
+
**/
|
|
64
|
+
is_value_allowed: (value, values_allowed) => {
|
|
65
|
+
return values_allowed.includes(value);
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* Create the url query for the parameter and value passed in argument
|
|
69
|
+
*
|
|
70
|
+
* @params {string} parameter The parameter that we want to config
|
|
71
|
+
* @params {string} value The value we want to give to the parameter
|
|
72
|
+
* @params {array} [values_allowed=null] The allowed value for this parameter
|
|
73
|
+
* @return {string} An url params with the form : & + parameter + = + value
|
|
74
|
+
**/
|
|
75
|
+
create_query: (parameter, value, values_allowed = null) => {
|
|
76
|
+
if (module.exports.is_parameter_missing(value)) {
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (values_allowed && !module.exports.is_value_allowed(value, values_allowed)) {
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return '&' + parameter + '=' + value;
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Create the url query of all the options
|
|
88
|
+
*
|
|
89
|
+
* @params {Object} options The object of the params and value
|
|
90
|
+
* @params {number} page_index The page of the search
|
|
91
|
+
* @params {string} [search=null] The term of the search
|
|
92
|
+
* @return {string} The url with all the params ready to be append to the url
|
|
93
|
+
**/
|
|
94
|
+
create_queries: (options, page_index, search = null) => {
|
|
95
|
+
let q = '';
|
|
96
|
+
q += module.exports.create_query('search', search);
|
|
97
|
+
q += module.exports.create_query('p', options.production, consts_queries.production);
|
|
98
|
+
q += module.exports.create_query('max_duration', options.max_duration, consts_queries.max_duration);
|
|
99
|
+
q += module.exports.create_query('min_duration', options.min_duration, consts_queries.min_duration);
|
|
100
|
+
q += module.exports.create_query('promo', options.promo, consts_queries.promo);
|
|
101
|
+
q += module.exports.create_query('o', module.exports.transform_filter(options.filter), Object.values(consts_queries.filter));
|
|
102
|
+
|
|
103
|
+
q += '&page=' + (page_index + 1);
|
|
104
|
+
q = q.replace('&', '?');
|
|
105
|
+
return q;
|
|
106
|
+
},
|
|
107
|
+
create_section_type: options => {
|
|
108
|
+
return options.search ? options.search : 'video';
|
|
109
|
+
},
|
|
110
|
+
create_link: (options, page_index, search = null) => {
|
|
111
|
+
let link = consts_global.links.BASE_URL + '/';
|
|
112
|
+
link += module.exports.create_section_type(options);
|
|
113
|
+
link += module.exports.is_parameter_missing(search) ? '' : '/' + consts_global.links.SEARCH;
|
|
114
|
+
link += module.exports.create_queries(options, page_index, search);
|
|
115
|
+
return link;
|
|
116
|
+
},
|
|
117
|
+
url_to_source: async url => {
|
|
118
|
+
url = module.exports.http_to_https(url);
|
|
119
|
+
const safe_url = url.toLowerCase();
|
|
120
|
+
const response = await got(safe_url);
|
|
121
|
+
return response.body;
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Change the protocol http to https in an url
|
|
125
|
+
*
|
|
126
|
+
* @params {string} url The url that we want to replace the protocol
|
|
127
|
+
* @return {string} The url with https protocol
|
|
128
|
+
**/
|
|
129
|
+
http_to_https: url => {
|
|
130
|
+
return url.replace(/^http:/gi, 'https:');
|
|
131
|
+
},
|
|
132
|
+
multi_url_to_source: async (options, search = null) => {
|
|
133
|
+
return promise.all([...new Array(options.page)].map(async (page, page_index) => {
|
|
134
|
+
return module.exports.url_to_source(module.exports.create_link(options, page_index, search));
|
|
135
|
+
}));
|
|
136
|
+
},
|
|
137
|
+
name_to_url: (name, type) => {
|
|
138
|
+
if (module.exports.is_parameter_missing(name)) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const slug = name.replace(/\s/gi, '-').toLowerCase();
|
|
143
|
+
const type_slug = type === consts_global.types.MODEL ? consts_global.types.MODEL : consts_global.types.PORNSTAR;
|
|
144
|
+
return consts_global.links.BASE_URL + '/' + type_slug + '/' + slug;
|
|
145
|
+
},
|
|
146
|
+
source_to_dom: source => {
|
|
147
|
+
const dom = new JSDOM(source);
|
|
148
|
+
return dom.window.document;
|
|
149
|
+
},
|
|
150
|
+
convert_to_second: time => {
|
|
151
|
+
if (module.exports.is_parameter_missing(time)) {
|
|
152
|
+
return consts_global.NO_DATA;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const time_splitted = time.split(':');
|
|
156
|
+
switch (time_splitted.length) {
|
|
157
|
+
case 3:
|
|
158
|
+
return ((+Number(time_splitted[0])) * 60 * 60) + ((+Number(time_splitted[1])) * 60) + (+Number(time_splitted[2]));
|
|
159
|
+
case 2:
|
|
160
|
+
return ((+Number(time_splitted[0])) * 60) + (+Number(time_splitted[1]));
|
|
161
|
+
default:
|
|
162
|
+
return Number(time);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Give additionnal informations about the performance of the request
|
|
167
|
+
*
|
|
168
|
+
* @params {Object} request_start_time The process.hrtime of the beginning of the request
|
|
169
|
+
* @params {Object} usage_start The process.memoryUsage at the beginning of the request
|
|
170
|
+
* @return {Object} The result of the performance of the request
|
|
171
|
+
**/
|
|
172
|
+
performance_calculation: (request_start_time, usage_start) => {
|
|
173
|
+
const request_duration = process.hrtime(request_start_time);
|
|
174
|
+
const request_performance_time = request_duration[0] + '.' + request_duration[1] + ' seconds';
|
|
175
|
+
const usage_end = process.memoryUsage();
|
|
176
|
+
const request_rss = usage_end.rss - usage_start.rss;
|
|
177
|
+
const request_heap_total = usage_end.heapTotal - usage_start.heapTotal;
|
|
178
|
+
const request_heap_used = usage_end.heapUsed - usage_start.heapUsed;
|
|
179
|
+
const performance = {
|
|
180
|
+
request_duration: request_performance_time,
|
|
181
|
+
request_diff_rss: request_rss,
|
|
182
|
+
request_diff_heap_total: request_heap_total,
|
|
183
|
+
request_diff_heap_used: request_heap_used
|
|
184
|
+
};
|
|
185
|
+
return {performance};
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* Handle the error message of the api
|
|
189
|
+
*
|
|
190
|
+
* @params {Object} error The error javascript object
|
|
191
|
+
* @return {Object} The object that notice there is an error
|
|
192
|
+
**/
|
|
193
|
+
error_message: error => {
|
|
194
|
+
console.log(error);
|
|
195
|
+
return {error: consts_global.errors.DEFAULT};
|
|
196
|
+
}
|
|
197
|
+
};
|