xvideosx 1.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/.codeclimate.yml +12 -0
- package/.editorconfig +12 -0
- package/.eslintignore +0 -0
- package/.eslintrc.yml +26 -0
- package/.gitattributes +107 -0
- package/.github/workflows/node.js.yml +29 -0
- package/.travis.yml +13 -0
- package/AUTHORS +2 -0
- package/CODE_OF_CONDUCT.md +5 -0
- package/LICENSE +29 -0
- package/README.md +188 -0
- package/index.js +1 -0
- package/lib/api/base.js +14 -0
- package/lib/api/index.js +5 -0
- package/lib/api/videos/best/best.js +19 -0
- package/lib/api/videos/best/best.spec.js +138 -0
- package/lib/api/videos/best/createHasNextFunction.js +10 -0
- package/lib/api/videos/best/createHasPreviousFunction.js +10 -0
- package/lib/api/videos/best/createNextFunction.js +12 -0
- package/lib/api/videos/best/createPreviousFunction.js +12 -0
- package/lib/api/videos/best/createRefreshFunction.js +11 -0
- package/lib/api/videos/best/index.js +1 -0
- package/lib/api/videos/best/parseResponse.js +45 -0
- package/lib/api/videos/best/parseVideo.js +27 -0
- package/lib/api/videos/dashboard/createHasNextFunction.js +10 -0
- package/lib/api/videos/dashboard/createHasPreviousFunction.js +10 -0
- package/lib/api/videos/dashboard/createNextFunction.js +12 -0
- package/lib/api/videos/dashboard/createPreviousFunction.js +12 -0
- package/lib/api/videos/dashboard/createRefreshFunction.js +11 -0
- package/lib/api/videos/dashboard/dashboard.js +14 -0
- package/lib/api/videos/dashboard/dashboard.spec.js +138 -0
- package/lib/api/videos/dashboard/index.js +1 -0
- package/lib/api/videos/dashboard/parseResponse.js +45 -0
- package/lib/api/videos/dashboard/parseVideo.js +27 -0
- package/lib/api/videos/details/details.js +48 -0
- package/lib/api/videos/details/details.spec.js +49 -0
- package/lib/api/videos/details/index.js +1 -0
- package/lib/api/videos/fresh/createHasNextFunction.js +10 -0
- package/lib/api/videos/fresh/createHasPreviousFunction.js +10 -0
- package/lib/api/videos/fresh/createNextFunction.js +12 -0
- package/lib/api/videos/fresh/createPreviousFunction.js +12 -0
- package/lib/api/videos/fresh/createRefreshFunction.js +11 -0
- package/lib/api/videos/fresh/fresh.js +14 -0
- package/lib/api/videos/fresh/fresh.spec.js +138 -0
- package/lib/api/videos/fresh/index.js +1 -0
- package/lib/api/videos/fresh/parseResponse.js +45 -0
- package/lib/api/videos/fresh/parseVideo.js +27 -0
- package/lib/api/videos/index.js +8 -0
- package/lib/api/videos/search/createHasNextFunction.js +10 -0
- package/lib/api/videos/search/createHasPreviousFunction.js +10 -0
- package/lib/api/videos/search/createNextFunction.js +12 -0
- package/lib/api/videos/search/createPreviousFunction.js +12 -0
- package/lib/api/videos/search/createRefreshFunction.js +11 -0
- package/lib/api/videos/search/index.js +1 -0
- package/lib/api/videos/search/parseResponse.js +45 -0
- package/lib/api/videos/search/parseVideo.js +27 -0
- package/lib/api/videos/search/search.js +23 -0
- package/lib/api/videos/search/search.spec.js +138 -0
- package/lib/api/videos/verified/createHasNextFunction.js +10 -0
- package/lib/api/videos/verified/createHasPreviousFunction.js +10 -0
- package/lib/api/videos/verified/createNextFunction.js +12 -0
- package/lib/api/videos/verified/createPreviousFunction.js +12 -0
- package/lib/api/videos/verified/createRefreshFunction.js +11 -0
- package/lib/api/videos/verified/index.js +1 -0
- package/lib/api/videos/verified/parseResponse.js +45 -0
- package/lib/api/videos/verified/parseVideo.js +27 -0
- package/lib/api/videos/verified/verified.js +14 -0
- package/lib/api/videos/verified/verified.spec.js +138 -0
- package/lib/index.js +1 -0
- package/lib/xvideos.js +1 -0
- package/lib/xvideos.spec.js +22 -0
- package/package.json +44 -0
package/.codeclimate.yml
ADDED
package/.editorconfig
ADDED
package/.eslintignore
ADDED
|
File without changes
|
package/.eslintrc.yml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
extends: airbnb-base
|
|
2
|
+
plugins:
|
|
3
|
+
- import
|
|
4
|
+
rules:
|
|
5
|
+
no-shadow: off
|
|
6
|
+
import/no-dynamic-require: off
|
|
7
|
+
global-require: off
|
|
8
|
+
no-param-reassign: off
|
|
9
|
+
consistent-return: off
|
|
10
|
+
arrow-body-style: off
|
|
11
|
+
no-underscore-dangle: off
|
|
12
|
+
import/extensions: off
|
|
13
|
+
prefer-destructuring: off
|
|
14
|
+
strict: off
|
|
15
|
+
max-len: off
|
|
16
|
+
no-console: off
|
|
17
|
+
no-restricted-globals: off
|
|
18
|
+
globals:
|
|
19
|
+
process: readonly
|
|
20
|
+
describe: readonly
|
|
21
|
+
before: readonly
|
|
22
|
+
after: readonly
|
|
23
|
+
beforeEach: readonly
|
|
24
|
+
suite: readonly
|
|
25
|
+
test: readonly
|
|
26
|
+
it: readonly
|
package/.gitattributes
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# These settings are for any web project
|
|
2
|
+
|
|
3
|
+
# Handle line endings automatically for files detected as text
|
|
4
|
+
# and leave all files detected as binary untouched.
|
|
5
|
+
# * text=auto
|
|
6
|
+
# NOTE - originally I had the above line un-commented. it caused me a lot of grief related to line endings because I was dealing with WordPress plugins and the website changing line endings out if a user modified a plugin through the web interface. commenting this line out seems to have alleviated the git chaos where simply switching to a branch caused it to believe 500 files were modified.
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# The above will handle all files NOT found below
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
## These files are text and should be normalized (Convert crlf => lf)
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
# source code
|
|
17
|
+
*.php text
|
|
18
|
+
*.css text
|
|
19
|
+
*.sass text
|
|
20
|
+
*.scss text
|
|
21
|
+
*.less text
|
|
22
|
+
*.styl text
|
|
23
|
+
*.js text
|
|
24
|
+
*.coffee text
|
|
25
|
+
*.json text
|
|
26
|
+
*.htm text
|
|
27
|
+
*.html text
|
|
28
|
+
*.xml text
|
|
29
|
+
*.svg text
|
|
30
|
+
*.txt text
|
|
31
|
+
*.ini text
|
|
32
|
+
*.inc text
|
|
33
|
+
*.pl text
|
|
34
|
+
*.rb text
|
|
35
|
+
*.py text
|
|
36
|
+
*.scm text
|
|
37
|
+
*.sql text
|
|
38
|
+
*.sh text
|
|
39
|
+
*.bat text
|
|
40
|
+
|
|
41
|
+
# templates
|
|
42
|
+
*.ejs text
|
|
43
|
+
*.hbt text
|
|
44
|
+
*.jade text
|
|
45
|
+
*.haml text
|
|
46
|
+
*.hbs text
|
|
47
|
+
*.dot text
|
|
48
|
+
*.tmpl text
|
|
49
|
+
*.phtml text
|
|
50
|
+
|
|
51
|
+
# server config
|
|
52
|
+
.htaccess text
|
|
53
|
+
|
|
54
|
+
# git config
|
|
55
|
+
.gitattributes text
|
|
56
|
+
.gitignore text
|
|
57
|
+
.gitconfig text
|
|
58
|
+
|
|
59
|
+
# code analysis config
|
|
60
|
+
.jshintrc text
|
|
61
|
+
.jscsrc text
|
|
62
|
+
.jshintignore text
|
|
63
|
+
.csslintrc text
|
|
64
|
+
|
|
65
|
+
# misc config
|
|
66
|
+
*.yaml text
|
|
67
|
+
*.yml text
|
|
68
|
+
.editorconfig text
|
|
69
|
+
|
|
70
|
+
# build config
|
|
71
|
+
*.npmignore text
|
|
72
|
+
*.bowerrc text
|
|
73
|
+
|
|
74
|
+
# Heroku
|
|
75
|
+
Procfile text
|
|
76
|
+
.slugignore text
|
|
77
|
+
|
|
78
|
+
# Documentation
|
|
79
|
+
*.md text
|
|
80
|
+
LICENSE text
|
|
81
|
+
AUTHORS text
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
## These files are binary and should be left untouched
|
|
86
|
+
#
|
|
87
|
+
|
|
88
|
+
# (binary is a macro for -text -diff)
|
|
89
|
+
*.png binary
|
|
90
|
+
*.jpg binary
|
|
91
|
+
*.jpeg binary
|
|
92
|
+
*.gif binary
|
|
93
|
+
*.ico binary
|
|
94
|
+
*.mov binary
|
|
95
|
+
*.mp4 binary
|
|
96
|
+
*.mp3 binary
|
|
97
|
+
*.flv binary
|
|
98
|
+
*.fla binary
|
|
99
|
+
*.swf binary
|
|
100
|
+
*.gz binary
|
|
101
|
+
*.zip binary
|
|
102
|
+
*.7z binary
|
|
103
|
+
*.ttf binary
|
|
104
|
+
*.eot binary
|
|
105
|
+
*.woff binary
|
|
106
|
+
*.pyc binary
|
|
107
|
+
*.pdf binary
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: Node.js CI
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ master ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ master ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
node-version: [10.x, 12.x, 14.x]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v2
|
|
23
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
24
|
+
uses: actions/setup-node@v1
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
- run: npm ci
|
|
28
|
+
- run: npm run build --if-present
|
|
29
|
+
- run: npm test
|
package/.travis.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
language: node_js
|
|
2
|
+
sudo: required
|
|
3
|
+
addons:
|
|
4
|
+
chrome: stable
|
|
5
|
+
node_js:
|
|
6
|
+
- 12
|
|
7
|
+
install:
|
|
8
|
+
- npm install
|
|
9
|
+
- npm install -g codeclimate-test-reporter
|
|
10
|
+
script:
|
|
11
|
+
- npm run eslint
|
|
12
|
+
- npm run coverage
|
|
13
|
+
- codeclimate-test-reporter < coverage/lcov.info
|
package/AUTHORS
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018, Rodrigo Gomes da Silva
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# xvideos
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/rodrigogs/xvideos)
|
|
4
|
+
[](https://codeclimate.com/github/rodrigogs/xvideos)
|
|
5
|
+
[](https://codeclimate.com/github/rodrigogs/xvideos/coverage)
|
|
6
|
+
|
|
7
|
+
A a [Node.js](https://nodejs.org) [xvideos.com](xvideos.com) API library.
|
|
8
|
+
|
|
9
|
+
### Install
|
|
10
|
+
```bash
|
|
11
|
+
$ npm install @rodrigogs/xvideos
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Usage
|
|
15
|
+
```javascript
|
|
16
|
+
const xvideos = require('@rodrigogs/xvideos');
|
|
17
|
+
|
|
18
|
+
//-- Inside an async function --//
|
|
19
|
+
|
|
20
|
+
// Retrieve fresh videos
|
|
21
|
+
const fresh = await xvideos.videos.fresh({ page: 1 });
|
|
22
|
+
console.log(fresh.videos); // { url, path, title, duration, profile: { name, url }, views, }
|
|
23
|
+
console.log(fresh.pagination.current); // 1
|
|
24
|
+
console.log(fresh.pagination.pages); // [1, 2, 3, 4, 5...]
|
|
25
|
+
console.log(fresh.hasNext()); // true
|
|
26
|
+
console.log(fresh.hasPrevious()); // false
|
|
27
|
+
|
|
28
|
+
const nextPage = await fresh.next();
|
|
29
|
+
console.log(nextPage.pagination.current); // 2
|
|
30
|
+
console.log(nextPage.hasNext()); // true
|
|
31
|
+
console.log(nextPage.hasPrevious()); // true
|
|
32
|
+
|
|
33
|
+
const previousPage = await fresh.previous();
|
|
34
|
+
console.log(previousPage.pagination.current); // 1
|
|
35
|
+
console.log(previousPage.hasNext()); // true
|
|
36
|
+
console.log(previousPage.hasPrevious()); // tfalse
|
|
37
|
+
|
|
38
|
+
const detail = await xvideos.videos.details(fresh.videos[0]); /**
|
|
39
|
+
{
|
|
40
|
+
title,
|
|
41
|
+
duration,
|
|
42
|
+
image,
|
|
43
|
+
videoType,
|
|
44
|
+
videoWidth,
|
|
45
|
+
videoHeigth,
|
|
46
|
+
views,
|
|
47
|
+
files: {
|
|
48
|
+
low,
|
|
49
|
+
high,
|
|
50
|
+
HLS,
|
|
51
|
+
thumb,
|
|
52
|
+
thumb69,
|
|
53
|
+
thumbSlide,
|
|
54
|
+
thumbSlideBig
|
|
55
|
+
}
|
|
56
|
+
} **/
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### API
|
|
60
|
+
* Retrieve [dashboard videos](https://www.xvideos.com)
|
|
61
|
+
```javascript
|
|
62
|
+
const dashboardList = await xvideos.videos.dashboard({ page: 1 });
|
|
63
|
+
```
|
|
64
|
+
* Is there a next page?
|
|
65
|
+
```javascript
|
|
66
|
+
console.log(deshboardList.hasNext()); // true or false
|
|
67
|
+
```
|
|
68
|
+
* Is there a previous page?
|
|
69
|
+
```javascript
|
|
70
|
+
console.log(deshboardList.hasPrevious()); // true or false
|
|
71
|
+
```
|
|
72
|
+
* Refresh page videos
|
|
73
|
+
```javascript
|
|
74
|
+
const refreshedVideos = await deshboardList.refresh();
|
|
75
|
+
```
|
|
76
|
+
* Retrieve next deshboard page videos
|
|
77
|
+
```javascript
|
|
78
|
+
const nextVideos = await deshboardList.next();
|
|
79
|
+
```
|
|
80
|
+
* Retrieve previous deshboard page videos
|
|
81
|
+
```javascript
|
|
82
|
+
const previousVideos = await deshboardList.previous();
|
|
83
|
+
```
|
|
84
|
+
* Retrieve [fresh videos](https://www.xvideos.com/new/1)
|
|
85
|
+
```javascript
|
|
86
|
+
const freshList = await xvideos.videos.fresh({ page: 1 });
|
|
87
|
+
```
|
|
88
|
+
* Is there a next page?
|
|
89
|
+
```javascript
|
|
90
|
+
console.log(freshList.hasNext()); // true or false
|
|
91
|
+
```
|
|
92
|
+
* Is there a previous page?
|
|
93
|
+
```javascript
|
|
94
|
+
console.log(freshList.hasPrevious()); // true or false
|
|
95
|
+
```
|
|
96
|
+
* Refresh page videos
|
|
97
|
+
```javascript
|
|
98
|
+
const refreshedVideos = await freshList.refresh();
|
|
99
|
+
```
|
|
100
|
+
* Retrieve next fresh page videos
|
|
101
|
+
```javascript
|
|
102
|
+
const nextVideos = await freshList.next();
|
|
103
|
+
```
|
|
104
|
+
* Retrieve previous fresh page videos
|
|
105
|
+
```javascript
|
|
106
|
+
const previousVideos = await freshList.previous();
|
|
107
|
+
```
|
|
108
|
+
* Retrieve [best videos](https://www.xvideos.com/best)
|
|
109
|
+
```javascript
|
|
110
|
+
const bestList = await xvideos.videos.best({ year: '2018', month: '02', page: 1 });
|
|
111
|
+
```
|
|
112
|
+
* Is there a next page?
|
|
113
|
+
```javascript
|
|
114
|
+
console.log(bestList.hasNext()); // true or false
|
|
115
|
+
```
|
|
116
|
+
* Is there a previous page?
|
|
117
|
+
```javascript
|
|
118
|
+
console.log(bestList.hasPrevious()); // true or false
|
|
119
|
+
```
|
|
120
|
+
* Refresh page videos
|
|
121
|
+
```javascript
|
|
122
|
+
const refreshedVideos = await bestList.refresh();
|
|
123
|
+
```
|
|
124
|
+
* Retrieve next best page videos
|
|
125
|
+
```javascript
|
|
126
|
+
const nextVideos = await bestList.next();
|
|
127
|
+
```
|
|
128
|
+
* Retrieve previous best page videos
|
|
129
|
+
```javascript
|
|
130
|
+
const previousVideos = await bestList.previous();
|
|
131
|
+
```
|
|
132
|
+
* Retrieve [verified videos](https://www.xvideos.com/verified/videos)
|
|
133
|
+
```javascript
|
|
134
|
+
const verifiedList = await xvideos.videos.verified({ page: 1 });
|
|
135
|
+
```
|
|
136
|
+
* Is there a next page?
|
|
137
|
+
```javascript
|
|
138
|
+
console.log(verifiedList.hasNext()); // true or false
|
|
139
|
+
```
|
|
140
|
+
* Is there a previous page?
|
|
141
|
+
```javascript
|
|
142
|
+
console.log(verifiedList.hasPrevious()); // true or false
|
|
143
|
+
```
|
|
144
|
+
* Refresh page videos
|
|
145
|
+
```javascript
|
|
146
|
+
const refreshedVideos = await verifiedList.refresh();
|
|
147
|
+
```
|
|
148
|
+
* Retrieve next verified page videos
|
|
149
|
+
```javascript
|
|
150
|
+
const nextVideos = await verifiedList.next();
|
|
151
|
+
```
|
|
152
|
+
* Retrieve previous verified page videos
|
|
153
|
+
```javascript
|
|
154
|
+
const previousVideos = await verifiedList.previous();
|
|
155
|
+
```
|
|
156
|
+
* Retrieve [video details](https://www.xvideos.com/video36638661/chaturbate_lulacum69_30-05-2018)
|
|
157
|
+
```javascript
|
|
158
|
+
const details = await xvideos.videos.details({ url: 'https://www.xvideos.com/video36638661/chaturbate_lulacum69_30-05-2018' });
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
* Filter [videos](https://www.xvideos.com/?k=threesome)
|
|
162
|
+
```javascript
|
|
163
|
+
const videos = await xvideos.videos.details({ k: 'threesome' });
|
|
164
|
+
const videos = await xvideos.videos.details({ k: 'public', page: 5 });
|
|
165
|
+
```
|
|
166
|
+
* Is there a next page?
|
|
167
|
+
```javascript
|
|
168
|
+
console.log(videos.hasNext()); // true or false
|
|
169
|
+
```
|
|
170
|
+
* Is there a previous page?
|
|
171
|
+
```javascript
|
|
172
|
+
console.log(videos.hasPrevious()); // true or false
|
|
173
|
+
```
|
|
174
|
+
* Refresh page videos
|
|
175
|
+
```javascript
|
|
176
|
+
const refreshedVideos = await videos.refresh();
|
|
177
|
+
```
|
|
178
|
+
* Retrieve next verified page videos
|
|
179
|
+
```javascript
|
|
180
|
+
const nextVideos = await videos.next();
|
|
181
|
+
```
|
|
182
|
+
* Retrieve previous verified page videos
|
|
183
|
+
```javascript
|
|
184
|
+
const previousVideos = await videos.previous();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### License
|
|
188
|
+
[Licence](https://github.com/4CROS2/xvideos/blob/main/LICENSE) © Yeferson Yair Tejada Rivas
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib');
|
package/lib/api/base.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://www.xvideos.com';
|
|
4
|
+
|
|
5
|
+
const createRequest = (options = {}) => {
|
|
6
|
+
return axios.create({ baseURL: BASE_URL, ...options });
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const base = {
|
|
10
|
+
BASE_URL,
|
|
11
|
+
createRequest,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = base;
|
package/lib/api/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const base = require('../../base');
|
|
2
|
+
const parseResponse = require('./parseResponse');
|
|
3
|
+
|
|
4
|
+
const PATH = '/best';
|
|
5
|
+
|
|
6
|
+
const best = async ({ year, month, page = 1 } = {}) => {
|
|
7
|
+
if (!year) year = new Date().getFullYear();
|
|
8
|
+
year = String(year);
|
|
9
|
+
if (!month) month = new Date().getMonth() + 1; // Date.getMonth is zero based
|
|
10
|
+
month = String(month).padStart(2, '0');
|
|
11
|
+
|
|
12
|
+
if (page < 1 || page > Number.MAX_SAFE_INTEGER) {
|
|
13
|
+
throw new Error(`Invalid page: ${page}`);
|
|
14
|
+
}
|
|
15
|
+
const request = base.createRequest();
|
|
16
|
+
return parseResponse(page, await request.get(`${PATH}/${year}-${month}/${page === 0 ? '' : page}`));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports = best;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/* eslint-disable padded-blocks */
|
|
2
|
+
|
|
3
|
+
const chai = require('chai');
|
|
4
|
+
const best = require('./best');
|
|
5
|
+
|
|
6
|
+
before(() => {
|
|
7
|
+
chai.should();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('api/videos/best', () => {
|
|
11
|
+
|
|
12
|
+
it('should list best video pages', async () => {
|
|
13
|
+
const list = await best({ page: 2 });
|
|
14
|
+
|
|
15
|
+
list.should.be.an('object');
|
|
16
|
+
list.pagination.should.be.an('object');
|
|
17
|
+
list.pagination.page.should.be.equals(2);
|
|
18
|
+
list.pagination.pages.should.be.an('array');
|
|
19
|
+
list.pagination.pages[0].should.be.a('number');
|
|
20
|
+
list.hasNext.should.be.a('function');
|
|
21
|
+
list.hasNext().should.be.equals(true);
|
|
22
|
+
list.hasPrevious.should.be.a('function');
|
|
23
|
+
list.hasPrevious().should.be.equals(true);
|
|
24
|
+
list.next.should.be.a('function');
|
|
25
|
+
list.previous.should.be.a('function');
|
|
26
|
+
list.videos.should.be.an('array');
|
|
27
|
+
list.videos.forEach((video) => {
|
|
28
|
+
video.should.be.an('object');
|
|
29
|
+
video.should.have.ownPropertyDescriptor('duration');
|
|
30
|
+
video.duration.should.be.a('string');
|
|
31
|
+
video.should.have.ownPropertyDescriptor('path');
|
|
32
|
+
video.path.should.be.a('string');
|
|
33
|
+
video.should.have.ownPropertyDescriptor('profile');
|
|
34
|
+
video.profile.should.be.an('object');
|
|
35
|
+
video.profile.should.have.ownPropertyDescriptor('name');
|
|
36
|
+
video.profile.name.should.be.an('string');
|
|
37
|
+
video.profile.should.have.ownPropertyDescriptor('url');
|
|
38
|
+
video.profile.url.should.be.an('string');
|
|
39
|
+
video.should.have.ownPropertyDescriptor('title');
|
|
40
|
+
video.title.should.be.a('string');
|
|
41
|
+
video.should.have.ownPropertyDescriptor('url');
|
|
42
|
+
video.url.should.be.a('string');
|
|
43
|
+
video.should.have.ownPropertyDescriptor('views');
|
|
44
|
+
video.views.should.be.a('string');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const previous = await list.previous();
|
|
48
|
+
previous.should.be.an('object');
|
|
49
|
+
previous.pagination.should.be.an('object');
|
|
50
|
+
previous.pagination.page.should.be.equals(1);
|
|
51
|
+
previous.pagination.pages.should.be.an('array');
|
|
52
|
+
previous.pagination.pages[0].should.be.a('number');
|
|
53
|
+
previous.hasNext.should.be.a('function');
|
|
54
|
+
previous.hasNext().should.be.equals(true);
|
|
55
|
+
previous.hasPrevious.should.be.a('function');
|
|
56
|
+
previous.hasPrevious().should.be.equals(false);
|
|
57
|
+
previous.next.should.be.a('function');
|
|
58
|
+
previous.previous.should.be.a('function');
|
|
59
|
+
previous.videos.should.be.an('array');
|
|
60
|
+
previous.videos.forEach((video) => {
|
|
61
|
+
video.should.be.an('object');
|
|
62
|
+
video.should.have.ownPropertyDescriptor('duration');
|
|
63
|
+
video.duration.should.be.a('string');
|
|
64
|
+
video.should.have.ownPropertyDescriptor('path');
|
|
65
|
+
video.path.should.be.a('string');
|
|
66
|
+
video.should.have.ownPropertyDescriptor('profile');
|
|
67
|
+
video.profile.should.be.an('object');
|
|
68
|
+
video.profile.should.have.ownPropertyDescriptor('name');
|
|
69
|
+
video.profile.name.should.be.an('string');
|
|
70
|
+
video.profile.should.have.ownPropertyDescriptor('url');
|
|
71
|
+
video.profile.url.should.be.an('string');
|
|
72
|
+
video.should.have.ownPropertyDescriptor('title');
|
|
73
|
+
video.title.should.be.a('string');
|
|
74
|
+
video.should.have.ownPropertyDescriptor('url');
|
|
75
|
+
video.url.should.be.a('string');
|
|
76
|
+
video.should.have.ownPropertyDescriptor('views');
|
|
77
|
+
video.views.should.be.a('string');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const next = await list.next();
|
|
81
|
+
next.should.be.an('object');
|
|
82
|
+
next.pagination.should.be.an('object');
|
|
83
|
+
next.pagination.page.should.be.equals(3);
|
|
84
|
+
next.pagination.pages.should.be.an('array');
|
|
85
|
+
next.pagination.pages[0].should.be.a('number');
|
|
86
|
+
next.hasNext.should.be.a('function');
|
|
87
|
+
next.hasNext().should.be.equals(true);
|
|
88
|
+
next.hasPrevious.should.be.a('function');
|
|
89
|
+
next.hasPrevious().should.be.equals(true);
|
|
90
|
+
next.next.should.be.a('function');
|
|
91
|
+
next.previous.should.be.a('function');
|
|
92
|
+
next.videos.should.be.an('array');
|
|
93
|
+
next.videos.forEach((video) => {
|
|
94
|
+
video.should.be.an('object');
|
|
95
|
+
video.should.have.ownPropertyDescriptor('duration');
|
|
96
|
+
video.duration.should.be.a('string');
|
|
97
|
+
video.should.have.ownPropertyDescriptor('path');
|
|
98
|
+
video.path.should.be.a('string');
|
|
99
|
+
video.should.have.ownPropertyDescriptor('profile');
|
|
100
|
+
video.profile.should.be.an('object');
|
|
101
|
+
video.profile.should.have.ownPropertyDescriptor('name');
|
|
102
|
+
video.profile.name.should.be.an('string');
|
|
103
|
+
video.profile.should.have.ownPropertyDescriptor('url');
|
|
104
|
+
video.profile.url.should.be.an('string');
|
|
105
|
+
video.should.have.ownPropertyDescriptor('title');
|
|
106
|
+
video.title.should.be.a('string');
|
|
107
|
+
video.should.have.ownPropertyDescriptor('url');
|
|
108
|
+
video.url.should.be.a('string');
|
|
109
|
+
video.should.have.ownPropertyDescriptor('views');
|
|
110
|
+
video.views.should.be.a('string');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await list.refresh();
|
|
114
|
+
}).timeout(10000);
|
|
115
|
+
|
|
116
|
+
it('should fail when page parameter is beyond limit', async () => {
|
|
117
|
+
let err;
|
|
118
|
+
try {
|
|
119
|
+
await best({ page: Number.MAX_SAFE_INTEGER + 1 });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
err = error;
|
|
122
|
+
} finally {
|
|
123
|
+
err.should.be.an('error');
|
|
124
|
+
}
|
|
125
|
+
}).timeout(10000);
|
|
126
|
+
|
|
127
|
+
it('should fail when page parameter is less than 1', async () => {
|
|
128
|
+
let err;
|
|
129
|
+
try {
|
|
130
|
+
await best({ page: 0 });
|
|
131
|
+
} catch (error) {
|
|
132
|
+
err = error;
|
|
133
|
+
} finally {
|
|
134
|
+
err.should.be.an('error');
|
|
135
|
+
}
|
|
136
|
+
}).timeout(10000);
|
|
137
|
+
|
|
138
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const hasNextFunction = (currentPage, pages) => () => {
|
|
2
|
+
return currentPage < Math.max(...pages);
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
const createHasNextFunction = (pagination) => {
|
|
6
|
+
const { page, pages } = pagination;
|
|
7
|
+
return hasNextFunction(page, pages);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
module.exports = createHasNextFunction;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const hasPreviousFunction = (currentPage, pages) => () => {
|
|
2
|
+
return currentPage > Math.min(...pages);
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
const createHasPreviousFunction = (pagination) => {
|
|
6
|
+
const { page, pages } = pagination;
|
|
7
|
+
return hasPreviousFunction(page, pages);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
module.exports = createHasPreviousFunction;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const nextFunction = (currentPage) => () => {
|
|
2
|
+
const best = require('./best');
|
|
3
|
+
const next = currentPage + 1;
|
|
4
|
+
return best({ page: next });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const createNextFunction = (pagination) => {
|
|
8
|
+
const { page } = pagination;
|
|
9
|
+
return nextFunction(page);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports = createNextFunction;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const previousFunction = (currentPage) => () => {
|
|
2
|
+
const best = require('./best');
|
|
3
|
+
const previous = currentPage - 1;
|
|
4
|
+
return best({ page: previous });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const createPreviousFunction = (pagination) => {
|
|
8
|
+
const { page } = pagination;
|
|
9
|
+
return previousFunction(page);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports = createPreviousFunction;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const refreshFunction = (currentPage) => () => {
|
|
2
|
+
const best = require('./best');
|
|
3
|
+
return best(currentPage);
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const createRefreshFunction = (pagination) => {
|
|
7
|
+
const { page } = pagination;
|
|
8
|
+
return refreshFunction(page);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = createRefreshFunction;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./best');
|