phub 4.8.2__py3-none-any.whl → 4.8.4__py3-none-any.whl
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.
- phub/__main__.py +15 -7
- phub/core.py +12 -11
- phub/modules/display.py +1 -1
- phub/objects/video.py +1 -1
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/METADATA +2 -1
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/RECORD +10 -10
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/WHEEL +0 -0
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/entry_points.txt +0 -0
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/licenses/LICENSE +0 -0
- {phub-4.8.2.dist-info → phub-4.8.4.dist-info}/top_level.txt +0 -0
phub/__main__.py
CHANGED
|
@@ -4,8 +4,9 @@ PHUB built-in CLI.
|
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
6
|
import argparse
|
|
7
|
-
import re
|
|
8
7
|
|
|
8
|
+
from typing import Union
|
|
9
|
+
from base_api import BaseCore
|
|
9
10
|
from phub import Client, Video
|
|
10
11
|
|
|
11
12
|
|
|
@@ -22,7 +23,7 @@ def text_progress_bar(downloaded, total, title=False):
|
|
|
22
23
|
print(f"\r | {title} | -->: [{bar}] {percents}%", end='')
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def download_video(client: Client, url: [str
|
|
26
|
+
def download_video(client: Client, url: Union[str | Video], output: str, quality: str, downloader: str, use_video_id=False):
|
|
26
27
|
if not isinstance(url, Video):
|
|
27
28
|
video = client.get(url)
|
|
28
29
|
|
|
@@ -33,10 +34,15 @@ def download_video(client: Client, url: [str, Video], output: str, quality: str,
|
|
|
33
34
|
else:
|
|
34
35
|
raise "Some error happened here, please report on GitHub, thank you :) "
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
if use_video_id:
|
|
38
|
+
title = video.id
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
title = BaseCore().strip_title(title=video.title)
|
|
42
|
+
|
|
37
43
|
final_output_path = os.path.join(output, title + ".mp4")
|
|
38
44
|
|
|
39
|
-
print(f"Downloading: {title} to: {final_output_path}")
|
|
45
|
+
print(f"Downloading: {video.title} to: {final_output_path}")
|
|
40
46
|
video.download(path=final_output_path, quality=quality, downloader=downloader, display=text_progress_bar)
|
|
41
47
|
print(f"Successfully downloaded: {title}")
|
|
42
48
|
|
|
@@ -47,6 +53,7 @@ def main():
|
|
|
47
53
|
group.add_argument("-url", type=str, help="a PornHub Video URL", default="")
|
|
48
54
|
group.add_argument("-model", type=str, help="a Pornhub Model URL", default="")
|
|
49
55
|
parser.add_argument("-video_limit", type=int, help="the maximum number of videos to download from a model (Default: all)", default=100000)
|
|
56
|
+
parser.add_argument("--use-video-id", action="store_true", help="uses video ID as the title instead of the original video title")
|
|
50
57
|
group.add_argument("-file", type=str, help="List to a file with Video URLs (separated by new lines)", default="")
|
|
51
58
|
parser.add_argument("-downloader", type=str, help="The threading (download backend) to use", choices=[
|
|
52
59
|
"threaded", "default", "ffmpeg"], default="threaded")
|
|
@@ -64,11 +71,12 @@ def main():
|
|
|
64
71
|
model = args.model
|
|
65
72
|
video_limit = args.video_limit
|
|
66
73
|
file = args.file
|
|
74
|
+
use_video_id = args.use_video_id
|
|
67
75
|
|
|
68
76
|
client = Client()
|
|
69
77
|
|
|
70
78
|
if len(url) >= 3: # Comparison with not == "" doesn't work, don't ask me why I have no fucking idea...
|
|
71
|
-
download_video(client=client, url=url, output=output, quality=quality, downloader=downloader)
|
|
79
|
+
download_video(client=client, url=url, output=output, quality=quality, downloader=downloader, use_video_id=use_video_id)
|
|
72
80
|
|
|
73
81
|
elif len(model) >= 3:
|
|
74
82
|
model_videos = client.get_user(model).videos
|
|
@@ -78,7 +86,7 @@ def main():
|
|
|
78
86
|
if idx >= video_limit:
|
|
79
87
|
break
|
|
80
88
|
|
|
81
|
-
download_video(client=client, url=video, output=output, quality=quality, downloader=downloader)
|
|
89
|
+
download_video(client=client, url=video, output=output, quality=quality, downloader=downloader, use_video_id=use_video_id)
|
|
82
90
|
idx += 1
|
|
83
91
|
|
|
84
92
|
elif len(file) >= 1:
|
|
@@ -95,7 +103,7 @@ def main():
|
|
|
95
103
|
|
|
96
104
|
for idx, url in enumerate(urls, start=1):
|
|
97
105
|
print(f"[{idx}|{len(urls)}] Downloading: {url}")
|
|
98
|
-
download_video(client=client, url=url, output=output, quality=quality, downloader=downloader)
|
|
106
|
+
download_video(client=client, url=url, output=output, quality=quality, downloader=downloader, use_video_id=use_video_id)
|
|
99
107
|
|
|
100
108
|
|
|
101
109
|
if __name__ == '__main__':
|
phub/core.py
CHANGED
|
@@ -7,9 +7,10 @@ import logging
|
|
|
7
7
|
import random
|
|
8
8
|
import httpx
|
|
9
9
|
|
|
10
|
-
from typing import Iterable, Union
|
|
11
10
|
from functools import cached_property
|
|
11
|
+
from typing import Iterable, Union, Optional
|
|
12
12
|
from base_api.base import BaseCore, setup_logger
|
|
13
|
+
from base_api.modules.config import RuntimeConfig
|
|
13
14
|
|
|
14
15
|
from . import utils
|
|
15
16
|
from . import consts
|
|
@@ -39,7 +40,7 @@ class Client:
|
|
|
39
40
|
bypass_geo_blocking: bool = False,
|
|
40
41
|
change_title_language: bool = True,
|
|
41
42
|
use_webmaster_api: bool = True,
|
|
42
|
-
core=None) -> None:
|
|
43
|
+
core: Optional[BaseCore] = None) -> None:
|
|
43
44
|
'''
|
|
44
45
|
Initialises a new client.
|
|
45
46
|
|
|
@@ -57,9 +58,10 @@ class Client:
|
|
|
57
58
|
'''
|
|
58
59
|
|
|
59
60
|
self.logger = setup_logger(name="PHUB API - [Client]", log_file=None, level=logging.ERROR)
|
|
60
|
-
self.core = core or BaseCore()
|
|
61
|
-
self.core.
|
|
62
|
-
self.core.
|
|
61
|
+
self.core = core or BaseCore(config=RuntimeConfig())
|
|
62
|
+
self.core.initialize_session()
|
|
63
|
+
self.core.session.headers.update(consts.HEADERS)
|
|
64
|
+
self.core.session.cookies.update(consts.HEADERS)
|
|
63
65
|
# Applying PornHub specific cookies and headers to base API
|
|
64
66
|
self.logger.debug('Initialised new Client %s', self)
|
|
65
67
|
|
|
@@ -71,8 +73,7 @@ class Client:
|
|
|
71
73
|
|
|
72
74
|
self.reset()
|
|
73
75
|
|
|
74
|
-
self.core.
|
|
75
|
-
self.core.update_headers({"Accept-Language": language})
|
|
76
|
+
self.core.session.headers.update({"Accept-Language": language})
|
|
76
77
|
self.credentials = {'email': email,
|
|
77
78
|
'password': password}
|
|
78
79
|
|
|
@@ -102,11 +103,11 @@ class Client:
|
|
|
102
103
|
language_code = "fr"
|
|
103
104
|
|
|
104
105
|
# Faking the X-Forwarded-For header (Fake IP source)
|
|
105
|
-
self.core.
|
|
106
|
+
self.core.session.headers.update({"X-Forwarded-For": f"{ip}"})
|
|
106
107
|
# Setting the Accept-Language tag to French, because the faked IP comes from france
|
|
107
|
-
self.core.
|
|
108
|
+
self.core.session.headers.update({"Accept-Language": f"{language_code}"})
|
|
108
109
|
# Setting the country code also to french
|
|
109
|
-
self.core.
|
|
110
|
+
self.core.session.headers.update({"CF-IPCountry": f"{language_code}"})
|
|
110
111
|
logging.debug(f"Using faked headers for geo-bypass: {self.core.config.session.headers}")
|
|
111
112
|
|
|
112
113
|
def call(self,
|
|
@@ -139,7 +140,7 @@ class Client:
|
|
|
139
140
|
self.logger.log(logging.DEBUG if silent else logging.INFO, 'Fetching %s', func or '/')
|
|
140
141
|
|
|
141
142
|
if headers:
|
|
142
|
-
self.core.
|
|
143
|
+
self.core.session.headers = headers
|
|
143
144
|
|
|
144
145
|
if not self.language == "en":
|
|
145
146
|
host = consts.LANGUAGE_MAPPING.get(self.language)
|
phub/modules/display.py
CHANGED
|
@@ -20,7 +20,7 @@ def progress(color: Union[dict, None] = dict(c1=30, c2=33, c3=34, c4=36), desc:
|
|
|
20
20
|
color['c0'] = 0
|
|
21
21
|
color = {k: '' if v == '' else f'\033[{v}m' for k, v in color.items()}
|
|
22
22
|
|
|
23
|
-
tem = '\r{c1}' + desc + ' {c2}{percent}%{c0} - {c3}{cur}{c0}/{c3}{total}
|
|
23
|
+
tem = '\r{c1}' + desc + ' {c2}{percent}%{c0} - {c3}{cur}{c0}/{c3}{total}{c0}' # ({c4}{speed}ips{c0})
|
|
24
24
|
done = False
|
|
25
25
|
start = time.time()
|
|
26
26
|
|
phub/objects/video.py
CHANGED
|
@@ -262,7 +262,7 @@ class Video:
|
|
|
262
262
|
remux=remux, callback_remux=display_remux)
|
|
263
263
|
|
|
264
264
|
except Exception as e:
|
|
265
|
-
self.logger.error(f"An error
|
|
265
|
+
self.logger.error(f"An error occurred while downloading video {e}")
|
|
266
266
|
|
|
267
267
|
return path
|
|
268
268
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phub
|
|
3
|
-
Version: 4.8.
|
|
3
|
+
Version: 4.8.4
|
|
4
4
|
Summary: An API for Pornhub
|
|
5
5
|
Author-email: Egsagon <egsagon.git@gmail.com>, EchterAlsFake <EchterAlsFake@proton.me>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -689,6 +689,7 @@ Description-Content-Type: text/markdown
|
|
|
689
689
|
License-File: LICENSE
|
|
690
690
|
Requires-Dist: httpx[brotli,socks]
|
|
691
691
|
Requires-Dist: eaf_base_api
|
|
692
|
+
Requires-Dist: h2
|
|
692
693
|
Dynamic: license-file
|
|
693
694
|
|
|
694
695
|
<p align="center">
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
phub/__init__.py,sha256=tEWpP7XSkDB9_M5iJ1XHSgpJ6g4olWqYTX8f9IBpIAA,635
|
|
2
|
-
phub/__main__.py,sha256=
|
|
2
|
+
phub/__main__.py,sha256=nP5IffsxbcFzPdGkMWky4fs647NOswW9DT-S5AcLQtU,4028
|
|
3
3
|
phub/consts.py,sha256=a-okcZtwtSDmt4eub_acE1xWg1Fqxm1DZ9yy7aVGvM0,12453
|
|
4
|
-
phub/core.py,sha256=
|
|
4
|
+
phub/core.py,sha256=rY5wiZ6gsPQPQY8xqC3V53D4Iah4P4M5g5CfR62IXpQ,18423
|
|
5
5
|
phub/errors.py,sha256=KiNt_4T4ffzgL-2iIfD8qhIHN_5DeKV4FLPcY72sOw8,1822
|
|
6
6
|
phub/literals.py,sha256=ZnRnn5hJNI3hM6aj2YxsxPANUR-PCqfE2SuQGD8_Yq4,10794
|
|
7
7
|
phub/utils.py,sha256=MYPYvpLrWAYXcwpSUJnRWvFNP0N9iOyLxkzaJFsk8GA,6582
|
|
8
8
|
phub/modules/__init__.py,sha256=h8BQjvxnqCEXxDCn7iDvnGLv0ZF_lE0dFlI7HVkzN5A,133
|
|
9
|
-
phub/modules/display.py,sha256=
|
|
9
|
+
phub/modules/display.py,sha256=qOUaDGZJbGp80JAqPu_T__F2Mzwr3FBRnhrAdYdVjoE,2444
|
|
10
10
|
phub/modules/parser.py,sha256=v2iDYAZB6VQ6KvKR_Oe1Cs5Du42W0yNFvtliJKxbZdI,2337
|
|
11
11
|
phub/modules/rss.py,sha256=j666dZenn3tWgLVXd2U3ox2-tWyUynFXuArzG2bmOFc,980
|
|
12
12
|
phub/objects/__init__.py,sha256=BHOythbS-r01YKYSxtExBlJZYF38hkp85aLAoVQfDd4,446
|
|
@@ -17,16 +17,16 @@ phub/objects/image.py,sha256=qCLuaOy-EYzA_uXxiPRQeCLHPf9gFr0o7TDszQvWXZs,3376
|
|
|
17
17
|
phub/objects/playlist.py,sha256=hpP76yH23LdDS0iL28jhp_iG7EGetYJA3xoqZZdXjTs,3278
|
|
18
18
|
phub/objects/query.py,sha256=crYC-MJGEf04XO3hfU7FPyyHEnBWS9D8XbeQmtTnpzQ,11596
|
|
19
19
|
phub/objects/user.py,sha256=pIumIGC_MQXQ-hjzf_0c0I_egL4WziHrh2e8XegArEc,8161
|
|
20
|
-
phub/objects/video.py,sha256=
|
|
20
|
+
phub/objects/video.py,sha256=0XJL-PP8HVqb2uUexIMZVfQ29-qGEeb60_yVoj3RLuc,19169
|
|
21
21
|
phub/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
phub/tests/test_auth.py,sha256=ySy1Aw0bogMGDSTmzVXO_W352cbRFzXUGjuDX1Iu0xE,609
|
|
23
23
|
phub/tests/test_model.py,sha256=hRpmIjsx2z0EjTWsIpwT_vpHm-H4wCmZtvGWOohaIKQ,1426
|
|
24
24
|
phub/tests/test_playlist.py,sha256=-hS5bIBecsv3zSNlUo66b73DdVbkYlmVThYip9Ivpss,1081
|
|
25
25
|
phub/tests/test_search.py,sha256=VeqyjVzu0QnIYR6NhcujXy8wfCcWn1BlvKS06iY-7JY,1301
|
|
26
26
|
phub/tests/test_video.py,sha256=4E70tiza45byMFIrjBdnpP3xOSyk1YKoTGNP4_QTI0E,1465
|
|
27
|
-
phub-4.8.
|
|
28
|
-
phub-4.8.
|
|
29
|
-
phub-4.8.
|
|
30
|
-
phub-4.8.
|
|
31
|
-
phub-4.8.
|
|
32
|
-
phub-4.8.
|
|
27
|
+
phub-4.8.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
28
|
+
phub-4.8.4.dist-info/METADATA,sha256=FrkX4nJyEFB61jgpBTB77lbVkj4SxY7loM2rUBa43TE,41758
|
|
29
|
+
phub-4.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
phub-4.8.4.dist-info/entry_points.txt,sha256=oxL1BvDV19M1IGLgwFElgb37PlmGnblDBEfMwx3x6u8,44
|
|
31
|
+
phub-4.8.4.dist-info/top_level.txt,sha256=xqJ5Lg28Ba-pgvXf8qwpTFurW3neZhguNd8bhbQonZo,5
|
|
32
|
+
phub-4.8.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|