phub 4.7.7__tar.gz → 4.7.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.
Files changed (40) hide show
  1. {phub-4.7.7 → phub-4.7.8}/PKG-INFO +3 -1
  2. {phub-4.7.7 → phub-4.7.8}/README.md +15 -7
  3. {phub-4.7.7 → phub-4.7.8}/pyproject.toml +3 -2
  4. {phub-4.7.7 → phub-4.7.8}/src/phub/__init__.py +1 -2
  5. {phub-4.7.7 → phub-4.7.8}/src/phub/__main__.py +4 -12
  6. {phub-4.7.7 → phub-4.7.8}/src/phub/consts.py +0 -16
  7. {phub-4.7.7 → phub-4.7.8}/src/phub/core.py +50 -60
  8. {phub-4.7.7 → phub-4.7.8}/src/phub/modules/__init__.py +1 -2
  9. {phub-4.7.7 → phub-4.7.8}/src/phub/modules/parser.py +3 -2
  10. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/account.py +13 -10
  11. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/feed.py +9 -6
  12. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/image.py +12 -9
  13. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/query.py +11 -8
  14. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/user.py +13 -11
  15. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/video.py +58 -81
  16. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/test_model.py +14 -3
  17. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/test_video.py +0 -14
  18. {phub-4.7.7 → phub-4.7.8}/src/phub/utils.py +6 -13
  19. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/PKG-INFO +3 -1
  20. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/SOURCES.txt +0 -1
  21. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/requires.txt +1 -0
  22. phub-4.7.7/src/phub/modules/download.py +0 -198
  23. {phub-4.7.7 → phub-4.7.8}/LICENSE +0 -0
  24. {phub-4.7.7 → phub-4.7.8}/pypi.md +0 -0
  25. {phub-4.7.7 → phub-4.7.8}/setup.cfg +0 -0
  26. {phub-4.7.7 → phub-4.7.8}/setup.py +0 -0
  27. {phub-4.7.7 → phub-4.7.8}/src/phub/errors.py +0 -0
  28. {phub-4.7.7 → phub-4.7.8}/src/phub/literals.py +0 -0
  29. {phub-4.7.7 → phub-4.7.8}/src/phub/modules/display.py +0 -0
  30. {phub-4.7.7 → phub-4.7.8}/src/phub/modules/rss.py +0 -0
  31. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/__init__.py +0 -0
  32. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/data.py +0 -0
  33. {phub-4.7.7 → phub-4.7.8}/src/phub/objects/playlist.py +0 -0
  34. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/__init__.py +0 -0
  35. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/test_auth.py +0 -0
  36. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/test_playlist.py +0 -0
  37. {phub-4.7.7 → phub-4.7.8}/src/phub/tests/test_search.py +0 -0
  38. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/dependency_links.txt +0 -0
  39. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/entry_points.txt +0 -0
  40. {phub-4.7.7 → phub-4.7.8}/src/phub.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: phub
3
- Version: 4.7.7
3
+ Version: 4.7.8
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
@@ -679,6 +679,7 @@ License: GNU GENERAL PUBLIC LICENSE
679
679
  <https://www.gnu.org/licenses/why-not-lgpl.html>.
680
680
 
681
681
  Project-URL: Documentation, https://phub.readthedocs.io
682
+ Project-URL: Documentation_Updated, https://github.com/EchterAlsFake/API_Docs/blob/master/Porn_APIs/PHUB.md
682
683
  Project-URL: Repository, https://github.com/EchterAlsFake/PHUB
683
684
  Keywords: pornhub,phub,porn,api,web scrapper,api wrapper
684
685
  Classifier: Development Status :: 4 - Beta
@@ -688,6 +689,7 @@ Description-Content-Type: text/markdown
688
689
  License-File: LICENSE
689
690
  Requires-Dist: httpx[brotli,socks]
690
691
  Requires-Dist: ffmpeg-progress-yield
692
+ Requires-Dist: eaf_base_api
691
693
  Dynamic: license-file
