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
package/example.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const pornhub = require('./src/index.js');
|
|
2
|
+
|
|
3
|
+
async function demo() {
|
|
4
|
+
console.log('PornHub API Library - Demo');
|
|
5
|
+
console.log('===========================\n');
|
|
6
|
+
|
|
7
|
+
console.log('This is a Node.js library for scraping PornHub.');
|
|
8
|
+
console.log('It provides the following main functions:\n');
|
|
9
|
+
|
|
10
|
+
console.log('1. pornhub.page(url, keys) - Scrape a single video page');
|
|
11
|
+
console.log('2. pornhub.search(value, keys, options) - Search for videos');
|
|
12
|
+
console.log('3. pornhub.video(keys, options) - Search by category');
|
|
13
|
+
console.log('4. pornhub.model(name, keys) - Get model information\n');
|
|
14
|
+
|
|
15
|
+
console.log('Example usage:');
|
|
16
|
+
console.log('---------------');
|
|
17
|
+
console.log(`
|
|
18
|
+
const pornhub = require('@justalk/pornhub-api');
|
|
19
|
+
|
|
20
|
+
// Scrape video info
|
|
21
|
+
const video = await pornhub.page(url, ['title', 'description', 'views']);
|
|
22
|
+
|
|
23
|
+
// Search for content
|
|
24
|
+
const results = await pornhub.search('keyword', ['title', 'link', 'hd']);
|
|
25
|
+
`);
|
|
26
|
+
|
|
27
|
+
console.log('\nSee README.md for complete documentation.');
|
|
28
|
+
console.log('\nLibrary loaded successfully! All exports available.');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
demo().catch(console.error);
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mot-ph",
|
|
3
|
+
"version": "3.4.0",
|
|
4
|
+
"description": "Very complete scrapper for the famous porn website pornhub",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/justalk/pornhub-api.git"
|
|
9
|
+
},
|
|
10
|
+
"author": "Justal Kevin <justal.kevin@gmail.com> (teamkd.online)",
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=12.0"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "xo --fix && nyc --reporter=html --reporter=text ava --verbose --timeout=20s",
|
|
16
|
+
"test-no": "ava tests/static/* --verbose --timeout=20s",
|
|
17
|
+
"test-s": "ava tests/static/*.js --verbose --timeout=20s",
|
|
18
|
+
"test-p": "ava tests/dynamic/tests_page.js --verbose --timeout=20s",
|
|
19
|
+
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
|
20
|
+
"postinstall": "node src/packages/postinstall.js"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"porn",
|
|
24
|
+
"pornhub",
|
|
25
|
+
"api",
|
|
26
|
+
"scraper",
|
|
27
|
+
"sex",
|
|
28
|
+
"download"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"diff": "^4.0.2",
|
|
32
|
+
"ejs": "^3.1.5",
|
|
33
|
+
"got": "6.6.3",
|
|
34
|
+
"html-entities": "^1.3.1",
|
|
35
|
+
"jsdom": "^16.3.0",
|
|
36
|
+
"promise": "^8.1.0",
|
|
37
|
+
"uglify-js": "^3.10.1"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"ava": "^2.4.0",
|
|
41
|
+
"coveralls": "^3.1.0",
|
|
42
|
+
"nock": "^13.0.4",
|
|
43
|
+
"nyc": "^15.1.0",
|
|
44
|
+
"xo": "*"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/justalk/pornhub-api/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/justalk/pornhub-api#readme",
|
|
50
|
+
"main": "src/index.js"
|
|
51
|
+
}
|
package/replit.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# PornHub API
|
|
2
|
+
|
|
3
|
+
A Node.js library for scraping PornHub website content.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This is an npm package that provides a programmatic API for scraping PornHub. It is **not** a web application - it's a JavaScript library meant to be imported and used by other projects.
|
|
8
|
+
|
|
9
|
+
## Project Structure
|
|
10
|
+
|
|
11
|
+
- `src/` - Source code for the library
|
|
12
|
+
- `index.js` - Main entry point with exports
|
|
13
|
+
- `page.js` - Video page scraping
|
|
14
|
+
- `search.js` - Search functionality
|
|
15
|
+
- `model.js` - Model/pornstar page scraping
|
|
16
|
+
- `utils.js` - Utility functions
|
|
17
|
+
- `constants/` - Configuration constants
|
|
18
|
+
- `helpers/` - Helper utilities
|
|
19
|
+
- `tests/` - Test files
|
|
20
|
+
- `static/` - Tests using mocked data
|
|
21
|
+
- `dynamic/` - Tests using live data
|
|
22
|
+
- `datas/` - Test fixture HTML files
|
|
23
|
+
- `example.js` - Demo script showing library usage
|
|
24
|
+
|
|
25
|
+
## Running the Project
|
|
26
|
+
|
|
27
|
+
Run `node example.js` to see a demo of the library capabilities.
|
|
28
|
+
|
|
29
|
+
Run `npm run test-s` to execute the static tests.
|
|
30
|
+
|
|
31
|
+
## Main API Functions
|
|
32
|
+
|
|
33
|
+
1. `pornhub.page(url, keys)` - Scrape a single video page
|
|
34
|
+
2. `pornhub.search(value, keys, options)` - Search for videos
|
|
35
|
+
3. `pornhub.video(keys, options)` - Search by category
|
|
36
|
+
4. `pornhub.model(name, keys)` - Get model information
|
|
37
|
+
|
|
38
|
+
## Dependencies
|
|
39
|
+
|
|
40
|
+
- got - HTTP requests
|
|
41
|
+
- jsdom - HTML parsing
|
|
42
|
+
- ejs - Template engine
|
|
43
|
+
- html-entities - Entity decoding
|
|
44
|
+
- uglify-js - Code minification
|
|
45
|
+
|
|
46
|
+
## Recent Changes
|
|
47
|
+
|
|
48
|
+
- December 2025: Initial setup for Replit environment
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const js_type = {
|
|
2
|
+
STRING: 'STRING',
|
|
3
|
+
URL: 'URL',
|
|
4
|
+
URL_PORNHUB: 'URL_PORNHUB',
|
|
5
|
+
NUMBER: 'NUMBER',
|
|
6
|
+
NUMBER_KM: 'NUMBER_KM',
|
|
7
|
+
NUMBER_SECONDS: 'NUMBER_SECONDS',
|
|
8
|
+
ARRAY: 'ARRAY',
|
|
9
|
+
DATE: 'DATE',
|
|
10
|
+
OBJECT: 'OBJECT',
|
|
11
|
+
BOOLEAN: 'BOOLEAN'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
NO_DATA: 'No Data',
|
|
16
|
+
js_type,
|
|
17
|
+
keys: {
|
|
18
|
+
COMMENTS: 'COMMENTS',
|
|
19
|
+
RELATED_VIDEOS: 'RELATED_VIDEOS',
|
|
20
|
+
DOWNLOAD_URLS: 'DOWNLOAD_URLS',
|
|
21
|
+
RESULTS: 'RESULTS'
|
|
22
|
+
},
|
|
23
|
+
type: {
|
|
24
|
+
TITLE: js_type.STRING,
|
|
25
|
+
VIEWS: js_type.NUMBER_KM,
|
|
26
|
+
UP_VOTES: js_type.NUMBER,
|
|
27
|
+
DOWN_VOTES: js_type.NUMBER,
|
|
28
|
+
PERCENT: js_type.NUMBER,
|
|
29
|
+
AUTHOR: js_type.STRING,
|
|
30
|
+
AUTHOR_SUBSCRIBER: js_type.NUMBER,
|
|
31
|
+
CATEGORIES: js_type.ARRAY,
|
|
32
|
+
TAGS: js_type.ARRAY,
|
|
33
|
+
PRODUCTION: js_type.STRING,
|
|
34
|
+
DESCRIPTION: js_type.STRING,
|
|
35
|
+
DURATION: js_type.NUMBER,
|
|
36
|
+
RANK_MODEL: js_type.NUMBER,
|
|
37
|
+
RANK_WEEK_MODEL: js_type.NUMBER,
|
|
38
|
+
RANK_MONTH_MODEL: js_type.NUMBER,
|
|
39
|
+
RANK_LAST_MONTH_MODEL: js_type.NUMBER,
|
|
40
|
+
RANK_YEAR_MODEL: js_type.NUMBER,
|
|
41
|
+
UPLOAD_DATE: js_type.DATE,
|
|
42
|
+
PORNSTARS: js_type.ARRAY,
|
|
43
|
+
DOWNLOAD_URLS: js_type.OBJECT,
|
|
44
|
+
LINK: js_type.URL_PORNHUB,
|
|
45
|
+
THUMBNAIL_URL: js_type.URL,
|
|
46
|
+
HD: js_type.BOOLEAN,
|
|
47
|
+
NUMBER_OF_COMMENT: js_type.NUMBER,
|
|
48
|
+
COMMENTS: js_type.OBJECT,
|
|
49
|
+
AVATAR: js_type.STRING,
|
|
50
|
+
USERNAME: js_type.STRING,
|
|
51
|
+
DATE: js_type.STRING,
|
|
52
|
+
MESSAGE: js_type.STRING,
|
|
53
|
+
TOTAL_VOTE: js_type.NUMBER,
|
|
54
|
+
PREMIUM: js_type.BOOLEAN,
|
|
55
|
+
RATING: js_type.NUMBER,
|
|
56
|
+
RELATED_SEARCH: js_type.ARRAY,
|
|
57
|
+
RELATED_PORNSTARS: js_type.ARRAY,
|
|
58
|
+
RELATED_VIDEOS: js_type.OBJECT,
|
|
59
|
+
RESULTS: js_type.OBJECT,
|
|
60
|
+
ACTOR: js_type.STRING,
|
|
61
|
+
VIDEO_NUMBER: js_type.NUMBER,
|
|
62
|
+
VIEW_NUMBER: js_type.STRING,
|
|
63
|
+
RANK: js_type.NUMBER,
|
|
64
|
+
LINK_MP4: js_type.URL,
|
|
65
|
+
LINK_WEBM: js_type.URL,
|
|
66
|
+
RELATIONSHIP_STATUS: js_type.STRING,
|
|
67
|
+
INTERESTED_IN: js_type.STRING,
|
|
68
|
+
GENDER: js_type.STRING,
|
|
69
|
+
BIRTHDAY: js_type.DATE,
|
|
70
|
+
AGE: js_type.NUMBER,
|
|
71
|
+
HEIGHT: js_type.STRING,
|
|
72
|
+
WEIGHT: js_type.STRING,
|
|
73
|
+
ETHNICITY: js_type.STRING,
|
|
74
|
+
VIDEO_VIEWS: js_type.NUMBER,
|
|
75
|
+
PROFILE_VIEWS: js_type.NUMBER,
|
|
76
|
+
VIDEOS_WATCHED: js_type.NUMBER,
|
|
77
|
+
JOINED: js_type.STRING
|
|
78
|
+
},
|
|
79
|
+
queries: {
|
|
80
|
+
PAGE_: 'PAGE'
|
|
81
|
+
},
|
|
82
|
+
links: {
|
|
83
|
+
BASE_URL: 'https://www.pornhub.com',
|
|
84
|
+
SEARCH: 'search',
|
|
85
|
+
VIDEO: 'video',
|
|
86
|
+
MODEL: 'model/'
|
|
87
|
+
},
|
|
88
|
+
types: {
|
|
89
|
+
MODEL: 'model',
|
|
90
|
+
PORNSTAR: 'pornstar'
|
|
91
|
+
},
|
|
92
|
+
errors: {
|
|
93
|
+
DEFAULT: 'An error occured'
|
|
94
|
+
}
|
|
95
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
PROFIL_INFOS_LIST: '.infoPiece',
|
|
3
|
+
model_selectors: {
|
|
4
|
+
TITLE: 'h1',
|
|
5
|
+
RANK_MODEL: '.rankingInfo div:nth-child(1) .big',
|
|
6
|
+
RANK_WEEK_MODEL: '.rankingInfo div:nth-child(2) .big',
|
|
7
|
+
RANK_MONTH_MODEL: '.rankingInfo div:nth-child(3) .big',
|
|
8
|
+
RANK_LAST_MONTH_MODEL: '.rankingInfo div:nth-child(4) .big',
|
|
9
|
+
RANK_YEAR_MODEL: '.rankingInfo div:nth-child(5) .big',
|
|
10
|
+
DESCRIPTION: '.model-details .aboutMeSection div:nth-child(2)',
|
|
11
|
+
VIDEO_NUMBER: '.pornstarVideosCounter'
|
|
12
|
+
},
|
|
13
|
+
model_element_attributs: {
|
|
14
|
+
TITLE: 'innerHTML',
|
|
15
|
+
DESCRIPTION: 'innerHTML',
|
|
16
|
+
RANK_MODEL: 'textContent',
|
|
17
|
+
RANK_WEEK_MODEL: 'textContent',
|
|
18
|
+
RANK_MONTH_MODEL: 'textContent',
|
|
19
|
+
RANK_LAST_MONTH_MODEL: 'textContent',
|
|
20
|
+
RANK_YEAR_MODEL: 'textContent',
|
|
21
|
+
VIDEO_NUMBER: 'textContent'
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
COMMENTS_LIST: '#cmtContent .topCommentBlock',
|
|
3
|
+
RELATED_VIDEOS_LIST: '#relatedVideosCenter li',
|
|
4
|
+
page_element_attributs: {
|
|
5
|
+
TITLE: 'textContent',
|
|
6
|
+
VIEWS: 'textContent',
|
|
7
|
+
UP_VOTES: 'textContent',
|
|
8
|
+
DOWN_VOTES: 'textContent',
|
|
9
|
+
PERCENT: 'textContent',
|
|
10
|
+
AUTHOR: 'textContent',
|
|
11
|
+
AUTHOR_SUBSCRIBER: 'textContent',
|
|
12
|
+
PORNSTARS: 'multi_textContent',
|
|
13
|
+
CATEGORIES: 'multi_textContent',
|
|
14
|
+
TAGS: 'multi_textContent',
|
|
15
|
+
PRODUCTION: 'textContent',
|
|
16
|
+
DURATION: 'dataContent',
|
|
17
|
+
NUMBER_OF_COMMENT: 'textContent',
|
|
18
|
+
AVATAR: 'data-src',
|
|
19
|
+
USERNAME: 'innerHTML',
|
|
20
|
+
DATE: 'innerHTML',
|
|
21
|
+
MESSAGE: 'innerHTML',
|
|
22
|
+
TOTAL_VOTE: 'innerHTML',
|
|
23
|
+
UPLOAD_DATE: 'javascript',
|
|
24
|
+
DESCRIPTION: 'javascript',
|
|
25
|
+
THUMBNAIL_URL: 'javascript'
|
|
26
|
+
},
|
|
27
|
+
page_related_videos_element_attributs: {
|
|
28
|
+
LINK: 'href',
|
|
29
|
+
TITLE: 'title',
|
|
30
|
+
HD: null,
|
|
31
|
+
DURATION: 'innerHTML',
|
|
32
|
+
VIEWS: 'innerHTML',
|
|
33
|
+
PREMIUM: null,
|
|
34
|
+
AUTHOR: 'innerHTML',
|
|
35
|
+
RATINGS: 'innerHTML',
|
|
36
|
+
RELATED_SEARCH: 'multi_textContent',
|
|
37
|
+
RELATED_PORNSTARS: 'multi_textContent',
|
|
38
|
+
ACTOR: 'innerHTML',
|
|
39
|
+
VIDEO_NUMBER: 'innerHTML',
|
|
40
|
+
VIEW_NUMBER: 'innerHTML',
|
|
41
|
+
RANK: 'innerHTML'
|
|
42
|
+
},
|
|
43
|
+
page_selectors: {
|
|
44
|
+
TITLE: '.title-container .title .inlineFree',
|
|
45
|
+
VIEWS: '.count',
|
|
46
|
+
UP_VOTES: '.votesUp',
|
|
47
|
+
DOWN_VOTES: '.votesDown',
|
|
48
|
+
PERCENT: '.percent',
|
|
49
|
+
AUTHOR: '.video-detailed-info .usernameBadgesWrapper a',
|
|
50
|
+
AUTHOR_SUBSCRIBER: '.userInfo span:nth-child(4)',
|
|
51
|
+
PORNSTARS: '.pornstarsWrapper .pstar-list-btn',
|
|
52
|
+
CATEGORIES: '.categoriesWrapper a:not(.add-btn-small)',
|
|
53
|
+
TAGS: '.tagsWrapper a:not(.add-btn-small)',
|
|
54
|
+
PRODUCTION: '.productionWrapper .item',
|
|
55
|
+
DURATION: 'meta[property="video:duration"]',
|
|
56
|
+
NUMBER_OF_COMMENT: '#cmtWrapper h2 span',
|
|
57
|
+
UPLOAD_DATE: 'script[type="application/ld+json"',
|
|
58
|
+
DESCRIPTION: 'script[type="application/ld+json"',
|
|
59
|
+
THUMBNAIL_URL: 'script[type="application/ld+json"'
|
|
60
|
+
},
|
|
61
|
+
comment_selectors: {
|
|
62
|
+
AVATAR: '.avatarTrigger',
|
|
63
|
+
USERNAME: '.usernameLink',
|
|
64
|
+
DATE: '.date',
|
|
65
|
+
MESSAGE: '.commentMessage span',
|
|
66
|
+
TOTAL_VOTE: '.voteTotal'
|
|
67
|
+
},
|
|
68
|
+
related_videos_selectors: {
|
|
69
|
+
LINK: 'a',
|
|
70
|
+
TITLE: '.title a',
|
|
71
|
+
HD: 'a .marker-overlays .hd-thumbnail',
|
|
72
|
+
DURATION: 'a .marker-overlays .duration',
|
|
73
|
+
VIEWS: '.videoDetailsBlock var',
|
|
74
|
+
PREMIUM: 'a .marker-overlays .premiumIcon',
|
|
75
|
+
AUTHOR: '.videoUploaderBlock .usernameWrap a',
|
|
76
|
+
RATINGS: '.rating-container .value'
|
|
77
|
+
},
|
|
78
|
+
javascript: {
|
|
79
|
+
UPLOAD_DATE: 'uploadDate',
|
|
80
|
+
DESCRIPTION: 'description',
|
|
81
|
+
THUMBNAIL_URL: 'thumbnailUrl'
|
|
82
|
+
}
|
|
83
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
sanitizer_by_type: {
|
|
3
|
+
STRING: 'sanitizer_string',
|
|
4
|
+
URL: 'sanitizer_normal',
|
|
5
|
+
URL_PORNHUB: 'sanitizer_url_pornhub',
|
|
6
|
+
NUMBER: 'sanitizer_number',
|
|
7
|
+
NUMBER_KM: 'sanitizer_KM_to_unit',
|
|
8
|
+
NUMBER_SECONDS: 'sanitizer_normal',
|
|
9
|
+
ARRAY: 'sanitizer_array',
|
|
10
|
+
DATE: 'sanitizer_date',
|
|
11
|
+
OBJECT: 'sanitizer_normal',
|
|
12
|
+
BOOLEAN: 'sanitizer_boolean'
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
scrap_by_attribut_type: {
|
|
3
|
+
innerHTML: 'scrap_inner_html',
|
|
4
|
+
dataContent: 'scrap_data_content',
|
|
5
|
+
textContent: 'scrap_text_content',
|
|
6
|
+
multi_textContent: 'scrap_multi_text_content',
|
|
7
|
+
javascript: 'scrap_javascript',
|
|
8
|
+
null: 'scrap_null'
|
|
9
|
+
}
|
|
10
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
primary_search_selectors: {
|
|
3
|
+
RELATED_SEARCH: '.relatedSearches li a',
|
|
4
|
+
RELATED_PORNSTARS: '#relatedPornstarSidebar li a .pornstars-name'
|
|
5
|
+
},
|
|
6
|
+
page_search_element_attributs: {
|
|
7
|
+
LINK: 'href',
|
|
8
|
+
TITLE: 'title',
|
|
9
|
+
HD: null,
|
|
10
|
+
DURATION: 'innerHTML',
|
|
11
|
+
VIEWS: 'innerHTML',
|
|
12
|
+
PREMIUM: null,
|
|
13
|
+
AUTHOR: 'innerHTML',
|
|
14
|
+
RATINGS: 'innerHTML',
|
|
15
|
+
RELATED_SEARCH: 'multi_textContent',
|
|
16
|
+
RELATED_PORNSTARS: 'multi_textContent',
|
|
17
|
+
ACTOR: 'innerHTML',
|
|
18
|
+
VIDEO_NUMBER: 'innerHTML',
|
|
19
|
+
VIEW_NUMBER: 'innerHTML',
|
|
20
|
+
RANK: 'innerHTML'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
GIFS_LIST: '.gifsWrapper .gifVideoBlock',
|
|
3
|
+
gifs_search_selectors: {
|
|
4
|
+
TITLE: '.title',
|
|
5
|
+
THUMBNAIL_URL: '.gifVideo',
|
|
6
|
+
LINK_MP4: '.gifVideo',
|
|
7
|
+
LINK_WEBM: '.gifVideo'
|
|
8
|
+
},
|
|
9
|
+
gifs_element_attributs: {
|
|
10
|
+
TITLE: 'textContent',
|
|
11
|
+
THUMBNAIL_URL: 'data-poster',
|
|
12
|
+
LINK_MP4: 'data-mp4',
|
|
13
|
+
LINK_WEBM: 'data-webm'
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
PORNSTARS_LIST: '#pornstarsSearchResult li .wrap',
|
|
3
|
+
pornstars_search_selectors: {
|
|
4
|
+
ACTOR: '.title',
|
|
5
|
+
VIDEO_NUMBER: '.videosNumber',
|
|
6
|
+
VIEW_NUMBER: '.pstarViews',
|
|
7
|
+
RANK: '.rank_number'
|
|
8
|
+
},
|
|
9
|
+
pornstars_element_attributs: {
|
|
10
|
+
LINK: 'href',
|
|
11
|
+
TITLE: 'title',
|
|
12
|
+
HD: null,
|
|
13
|
+
DURATION: 'innerHTML',
|
|
14
|
+
VIEWS: 'innerHTML',
|
|
15
|
+
PREMIUM: null,
|
|
16
|
+
AUTHOR: 'innerHTML',
|
|
17
|
+
RATINGS: 'innerHTML',
|
|
18
|
+
RELATED_SEARCH: 'multi_textContent',
|
|
19
|
+
RELATED_PORNSTARS: 'multi_textContent',
|
|
20
|
+
ACTOR: 'innerHTML',
|
|
21
|
+
VIDEO_NUMBER: 'innerHTML',
|
|
22
|
+
VIEW_NUMBER: 'innerHTML',
|
|
23
|
+
RANK: 'innerHTML'
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
VIDEOS_LIST: '.nf-videos ul .pcVideoListItem',
|
|
3
|
+
videos_search_selectors: {
|
|
4
|
+
LINK: 'a',
|
|
5
|
+
TITLE: '.title a',
|
|
6
|
+
HD: 'a .marker-overlays .hd-thumbnail',
|
|
7
|
+
DURATION: 'a .marker-overlays .duration',
|
|
8
|
+
VIEWS: '.videoDetailsBlock var',
|
|
9
|
+
PREMIUM: 'a .marker-overlays .premiumIcon',
|
|
10
|
+
AUTHOR: '.videoUploaderBlock .usernameWrap a',
|
|
11
|
+
RATINGS: '.rating-container .value'
|
|
12
|
+
},
|
|
13
|
+
videos_element_attributs: {
|
|
14
|
+
LINK: 'href',
|
|
15
|
+
TITLE: 'title',
|
|
16
|
+
HD: null,
|
|
17
|
+
DURATION: 'innerHTML',
|
|
18
|
+
VIEWS: 'innerHTML',
|
|
19
|
+
PREMIUM: null,
|
|
20
|
+
AUTHOR: 'innerHTML',
|
|
21
|
+
RATINGS: 'innerHTML',
|
|
22
|
+
RELATED_SEARCH: 'multi_textContent',
|
|
23
|
+
RELATED_PORNSTARS: 'multi_textContent',
|
|
24
|
+
ACTOR: 'innerHTML',
|
|
25
|
+
VIDEO_NUMBER: 'innerHTML',
|
|
26
|
+
VIEW_NUMBER: 'innerHTML',
|
|
27
|
+
RANK: 'innerHTML'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Regroup all the general functions that can be usefull anywhere
|
|
3
|
+
* @author Justal Kevin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
/**
|
|
10
|
+
* Remove duplicated string inside an array
|
|
11
|
+
*
|
|
12
|
+
* @params {array} array The array with possible duplicate of same data
|
|
13
|
+
* @return {array} The array with unique value
|
|
14
|
+
**/
|
|
15
|
+
remove_duplicate: array => {
|
|
16
|
+
return array.filter((item, index) => array.indexOf(item) === index);
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* Check if the parameter is defined and exist
|
|
20
|
+
*
|
|
21
|
+
* @params {string} parameter The parameter we want to test
|
|
22
|
+
* @return {boolean} True if the parameter exist or else false
|
|
23
|
+
**/
|
|
24
|
+
is_parameter_missing: parameter => {
|
|
25
|
+
return parameter === null || parameter === '' || parameter === undefined;
|
|
26
|
+
},
|
|
27
|
+
selectors_restriction: (keys, selectors) => {
|
|
28
|
+
return Object.fromEntries(Object.keys(selectors).map(selector => {
|
|
29
|
+
if (keys.includes(selector)) {
|
|
30
|
+
return [selector, selectors[selector]];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return null;
|
|
34
|
+
}).filter(x => x));
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Regroup all the functions use for sanitize the informations coming and going in the api
|
|
3
|
+
* @author Justal Kevin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const consts_global = require('./../constants/consts_global');
|
|
9
|
+
const consts_sanitizer = require('./../constants/consts_sanitizer');
|
|
10
|
+
const utils_global = require('./utils_global');
|
|
11
|
+
const Entities = require('html-entities').AllHtmlEntities;
|
|
12
|
+
const entities = new Entities();
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
/**
|
|
16
|
+
* Sanitize the number of pornhub to a javascript type Number
|
|
17
|
+
* Most of the number in pornhub contains letters or commas, so it need to be filter
|
|
18
|
+
*
|
|
19
|
+
* @params {string} value The string that represents a number
|
|
20
|
+
* @return {number} The string converted into a number javascript
|
|
21
|
+
**/
|
|
22
|
+
sanitizer_number: value => {
|
|
23
|
+
value = value.replace(/[()&A-Za-z,%]/g, '');
|
|
24
|
+
value = Number(value);
|
|
25
|
+
return value;
|
|
26
|
+
},
|
|
27
|
+
/**
|
|
28
|
+
* Sanitize the string from pornhub to a single ligne.
|
|
29
|
+
* This function remove the tabs, break line and trim the string
|
|
30
|
+
*
|
|
31
|
+
* @params {string} value The string that we want to sanitize
|
|
32
|
+
* @return {string} The string sanitized
|
|
33
|
+
**/
|
|
34
|
+
sanitizer_string: value => {
|
|
35
|
+
value = value.replace(/[\t\n]/g, '');
|
|
36
|
+
value = value.trim();
|
|
37
|
+
value = entities.decode(value);
|
|
38
|
+
return value;
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* Convert a string or number into a boolean
|
|
42
|
+
*
|
|
43
|
+
* @params {(string|number)} value The string or number representing a boolean
|
|
44
|
+
* @return {boolean} True or False depending of the value passed
|
|
45
|
+
**/
|
|
46
|
+
sanitizer_boolean: value => {
|
|
47
|
+
return Boolean(value);
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Sanitize the key passed to the API
|
|
51
|
+
* Replace space and : and put the key in uppercase
|
|
52
|
+
*
|
|
53
|
+
* @params {string} value The API key that we want to sanitize
|
|
54
|
+
* @return {string} The key sanitized
|
|
55
|
+
**/
|
|
56
|
+
sanitizer_key: value => {
|
|
57
|
+
value = module.exports.sanitizer_string(value);
|
|
58
|
+
value = value.replace(/\s/g, '_');
|
|
59
|
+
value = value.replace(/:/g, '');
|
|
60
|
+
value = value.toUpperCase();
|
|
61
|
+
return value;
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Convert the value with an unit to a number javascript
|
|
65
|
+
*
|
|
66
|
+
* @params {string} value The string with an unit representing a number
|
|
67
|
+
* @return {number} The javascript number
|
|
68
|
+
**/
|
|
69
|
+
sanitizer_KM_to_unit: value => {
|
|
70
|
+
if (value.includes('K')) {
|
|
71
|
+
return Number(value.replace('K', '')) * 1000;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (value.includes('M')) {
|
|
75
|
+
return Number(value.replace('M', '')) * 1000000;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return value;
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* Convert a string date to a javascript date
|
|
82
|
+
*
|
|
83
|
+
* @params {string} value A string representing a date
|
|
84
|
+
* @return {Date} The javascript date representing the value passed in argument
|
|
85
|
+
**/
|
|
86
|
+
sanitizer_date: value => {
|
|
87
|
+
return new Date(value);
|
|
88
|
+
},
|
|
89
|
+
/**
|
|
90
|
+
* Create a complete url pornhub from a route passed in argument
|
|
91
|
+
*
|
|
92
|
+
* @params {string} value A pornhub route
|
|
93
|
+
* @return {string} A complete url pornhub
|
|
94
|
+
**/
|
|
95
|
+
sanitizer_url_pornhub: value => {
|
|
96
|
+
return consts_global.links.BASE_URL + value;
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Simply return the variable passed in argument
|
|
100
|
+
* This function is used for getting the function sanitizer possible and givig every type a function
|
|
101
|
+
*
|
|
102
|
+
* @params {Object} A value
|
|
103
|
+
* @return {Object} The same value without any change
|
|
104
|
+
**/
|
|
105
|
+
sanitizer_normal: value => {
|
|
106
|
+
return value;
|
|
107
|
+
},
|
|
108
|
+
/**
|
|
109
|
+
* Sanitize every string element of an array of string
|
|
110
|
+
* and remove duplicate value
|
|
111
|
+
*
|
|
112
|
+
* @params {array} array An array containing string
|
|
113
|
+
* @return {array} Return the array with unique value and sanitized string
|
|
114
|
+
**/
|
|
115
|
+
sanitizer_array: array => {
|
|
116
|
+
if (Array.isArray(array)) {
|
|
117
|
+
array = array.map(x => module.exports.sanitizer_string(x));
|
|
118
|
+
return utils_global.remove_duplicate(array);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return module.exports.sanitizer_string(array);
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Sanitize all the data receive from pornhub to a more flexible format
|
|
125
|
+
*
|
|
126
|
+
* @params {Object} datas The datas that we want to sanitize
|
|
127
|
+
* @return {Object} The datas sanitized
|
|
128
|
+
**/
|
|
129
|
+
sanitizer: datas => {
|
|
130
|
+
const rsl = Object.keys(consts_global.type).map(x => {
|
|
131
|
+
if (datas[x] === null || datas[x] === undefined) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Choose the sanitizer to apply to the current value depending of the type
|
|
136
|
+
const sanitizer = consts_sanitizer.sanitizer_by_type[consts_global.type[x].toUpperCase()];
|
|
137
|
+
const sanitize_data = module.exports[sanitizer](datas[x]);
|
|
138
|
+
|
|
139
|
+
return [x.toLowerCase(), sanitize_data];
|
|
140
|
+
}).filter(x => x);
|
|
141
|
+
|
|
142
|
+
return Object.fromEntries(rsl);
|
|
143
|
+
}
|
|
144
|
+
};
|