phub 4.8.6__tar.gz → 4.8.8__tar.gz
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-4.8.8/PKG-INFO +23 -0
- {phub-4.8.6 → phub-4.8.8}/pyproject.toml +17 -9
- {phub-4.8.6 → phub-4.8.8}/src/phub/consts.py +4 -2
- {phub-4.8.6 → phub-4.8.8}/src/phub/core.py +5 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/video.py +22 -8
- {phub-4.8.6 → phub-4.8.8}/src/phub/utils.py +4 -0
- phub-4.8.6/PKG-INFO +0 -705
- phub-4.8.6/README.md +0 -89
- phub-4.8.6/pypi.md +0 -11
- phub-4.8.6/setup.cfg +0 -4
- phub-4.8.6/setup.py +0 -4
- phub-4.8.6/src/phub.egg-info/PKG-INFO +0 -705
- phub-4.8.6/src/phub.egg-info/SOURCES.txt +0 -37
- phub-4.8.6/src/phub.egg-info/dependency_links.txt +0 -1
- phub-4.8.6/src/phub.egg-info/entry_points.txt +0 -2
- phub-4.8.6/src/phub.egg-info/requires.txt +0 -3
- phub-4.8.6/src/phub.egg-info/top_level.txt +0 -1
- {phub-4.8.6 → phub-4.8.8}/LICENSE +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/__init__.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/__main__.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/errors.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/literals.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/modules/__init__.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/modules/display.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/modules/parser.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/modules/rss.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/__init__.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/account.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/data.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/feed.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/image.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/playlist.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/query.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/objects/user.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/__init__.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/test_auth.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/test_model.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/test_playlist.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/test_search.py +0 -0
- {phub-4.8.6 → phub-4.8.8}/src/phub/tests/test_video.py +0 -0
phub-4.8.8/PKG-INFO
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phub
|
|
3
|
+
Version: 4.8.8
|
|
4
|
+
Summary: An API for Pornhub
|
|
5
|
+
Keywords: pornhub,phub,porn,api,web scrapper,api wrapper
|
|
6
|
+
Author: Egsagon, EchterAlsFake
|
|
7
|
+
Author-email: Egsagon <egsagon.git@gmail.com>, EchterAlsFake <EchterAlsFake@proton.me>
|
|
8
|
+
License-Expression: LGPL-3.0-only
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Requires-Dist: eaf-base-api
|
|
13
|
+
Requires-Dist: m3u8
|
|
14
|
+
Requires-Dist: lxml
|
|
15
|
+
Requires-Dist: av ; python_full_version >= '3.10' and extra == 'av'
|
|
16
|
+
Requires-Dist: httpx[http2] ; extra == 'full'
|
|
17
|
+
Requires-Dist: httpx[socks] ; extra == 'full'
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Project-URL: Documentation, https://phub.readthedocs.io
|
|
20
|
+
Project-URL: Documentation_Updated, https://github.com/EchterAlsFake/API_Docs/blob/master/Porn_APIs/PHUB.md
|
|
21
|
+
Project-URL: Repository, https://github.com/EchterAlsFake/PHUB
|
|
22
|
+
Provides-Extra: av
|
|
23
|
+
Provides-Extra: full
|
|
@@ -1,21 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.9.18,<0.10.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
1
5
|
[project]
|
|
2
6
|
name = "phub"
|
|
3
|
-
version = "4.8.
|
|
7
|
+
version = "4.8.8"
|
|
4
8
|
description = "An API for Pornhub"
|
|
5
9
|
authors = [
|
|
6
10
|
{name = 'Egsagon', email = "egsagon.git@gmail.com"},
|
|
7
11
|
{name = "EchterAlsFake", email = "EchterAlsFake@proton.me"}
|
|
8
12
|
]
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
requires-python = ">=3.9"
|
|
14
|
+
license = "LGPL-3.0-only"
|
|
15
|
+
license-files = ["LICENSE"]
|
|
11
16
|
keywords = ["pornhub", "phub", "porn", "api", "web scrapper", "api wrapper"]
|
|
12
17
|
classifiers = [
|
|
13
18
|
"Development Status :: 4 - Beta",
|
|
14
19
|
"Programming Language :: Python"
|
|
15
20
|
]
|
|
16
|
-
dependencies = [
|
|
17
|
-
|
|
21
|
+
dependencies = [
|
|
22
|
+
"eaf_base_api",
|
|
23
|
+
"m3u8",
|
|
24
|
+
"lxml"
|
|
18
25
|
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
av = ["av; python_version >= '3.10'"]
|
|
30
|
+
full = ["httpx[http2]", "httpx[socks]"] # H2 for HTTP 2.0 support, LXML for faster parsing speed, though optional :)
|
|
19
31
|
|
|
20
32
|
[project.scripts]
|
|
21
33
|
phub = "phub.__main__:main"
|
|
@@ -25,9 +37,5 @@ Documentation = "https://phub.readthedocs.io"
|
|
|
25
37
|
Documentation_Updated = "https://github.com/EchterAlsFake/API_Docs/blob/master/Porn_APIs/PHUB.md"
|
|
26
38
|
Repository = "https://github.com/EchterAlsFake/PHUB"
|
|
27
39
|
|
|
28
|
-
[build-system]
|
|
29
|
-
requires = ["setuptools", "wheel"]
|
|
30
|
-
build-backend = "setuptools.build_meta"
|
|
31
|
-
|
|
32
40
|
[tool.setuptools.packages.find]
|
|
33
41
|
where = ["src"]
|
|
@@ -19,7 +19,9 @@ HEADERS = {
|
|
|
19
19
|
'Accept': '*/*',
|
|
20
20
|
'Accept-Language': 'en,en-US',
|
|
21
21
|
'Connection': 'keep-alive',
|
|
22
|
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0'
|
|
22
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0',
|
|
23
|
+
'Referer': 'https://www.pornhub.com/',
|
|
24
|
+
'Origin': 'https://www.pornhub.com',
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
COOKIES = {
|
|
@@ -227,7 +229,7 @@ class re:
|
|
|
227
229
|
container = find( engine.DOTALL, r'class=\"container(.*)' ) # Get the page container
|
|
228
230
|
document = find( engine.DOTALL, r'.*' ) # Match a whole document
|
|
229
231
|
get_playlist_unavailable = find( engine.DOTALL, r': (\d+)</h5' ) # Get playlist unavailable videos amount
|
|
230
|
-
get_playlist_size = find( engine.DOTALL, r'var itemsCount = (.*?) ||'
|
|
232
|
+
get_playlist_size = find( engine.DOTALL, r'var itemsCount = (.*?) ||' ) # Get playlist video amount
|
|
231
233
|
get_playlist_likes = find( engine.DOTALL, r'<span class="votesUp">(.*?)</span>' ) # Get playlist likes
|
|
232
234
|
get_playlist_dislikes = find( engine.DOTALL, r'<span class="votesDown">(.*?)</span>' ) # Get playlist dislikes
|
|
233
235
|
get_playlist_ratings = find( engine.DOTALL, r'<span class="percent">(.*?)%</span>' ) # Get paylist like/dislike ratio
|
|
@@ -5,6 +5,8 @@ import re
|
|
|
5
5
|
import time
|
|
6
6
|
import logging
|
|
7
7
|
import random
|
|
8
|
+
import traceback
|
|
9
|
+
|
|
8
10
|
import httpx
|
|
9
11
|
|
|
10
12
|
from functools import cached_property
|
|
@@ -117,6 +119,7 @@ class Client:
|
|
|
117
119
|
headers: dict = None,
|
|
118
120
|
throw: bool = True,
|
|
119
121
|
silent: bool = False,
|
|
122
|
+
params: dict = None,
|
|
120
123
|
get_response = True) -> httpx.Response:
|
|
121
124
|
'''
|
|
122
125
|
Used internally to send a request or an API call.
|
|
@@ -156,6 +159,7 @@ class Client:
|
|
|
156
159
|
method = method,
|
|
157
160
|
url = url,
|
|
158
161
|
data = data,
|
|
162
|
+
params = params,
|
|
159
163
|
get_response=get_response)
|
|
160
164
|
|
|
161
165
|
# Silent 429 errors
|
|
@@ -175,6 +179,7 @@ class Client:
|
|
|
175
179
|
break
|
|
176
180
|
|
|
177
181
|
except Exception as err:
|
|
182
|
+
print(traceback.format_exc())
|
|
178
183
|
self.logger.log(logging.DEBUG if silent else logging.WARNING,
|
|
179
184
|
f'Call failed: {repr(err)}. Retrying (attempt {i + 1}/{self.core.config.max_retries})')
|
|
180
185
|
continue
|
|
@@ -4,11 +4,16 @@ import html
|
|
|
4
4
|
import os
|
|
5
5
|
import random
|
|
6
6
|
import logging
|
|
7
|
+
import traceback
|
|
7
8
|
from functools import cached_property
|
|
9
|
+
|
|
10
|
+
import httpx
|
|
8
11
|
from base_api.base import setup_logger
|
|
9
12
|
from datetime import datetime, timedelta
|
|
10
13
|
from typing import TYPE_CHECKING, Iterator, Literal, Callable, Any, Union
|
|
11
14
|
|
|
15
|
+
from httpx import request
|
|
16
|
+
|
|
12
17
|
from . import Tag, Like, User, Image
|
|
13
18
|
from .. import utils
|
|
14
19
|
from .. import errors
|
|
@@ -262,7 +267,8 @@ class Video:
|
|
|
262
267
|
remux=remux, callback_remux=display_remux)
|
|
263
268
|
|
|
264
269
|
except Exception as e:
|
|
265
|
-
|
|
270
|
+
error = traceback.format_exc()
|
|
271
|
+
self.logger.error(f"An error occurred while downloading video {error}")
|
|
266
272
|
|
|
267
273
|
return path
|
|
268
274
|
|
|
@@ -383,7 +389,7 @@ class Video:
|
|
|
383
389
|
|
|
384
390
|
self._assert_internal_success(res.json())
|
|
385
391
|
|
|
386
|
-
def watch_later(self, toggle: bool = True) ->
|
|
392
|
+
def watch_later(self, toggle: bool = True) -> bool:
|
|
387
393
|
'''
|
|
388
394
|
Add or remove the video to the watch later playlist.
|
|
389
395
|
|
|
@@ -391,14 +397,22 @@ class Video:
|
|
|
391
397
|
toggle (bool): The toggle value.
|
|
392
398
|
'''
|
|
393
399
|
|
|
394
|
-
|
|
400
|
+
if toggle:
|
|
401
|
+
res = self.client.call(f'api/v1/playlist/video_add_watchlater', 'POST', dict(
|
|
402
|
+
vid=self.id,
|
|
403
|
+
token=self.client._granted_token
|
|
404
|
+
))
|
|
405
|
+
return res.is_success
|
|
395
406
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
407
|
+
else:
|
|
408
|
+
res = self.client.call(
|
|
409
|
+
"api/v1/playlist/video_remove_watchlater",
|
|
410
|
+
method="DELETE",
|
|
411
|
+
params={"vid": str(self.id), "token": str(self.client._granted_token)},
|
|
412
|
+
headers={"Accept": "application/json"},
|
|
413
|
+
)
|
|
414
|
+
return res.is_success
|
|
400
415
|
|
|
401
|
-
self._assert_internal_success(res.json())
|
|
402
416
|
|
|
403
417
|
# === Data properties === #
|
|
404
418
|
|
|
@@ -254,4 +254,8 @@ def fix_url(url: str):
|
|
|
254
254
|
url = url.replace(language, "www", 1)
|
|
255
255
|
return url
|
|
256
256
|
|
|
257
|
+
|
|
258
|
+
if "#" in url: # Some URLs have a # at the end and some number, idk why but yeah, fixing that here...
|
|
259
|
+
url = url.split("#")[0]
|
|
260
|
+
|
|
257
261
|
return url # Sometimes URL doesn't need to be changed. In this case, just return it.
|