692
694
 
693
695
  <p align="center">
@@ -13,7 +13,9 @@ PHUB is an easy-to-use API wrapper for Pornhub. It can access most used or usefu
13
13
  PH features, such as video searching, account features, video downloading, and more.
14
14
 
15
15
  > [!WARNING]
16
- > This project is probably against Pornhub TOS. Use at your own risks.
16
+ > This project is against PornHub's Terms of Services. Redistributing copyright protected content is a crime under DMCA.
17
+ > Usage of this API is intended for **PRIVATE** non-commercial purposes only. We are not responsible for damages caused by
18
+ > this project. Please use it responsibly to ensure the continued development for everyone!
17
19
 
18
20
  # Installation
19
21
 
@@ -30,26 +32,26 @@ pip install --upgrade git+https://github.com/EchterAlsFake/PHUB.git
30
32
  # Usage from command line
31
33
  ```shell
32
34
  # Download a single video
33
- py -m phub https://www.pornhub.com/view_video.php?viewkey=abcdef
35
+ phub -url https://www.pornhub.com/view_video.php?viewkey=abcdef
34
36
  # Download multiple videos from a text file
35
- py -m phub path/to/file.txt --quality best --downloader threaded --output video.mp4
37
+ phub -file path/to/file.txt --quality best --downloader threaded --output video.mp4
36
38
  ```
37
39
 
38
40
  # Quickstart
39
41
 
40
42
  > [!NOTE]
