Skip to content

Commit

Permalink
Some dosctring updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Egsago-n committed Apr 10, 2024
1 parent 32b5048 commit 4430a83
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 130 deletions.
2 changes: 1 addition & 1 deletion src/phub/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
IFRAME = '<iframe src="https://www.pornhub.com/embed/{key}" frameborder="0" width="{width}" height="{height}" scrolling="no" allowfullscreen></iframe>'

# Supported languages
LANGUAGES = [ 'cn', 'de', 'fr', 'it', 'pt', 'pl', 'rt', 'nl', 'cz', 'jp' ]
LANGUAGES = [ 'en', 'cn', 'de', 'fr', 'it', 'pt', 'pl', 'rt', 'nl', 'cz', 'jp' ]

FEED_CLASS_TO_CONST = {
'stream_videos_uploaded': 'Section.VIDEO',
Expand Down
169 changes: 102 additions & 67 deletions src/phub/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,27 @@ class Client:
'''

def __init__(self,
username: str = None,
email: str = None,
password: str = None,
*,
language: str = 'en,en-US',
delay: int = 0,
language: literals.language = 'en,en-US',
delay: int | float = 0,
proxies: dict = None,
login: bool = True) -> None:
'''
Initialise a new client.
Initialises a new client.
Args:
username (str): Optional account username/address to connect to.
password (str): Optional account password to connect to.
language (str): Language locale (fr, en, ru, etc.)
delay (float): Minimum delay between requests.
email (str): Account email address.
password (str): Account password.
language (str): Client language (fr, en, ru, etc.)
delay (int | float): Minimum delay between requests.
proxies (dict): Dictionary of proxies for the requests.
login (bool): Whether to automatically log in after initialization.
login (bool): Whether to directly log in after initialization.
Raises:
LoginFailed: If Pornhub refuses the authentification.
The reason will be passed as the error body.
'''

logger.debug('Initialised new Client %s', self)
Expand All @@ -54,7 +58,7 @@ def __init__(self,

self.proxies = proxies
self.language = {'Accept-Language': language}
self.credentials = {'email': username,
self.credentials = {'email': email,
'password': password}

self.delay = delay
Expand All @@ -68,12 +72,13 @@ def __init__(self,

# Automatic login
if login and self.account:
logger.debug('Automatic login triggered')
self.login()

def reset(self) -> None:
'''
Reset the client requests session.
This is useful if you are keeping the client running
for a long time and can help with Pornhub rate limit.
'''

# Initialise session
Expand All @@ -92,19 +97,23 @@ def call(self,
throw: bool = True,
silent: bool = False) -> requests.Response:
'''
Send a request.
Used internally to send a request or an API call.
Args:
func (str): URL or PH function to call.
method (str): Request method.
data (dict): Optional data to send to the server.
headers (dict): Request optional headers.
func (str): URL or PH function to fetch or call.
method (str): Request method (GET, POST, PUT, ...).
data (dict): Optional data to send to the server.
headers (dict): Additional request headers.
timeout (float): Request maximum response time.
throw (bool): Whether to raise an error when a request explicitly fails.
silent (bool): Make the call logging one level deeper.
throw (bool): Whether to raise an error when a request explicitly fails.
silent (bool): Whether to supress this call from logs.
Returns:
requests.Response: The fetched response.
Response: The fetched response.
Raises:
ConnectionError: If the request was blocked by Pornhub.
HTTPError: If the request failed, for any reason.
'''

logger.log(logging.DEBUG if silent else logging.INFO, 'Fetching %s', func or '/')
Expand Down Expand Up @@ -168,6 +177,10 @@ def login(self,
Returns:
bool: Whether the login was successful.
Raises:
ClientAlreadyLogged: If ``force`` was False and client was already logged.
LoginFailed: If the login failed, for a reason passed in the error body.
'''

logger.debug('Attempting login')
Expand Down Expand Up @@ -203,10 +216,10 @@ def login(self,

def get(self, video: str | Video) -> Video:
'''
Fetch a Pornhub video.
Get a Pornhub video.
Args:
video (str): Video full URL, partial URL or viewkey.
video (str | Video): Video URL or viewkey.
Returns:
Video: The corresponding video object.
Expand Down Expand Up @@ -238,10 +251,10 @@ def get(self, video: str | Video) -> Video:

def get_user(self, user: str | User) -> User:
'''
Get a specific user.
Get a Pornhub user.
Args:
user (str): user URL or name.
user (str | User): user URL or name.
Returns:
User: The corresponding user object.
Expand All @@ -265,13 +278,16 @@ def search_hubtraffic(self,
It is condidered to be much faster but has less filters.
Args:
query (str): The query to search.
category (str): A category the video is in.
sort (str): Sorting type.
period (str): When using sort, specify the search period.
query (str): The query to search.
category (str): A category the video is in.
sort (str): Sorting type.
period (str): When using sort, specify the search period.
Returns:
Query: Initialised query.
Query: Initialised query response.
Raises:
AssertionError: If one or more filters don't match their literals.
'''

literals.ass('category', category, literals.category)
Expand Down Expand Up @@ -304,16 +320,20 @@ def search(self,
Performs searching on Pornhub.
Args:
query (str): The query to search.
production (str): Production type.
category (str): A category the video is in.
query (str): The query to search.
production (str): Production type.
category (str): A category the video is in.
exclude_category (str | list): One or more categories to exclude.
hd (bool): Whether to search only HD videos.
sort (str): Sorting type.
period (str): When using sort, specify the search period.
hd (bool): Whether to search only HD videos.
sort (str): Sorting type.
period (str): When using sort, specify the search period.
Returns:
Query: Initialised query.
Raises:
AssertioneError: If the query is empty.
AssertioneError: If one or more filters don't match their literals.
'''

query = query.strip()
Expand Down Expand Up @@ -341,49 +361,63 @@ def search(self,
query_repr = query
)

def get_playlist(self, pl: str | int | Playlist) -> Playlist:
def get_playlist(self, playlist: str | int | Playlist) -> Playlist:
'''
Initializes a Playlist object.
Get a Pornhub playlist.
Args:
pl (str | int | Playlist): The playlist url or id
playlist (str | int | Playlist): The playlist url or id
Returns:
Playlist object
Playlist: The corresponding playlist object.
Raises:
TypeError: If the playlist argument is invalid.
'''

assert isinstance(pl, str | int | Playlist), 'Invalid type'
if not isinstance(playlist, str | int | Playlist):
raise TypeError(f'Invalid type: {type(playlist)} should be str, int or Playlist.')

if isinstance(pl, Playlist):
pl = pl.url
if isinstance(playlist, Playlist):
playlist = playlist.url

if isinstance(pl, str) and 'playlist' in pl:
pl = pl.split('/')[-1]
if isinstance(playlist, str) and 'playlist' in playlist:
playlist = playlist.split('/')[-1]

return Playlist(self, pl)
return Playlist(self, playlist)

def search_user(self,
username: str = None,
country: str = None,
city: str = None,
min_age: int = None,
max_age: int = None,
gender: literals.gender = None,
orientation: literals.orientation = None,
offers: literals.offers = None,
relation: literals.relation = None,
sort: literals.sort_user = None,
is_online: bool = None,
is_model: bool = None,
is_staff: bool = None,
has_avatar: bool = None,
has_videos: bool = None,
has_photos: bool = None,
has_playlists: bool = None
) -> queries.UserQuery:
username: str = None, country: str = None,
city: str = None, min_age: int = None,
max_age: int = None, gender: literals.gender = None,
orientation: literals.orientation = None, offers: literals.offers = None,
relation: literals.relation = None, sort: literals.sort_user = None,
is_online: bool = None, is_model: bool = None,
is_staff: bool = None, has_avatar: bool = None,
has_videos: bool = None, has_photos: bool = None,
has_playlists: bool = None) -> queries.UserQuery:
'''
Search for users in the community.
Args:
username (str): Filters users with a name query.
country (str): Filter users with a country.
city (str): Filters users with a city.
min_age (int): Filters users with a minimal age.
max_age (int): Filters users with a maximal age.
gender (gender): Filters users with a gender.
orientation (orientation): Filters users with an orientation.
offers (offers): Filters users with what content they do on their channel.
relation (relation): Filters users with their relation.
sort (sort_user): Response sort type.
is_online (bool): Get only online or offline users.
is_model (bool): Get only model users.
is_staff (bool): Get only Pornhub staff members.
has_avatar (bool): Get only users with a custom avatar.
has_videos (bool): Get only users that have posted videos.
has_photos (bool): Get only users that have posted photos.
has_playlists (bool): Get only users that have posted playlists.
Returns:
UserQuery: Initialised query.
'''
Expand Down Expand Up @@ -414,7 +448,7 @@ def search_user(self,

def _clear_granted_token(self) -> None:
'''
Clear the granted token cache.
Removes the current granted token stored, if any.
'''

if '_granted_token' in self.__dict__:
Expand All @@ -423,13 +457,14 @@ def _clear_granted_token(self) -> None:
@cached_property
def _granted_token(self) -> str:
'''
Get a granted token after having
authentified the account.
Get a granted token for the account. Used internally
for making API calls.
Raises:
AssertionError: If the client is not logged in
'''

assert self.logged, 'Client must be logged in'
self._token_controller = True

page = self.call('').text
return consts.re.get_token(page)

Expand Down
42 changes: 10 additions & 32 deletions src/phub/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

class ClientAlreadyLogged(Exception):
'''
The Client already has initiated
a login call which was successful.
The Client is already logged in.
'''

class LoginFailed(Exception):
'''
The Client failed to connect.
Given credentials might be wrong.
Input credentials might be wrong.
'''

class RegexError(Exception):
Expand All @@ -21,53 +20,32 @@ class RegexError(Exception):

class URLError(Exception):
'''
Provided URL is invalid.
The provided URL is invalid.
'''

class ParsingError(Exception):
'''
The parser failed to properly
fetch data.
The parser failed to properly fetch data.
'''

class MaxRetriesExceeded(Exception):
'''
A module failed its job after too
many retries. You might want to
try again after a little time.
A process failed after too many retries.
You can also use: attr:`Client.delay`
to slow down requests.
Note: You can use: attr:`Client.delay` to slow down requests.
'''

class UserNotFound(Exception):
'''
User wasn't found. This either happens
because the user does not exist, or
its name or URL is wrong.
User could not be foundn either because
it does not exists, or its name/URL is wrong.
'''

class NoResult(Exception):
'''
A query failed to retrieve an item
at a specific index. Most of the time,
this is raised when you go too far in
a fetching loop:
.. code-block:: python
query = ...
for i in range(1000):
print(query[i])
Instead, use:
.. code-block:: python
query = ...
for item in query[:1000]:
print(item)
this is the equivalent of a StopIteration signal.
'''

class InvalidCategory(Exception):
Expand All @@ -88,7 +66,7 @@ class VideoError(Exception):
'''
Pornhub refused to serve video data because
of some internal error (mostly because the video
is not available anymore).
is not available).
'''

# EOF
Loading

0 comments on commit 4430a83

Please sign in to comment.