41
- > You can find the docs on this project [here](https://phub.readthedocs.io).
43
+ > You can find the beautiful outdated docs on this project [here](https://phub.readthedocs.io).
44
+ > <br>Or use the ugly but **UPDATED** docs (xD) [here](https://github.com/EchterAlsFake/API_Docs/blob/master/Porn_APIs/PHUB.md)
42
45
 
43
46
  ```python
44
47
  import phub
45
- from phub.locals import *
46
48
 
47
49
  # Initialise a client
48
50
  client = phub.Client()
49
51
 
50
52
  # Fetch and download a video
51
53
  video = client.get('https://...')
52
- video.download('my-video.mp4', Quality.BEST)
54
+ video.download('my-video.mp4', quality="best") # See docs for more options
53
55
 
54
56
  # Fetch user videos
55
57
  user = client.get_user('this-user')
@@ -61,7 +63,7 @@ for video in client.search('my-query'):
61
63
  print(video.title)
62
64
 
63
65
  # Connect to an account
64
- client = phub.Client('my-username', 'my-password')
66
+ client = phub.Client('my-email', 'my-password')
65
67
 
66
68
  # Access account history, liked and recommended stuff
67
69
  client.account.watched
@@ -76,6 +78,12 @@ This repository was initiated and maintained by [Egsagon](https://github.com/Egs
76
78
  He doesn't have any time to maintain this and transferred me the ownership.
77
79
  I'll do my best to maintain this repository functional.
78
80
 
81
+ # Donations
82
+ If you want to donate, I and Egsagon will gladly appreciate it. Donations will be split 50/50 between us.
83
+ Please use PayPal for donating, as it makes it easier. Thanks a lot!
84
+
85
+ - https://paypal.me/EchterAlsFake
86
+
79
87
  # Contributing
80
88
  Feel free to contribute to this project by submitting
81
89
  feature requests, issues, bugs, or whatever.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "phub"
3
- version = "4.7.7"
3
+ version = "4.7.8"
4
4
  description = "An API for Pornhub"
5
5
  authors = [
6
6
  {name = 'Egsagon', email = "egsagon.git@gmail.com"},
@@ -13,7 +13,7 @@ classifiers = [
13
13
  "Development Status :: 4 - Beta",
14
14
  "Programming Language :: Python"
15
15
  ]
16
- dependencies = ["httpx[brotli,socks]", "ffmpeg-progress-yield"]
16
+ dependencies = ["httpx[brotli,socks]", "ffmpeg-progress-yield", "eaf_base_api"]
17
17
  requires-python = ">=3.9"
18
18
 
19
19
 
@@ -22,6 +22,7 @@ phub = "phub.__main__:main"
22
22
 
23
23
  [project.urls]
24
24
  Documentation = "https://phub.readthedocs.io"
25
+ Documentation_Updated = "https://github.com/EchterAlsFake/API_Docs/blob/master/Porn_APIs/PHUB.md"
25
26
  Repository = "https://github.com/EchterAlsFake/PHUB"
26
27
 
27
28
  [build-system]
@@ -11,12 +11,11 @@ __copyright__ = 'Copyright 2024, PHUB'
11
11
  __license__ = 'GPLv3'
12
12
  __version__ = '4.7.2'
13
13
 
14
- __all__ = ['Client', 'Quality', 'core', 'utils',
14
+ __all__ = ['Client', 'core', 'utils',
15
15
  'consts', 'errors', 'objects', 'modules']
16
16
 
17
17
  # Shortcuts
18
18
  from .core import Client
19
- from .utils import Quality
20
19
 
21
20
  # Sub modules
22
21
  from . import core
@@ -4,9 +4,9 @@ PHUB built-in CLI.
4
4
 
5
5
  import os
6
6
  import argparse
7
+ import re
7
8
 
8
9
  from phub import Client, Video
9
- from phub.modules.download import threaded, FFMPEG, default
10
10
 
11
11
 
12
12
  def text_progress_bar(downloaded, total, title=False):
@@ -33,21 +33,13 @@ def download_video(client: Client, url: [str, Video], output: str, quality: str,
33
33
  else:
34
34
  raise "Some error happened here, please report on GitHub, thank you :) "
35
35
 
36
- title = video.title
36
+ title = re.sub(r'[<>:"/\\|?*]', '', video.title)
37
37
  final_output_path = os.path.join(output, title + ".mp4")
38
38
 
39
39
  print(f"Downloading: {title} to: {final_output_path}")
40
40
  video.download(path=final_output_path, quality=quality, downloader=downloader, display=text_progress_bar)
41
41
  print(f"Successfully downloaded: {title}")
42
42
 
43
- def resolve_threading_mode(mode, workers=10, timeout=10):
44
- """Resolve the appropriate threading mode based on input."""
45
- return {
46
- "threaded": threaded(max_workers=workers, timeout=timeout),
47
- "ffmpeg": FFMPEG,
48
- "default": default
49
- }.get(mode, default)
50
-
51
43
 
52
44
  def main():
53
45
  parser = argparse.ArgumentParser(description="PHUB built-in CLI")
@@ -67,7 +59,7 @@ def main():
67
59
  args = parser.parse_args()
68
60
  quality = args.quality
69
61
  output = args.output
70
- downloader = resolve_threading_mode(mode=args.downloader)
62
+ downloader = args.downloader
71
63
  url = args.url
72
64
  model = args.model
73
65
  video_limit = args.video_limit
@@ -109,4 +101,4 @@ def main():
109
101
  if __name__ == '__main__':
110
102
  main()
111
103
 
112
- # EOF
104
+ # EOF
@@ -36,22 +36,6 @@ LOGIN_PAYLOAD = {
36
36
  }
37
37
 
38
38
  RSS = 'https://www.pornhub.com/video/webmasterss'
39
-
40
- PROXY = None
41
- # Can be any http or socks proxy
42
-
43
-
44
- MAX_CALL_RETRIES = 4 # Maximum times a HTTPError can be reproduced
45
- MAX_CALL_TIMEOUT = .4 # Time to wait before retrying basic calls
46
- CALL_TIMEOUT = 30 # Time to wait before retrying calls (in case no error happens)
47
- CHALLENGE_TIMEOUT = 2 # Time to wait before injecting the new cookie for resolving the challenge (needs to be at least 1)
48
- DELAY = 0 # Minimum time between requests
49
-
50
- DOWNLOAD_SEGMENT_MAX_ATTEMPS = 5
51
- DOWNLOAD_SEGMENT_ERROR_DELAY = .5
52
-
53
- FFMPEG_EXECUTABLE = 'ffmpeg' # Use from PATH by default
54
-
55
39
  IFRAME = '<iframe src="https://www.pornhub.com/embed/{key}" frameborder="0" width="{width}" height="{height}" scrolling="no" allowfullscreen></iframe>'
56
40
 
57
41
  # Supported languages
@@ -5,23 +5,23 @@ PHUB core module.
5
5
  import time
6
6
  import logging
7
7
  import random
8
-
9
8
  import httpx
9
+
10
10
  from typing import Iterable, Union
11
11
  from functools import cached_property
12
+ from base_api.base import BaseCore, setup_logger
12
13
 
13
14
  from . import utils
14
15
  from . import consts
15
16
  from . import errors
16
17
  from . import literals
18
+ from .errors import LoginFailed
17
19
 
18
20
  from .modules import parser
19
21
 
20
22
  from .objects import (Video, User,
21
23
  Account, Query, queries, Playlist)
22
24
 
23
- logger = logging.getLogger(__name__)
24
-
25
25
 
26
26
  class Client:
27
27
  '''
@@ -38,7 +38,8 @@ class Client:
38
38
  login: bool = True,
39
39
  bypass_geo_blocking: bool = False,
40
40
  change_title_language: bool = True,
41
- use_webmaster_api: bool = True) -> None:
41
+ use_webmaster_api: bool = True,
42
+ core=None) -> None:
42
43
  '''
43
44
  Initialises a new client.
44
45
 
@@ -54,8 +55,13 @@ class Client:
54
55
  LoginFailed: If Pornhub refuses the authentication.
55
56
  The reason will be passed as the error body.
56
57
  '''
57
-
58
- logger.debug('Initialised new Client %s', self)
58
+
59
+ self.logger = setup_logger(name="PHUB API - [Client]", log_file=None, level=logging.ERROR)
60
+ self.core = core or BaseCore()
61
+ self.core.config.cookies = consts.COOKIES
62
+ self.core.config.headers = consts.HEADERS
63
+ # Applying PornHub specific cookies and headers to base API
64
+ self.logger.debug('Initialised new Client %s', self)
59
65
 
60
66
  # Initialise session
61
67
  Client.use_webmaster_api = use_webmaster_api
@@ -65,41 +71,30 @@ class Client:
65
71
 
66
72
  self.reset()
67
73
 
68
- self.session.headers.update({"Accept-Language": language})
74
+ self.core.config.headers.update({"Accept-Language": language})
75
+ self.core.update_headers({"Accept-Language": language})
69
76
  self.credentials = {'email': email,
70
77
  'password': password}
71
-
72
- self.delay = consts.DELAY
73
- self.start_delay = False
74
- self.last_request_time = None
75
-
78
+
79
+
76
80
  # Connect account
77
81
  self.logged = False
78
82
  self.account = Account(self)
79
- logger.debug('Connected account to client %s', self.account)
83
+ self.logger.debug('Connected account to client %s', self.account)
80
84
 
81
85
  # Automatic login
82
86
  if login and self.account:
83
87
  self.login()
84
-
88
+
89
+ def enable_logging(self, log_file: str = None, level = None, log_ip=None, log_port=None):
90
+ self.logger = setup_logger(name="PHUB API - [Client]", log_file=log_file, level=level, http_ip=log_ip, http_port=log_port)
91
+
85
92
  def reset(self) -> None:
86
93
  '''
87
94
  Reset the client requests session.
88
95
  This is useful if you are keeping the client running
89
96
  for a long time and can help with Pornhub rate limit.
90
97
  '''
91
- verify = True
92
- if consts.PROXY is not None:
93
- verify = False
94
-
95
- # Initialise session
96
- self.session = httpx.Client(
97
- headers = consts.HEADERS,
98
- cookies = consts.COOKIES,
99
- follow_redirects = True,
100
- proxy = consts.PROXY,
101
- verify = verify)
102
-
103
98
  self._clear_granted_token()
104
99
 
105
100
  if self.bypass_geo_blocking:
@@ -107,21 +102,21 @@ class Client:
107
102
  language_code = "fr"
108
103
 
109
104
  # Faking the X-Forwarded-For header (Fake IP source)
110
- self.session.headers.update({"X-Forwarded-For": f"{ip}"})
105
+ self.core.config.headers.update({"X-Forwarded-For": f"{ip}"})
111
106
  # Setting the Accept-Language tag to French, because the faked IP comes from france
112
- self.session.headers.update({"Accept-Language": f"{language_code}"})
107
+ self.core.config.headers.update({"Accept-Language": f"{language_code}"})
113
108
  # Setting the country code also to french
114
- self.session.headers.update({"CF-IPCountry": f"{language_code}"})
115
- logging.debug(f"Using faked headers for geo-bypass: {self.session.headers}")
109
+ self.core.config.headers.update({"CF-IPCountry": f"{language_code}"})
110
+ logging.debug(f"Using faked headers for geo-bypass: {self.core.config.session.headers}")
116
111
 
117
112
  def call(self,
118
113
  func: str,
119
114
  method: str = 'GET',
120
115
  data: dict = None,
121
116
  headers: dict = None,
122
- timeout: float = consts.CALL_TIMEOUT,
123
117
  throw: bool = True,
124
- silent: bool = False) -> httpx.Response:
118
+ silent: bool = False,
119
+ get_response = True) -> httpx.Response:
125
120
  '''
126
121
  Used internally to send a request or an API call.
127
122
 
@@ -130,7 +125,6 @@ class Client:
130
125
  method (str): Request method (GET, POST, PUT, ...).
131
126
  data (dict): Optional data to send to the server.
132
127
  headers (dict): Additional request headers.
133
- timeout (float): Request maximum response time.
134
128
  throw (bool): Whether to raise an error when a request explicitly fails.
135
129
  silent (bool): Whether to supress this call from logs.
136
130
 
@@ -142,15 +136,10 @@ class Client:
142
136
  HTTPError: If the request failed, for any reason.
143
137
  '''
144
138
  func = utils.fix_url(func)
145
- logger.log(logging.DEBUG if silent else logging.INFO, 'Fetching %s', func or '/')
139
+ self.logger.log(logging.DEBUG if silent else logging.INFO, 'Fetching %s', func or '/')
146
140
 
147
- # Delay mechanism
148
- if self.last_request_time:
149
- elapsed_time = time.time() - self.last_request_time
150
- if elapsed_time < self.delay:
151
- time.sleep(self.delay - elapsed_time)
152
-
153
- self.last_request_time = time.time() # Update the time of the last request
141
+ if headers:
142
+ self.core.config.headers = headers
154
143
 
155
144
  if not self.language == "en":
156
145
  host = consts.LANGUAGE_MAPPING.get(self.language)
@@ -160,15 +149,13 @@ class Client:
160
149
  host = consts.HOST
161
150
 
162
151
  url = func if 'http' in func else utils.concat(host, func)
163
- for i in range(consts.MAX_CALL_RETRIES):
152
+ for i in range(self.core.config.max_retries):
164
153
  try:
165
- response = self.session.request(
154
+ response = self.core.fetch(
166
155
  method = method,
167
156
  url = url,
168
- headers = headers,
169
157
  data = data,
170
- timeout = timeout
171
- )
158
+ get_response=get_response)
172
159
 
173
160
  # Silent 429 errors
174
161
  if b'429</title>' in response.content:
@@ -177,19 +164,18 @@ class Client:
177
164
  # Attempt to resolve the challenge if needed
178
165
  challenge = consts.re.get_challenge(response.text, False)
179
166
  if challenge:
180
- logger.info('Challenge found, attempting to resolve')
167
+ self.logger.info('Challenge found, attempting to resolve')
181
168
  parser.challenge(self, *challenge)
182
169
 
183
- logger.info(f"Sleeping for {consts.CHALLENGE_TIMEOUT} seconds")
184
- time.sleep(consts.CHALLENGE_TIMEOUT)
170
+ self.logger.info(f"Sleeping for 1.5 seconds")
171
+ time.sleep(1.5) # Yes, we need to sleep that amount, otherwise PornHub refuses the challenge.
185
172
  continue # Reload page
186
173
 
187
174
  break
188
175
 
189
176
  except Exception as err:
190
- logger.log(logging.DEBUG if silent else logging.WARNING,
191
- f'Call failed: {repr(err)}. Retrying (attempt {i + 1}/{consts.MAX_CALL_RETRIES})')
192
- time.sleep(consts.MAX_CALL_TIMEOUT)
177
+ self.logger.log(logging.DEBUG if silent else logging.WARNING,
178
+ f'Call failed: {repr(err)}. Retrying (attempt {i + 1}/{self.core.config.max_retries})')
193
179
  continue
194
180
 
195
181
  else:
@@ -216,16 +202,20 @@ class Client:
216
202
  LoginFailed: If the login failed, for a reason passed in the error body.
217
203
  '''
218
204
 
219
- logger.debug('Attempting login')
205
+ self.logger.debug('Attempting login')
220
206
 
221
207
  if not force and self.logged:
222
- logger.error('Client is already logged in')
208
+ self.logger.error('Client is already logged in')
223
209
  raise errors.ClientAlreadyLogged()
224
210
 
225
211
  # Get token
226
212
  page = self.call('').text
227
- base_token = consts.re.get_token(page)
228
-
213
+ try:
214
+ base_token = consts.re.get_token(page)
215
+
216
+ except errors.RegexError:
217
+ raise LoginFailed("(Probably) invalid credentials. If you are sure they are correct, please report this issue.")
218
+
229
219
  # Send credentials
230
220
  payload = consts.LOGIN_PAYLOAD | self.credentials | {'token': base_token}
231
221
  response = self.call('front/authenticate', method = 'POST', data = payload)
@@ -236,7 +226,7 @@ class Client:
236
226
  message = data.get('message')
237
227
 
238
228
  if throw and not success:
239
- logger.error('Login failed: Received error: %s', message)
229
+ self.logger.error('Login failed: Received error: %s', message)
240
230
  raise errors.LoginFailed(message)
241
231
 
242
232
  # Reset token
@@ -258,7 +248,7 @@ class Client:
258
248
  Video: The corresponding video object.
259
249
  '''
260
250
 
261
- logger.debug(f'Fetching video at {video}')
251
+ self.logger.debug(f'Fetching video at {video}')
262
252
 
263
253
  if isinstance(video, Video):
264
254
  # User might want to re-init a video,
@@ -296,7 +286,7 @@ class Client:
296
286
  if isinstance(user, User):
297
287
  user = user.url
298
288
 
299
- logger.debug('Fetching user %s', user)
289
+ self.logger.debug('Fetching user %s', user)
300
290
  return User.get(self, user)
301
291
 
302
292
  def search_hubtraffic(self,
@@ -308,7 +298,7 @@ class Client:
308
298
  period: literals.ht_period = None) -> Query:
309
299
  '''
310
300
  Perform searching on Pornhub using the HubTraffic API.
311
- It is condidered to be much faster but has less filters.
301
+ It is considered to be much faster but has less filters.
312
302
 
313
303
  Args:
314
304
  query (str): The query to search.
@@ -2,11 +2,10 @@
2
2
  PHUB submodules.
3
3
  '''
4
4
 
5
- __all__ = ['parser', 'display', 'download', 'rss']
5
+ __all__ = ['parser', 'display', 'rss']
6
6
 
7
7
  from . import rss
8
8
  from . import parser
9
9
  from . import display
10
- from . import download
11
10
 
12
11
  # EOF
@@ -79,7 +79,8 @@ def challenge(client: Client, challenge: str, token: str) -> None:
79
79
 
80
80
  # Build and inject cookie
81
81
  cookie = f'{n}*{p // n}:{s}:{token}:1'
82
- client.session.cookies.set('KEY', cookie)
82
+ client.core.config.cookies = {'KEY', cookie}
83
+ client.core.update_cookies()
83
84
  logger.info('Injected cookie %s', cookie)
84
-
85
+ print("Injected cookie for authentication")
85
86
  # EOF
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  from functools import cached_property
5
+ from base_api.base import setup_logger
5
6
  from typing import TYPE_CHECKING, Literal, Iterator, Union
6
7
 
7
8
  from .. import utils
@@ -12,8 +13,6 @@ if TYPE_CHECKING:
12
13
  from ..core import Client
13
14
  from . import Feed, queries, User
14
15
 
15
- logger = logging.getLogger(__name__)
16
-
17
16
 
18
17
  class Account:
19
18
  '''
@@ -45,6 +44,7 @@ class Account:
45
44
  '''
46
45
 
47
46
  self.client = client
47
+ self.logger = setup_logger(name="PHUB API - [Account]", log_file=None, level=logging.ERROR)
48
48
 
49
49
  self.name: str = None
50
50
  self.avatar: Image = None
@@ -54,9 +54,12 @@ class Account:
54
54
  # Save data keys so far, so we can make a difference with the
55
55
  # cached property ones.
56
56
  self.loaded_keys = list(self.__dict__.keys()) + ['loaded_keys']
57
-
57
+
58
+ def enable_logging(self, log_file: str = None, level=None, log_ip=None, log_port=None):
59
+ self.logger = setup_logger(name="PHUB API - [Account]", log_file=log_file, level=level, http_ip=log_ip,
60
+ http_port=log_port)
61
+
58
62
  def __repr__(self) -> str:
59
-
60
63
  status = 'logged-out' if self.name is None else f'name={self.name}'
61
64
  return f'phub.Account({status})'
62
65
 
@@ -77,7 +80,7 @@ class Account:
77
80
 
78
81
  # We assert that the account is from a normal user (not model, etc.)
79
82
  if not 'users/' in self.user.url:
80
- logger.error('Invalid user type: %s', url)
83
+ self.logger.error('Invalid user type: %s', url)
81
84
  raise NotImplementedError('Non-user account are not supported.')
82
85
 
83
86
  def refresh(self, refresh_login: bool = False) -> None:
@@ -88,25 +91,25 @@ class Account:
88
91
  refresh_login (bool): Whether to also attempt to re-log in.
89
92
  '''
90
93
 
91
- logger.info('Refreshing account %s', self)
94
+ self.logger.info('Refreshing account %s', self)
92
95
 
93
96
  if refresh_login:
94
- logger.info('Forcing login refresh')
97
+ self.logger.info('Forcing login refresh')
95
98
  self.client.login(force = True)
96
99
 
97
100
  # Clear properties cache
98
101
  for key in list(self.__dict__.keys()):
99
102
  if not key in self.loaded_keys:
100
103
 
101
- logger.debug('Deleting key %s', key)
104
+ self.logger.debug('Deleting key %s', key)
102
105
  delattr(self, key)
103
106
 
104
107
  def fix_recommendations(self) -> None:
105
108
  '''
106
- Allow recommandations cookies.
109
+ Allow recommendations cookies.
107
110
  '''
108
111
 
109
- logger.info('Fixing account recommendations')
112
+ self.logger.info('Fixing account recommendations')
110
113
 
111
114
  payload = utils.urlify({
112
115
  'token': self.client._granted_token,
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  from functools import cached_property
5
+ from base_api.base import setup_logger
5
6
  from typing import TYPE_CHECKING, Callable, Iterator, Union
6
7
 
7
8
  from .. import literals
@@ -11,8 +12,6 @@ if TYPE_CHECKING:
11
12
  from . import queries
12
13
  from ..core import Client
13
14
 
14
- logger = logging.getLogger(__name__)
15
-
16
15
 
17
16
  class Feed:
18
17
  '''
@@ -28,9 +27,13 @@ class Feed:
28
27
  '''
29
28
 
30
29
  self.client = client
31
-
32
- logger.debug('Initialised account feed: %s', self)
33
-
30
+ self.logger = setup_logger(name="PHUB API - [Feed]", log_file=None, level=logging.ERROR)
31
+ self.logger.debug('Initialised account feed: %s', self)
32
+
33
+ def enable_logging(self, log_file: str = None, level=None, log_ip=None, log_port=None):
34
+ self.logger = setup_logger(name="PHUB API - [Feed]", log_file=log_file, level=level, http_ip=log_ip,
35
+ http_port=log_port)
36
+
34
37
  def __repr__(self) -> str:
35
38
 
36
39
  return f'phub.FeedCreator(for={self.client.account.name})'
@@ -51,7 +54,7 @@ class Feed:
51
54
  # Generate args
52
55
  username = user.name if isinstance(user, User) else user
53
56
 
54
- logger.info('Generating new filter feed using args', )
57
+ self.logger.info('Generating new filter feed using args', )
55
58
 
56
59
  return queries.FeedQuery(
57
60
  client = self.client,
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
  import logging
5
+ from base_api.base import setup_logger
5
6
  from typing import TYPE_CHECKING, Literal, Union
6
7
 
7
8
  from .. import utils
@@ -10,9 +11,6 @@ if TYPE_CHECKING:
10
11
  from ..core import Client
11
12
 
12
13
 
13
- logger = logging.getLogger(__name__)
14
-
15
-
16
14
  class Image:
17
15
  '''
18
16
  Represents an image hosted on Pornhub.
@@ -34,19 +32,24 @@ class Image:
34
32
  name (str): Image name.
35
33
  '''
36
34
 
35
+ self.logger = setup_logger(name="PHUB API - [Image]", log_file=None, level=logging.ERROR)
37
36
  self.url = url
38
37
  self.name = name
39
38
  self.client = client
40
39
  self._servers = servers or []
41
40
 
42
- logger.debug('Generated new image object: %s', self)
41
+ self.logger.debug('Generated new image object: %s', self)
43
42
 
44
43
  # Check server image sizes
45
44
  sizes = [s.get('size') for s in self._servers]
46
45
 
47
46
  if len(set(sizes)) > 1:
48
- logger.warning('Detected different image sizes on alt servers: %s', sizes)
49
-
47
+ self.logger.warning('Detected different image sizes on alt servers: %s', sizes)
48
+
49
+ def enable_logging(self, log_file: str = None, level=None, log_ip=None, log_port=None):
50
+ self.logger = setup_logger(name="PHUB API - [Image]", log_file=log_file, level=level, http_ip=log_ip,
51
+ http_port=log_port)
52
+
50
53
  def __repr__(self) -> str:
51
54
 
52
55
  return f'phub.Image(name={self.name})'
@@ -70,7 +73,7 @@ class Image:
70
73
  if os.path.isdir(path):
71
74
  path = utils.concat(path, self.name + ext)
72
75
 
73
- logger.info('Saving %s at %s', self, path)
76
+ self.logger.info('Saving %s at %s', self, path)
74
77
 
75
78
  with open(path, 'wb') as file:
76
79
 
@@ -81,12 +84,12 @@ class Image:
81
84
 
82
85
  except Exception as err:
83
86
 
84
- logger.warning('Failed to get image `%s`', url)
87
+ self.logger.warning('Failed to get image `%s`', url)
85
88
  if not self._servers: raise err
86
89
 
87
90
  # Pop server and retry
88
91
  server = self._servers.pop(0)
89
- logger.info('Retrying download with server %s', server)
92
+ self.logger.info('Retrying download with server %s', server)
90
93
  self.url = server['src']
91
94
  self.download(path)
92
95