Skip to content

Commit

Permalink
moved errors + search parameters constants
Browse files Browse the repository at this point in the history
  • Loading branch information
Egsago-n committed Aug 20, 2023
1 parent fd40a6c commit d89f6c3
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 124 deletions.
7 changes: 6 additions & 1 deletion docs/source/api/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ by other PHUB objects.
.. autoclass:: phub.utils.Quality
:members:
:undoc-members:
:special-members: __init__, __new__
:special-members: __init__, __new__

.. autoclass:: phub.utils.Category
:members:
:undoc-members:
:special-members: __init__
14 changes: 9 additions & 5 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ like so:
client = phub.Client()
url = 'https://www.pornhub.com/view_video.php?viewkey=xxx'
video = client.get(url)
video = client.get(url) # (1)!
# video will be a phub.Video object
# Note - You can also load the video
# using its `viewkey` https argument
# if you think that improves clarity.
video = client.get(key = 'xxx')
.. code-annotations::
#.
Note that you can also load the video
using the `viewkey` paramater in the URL.

.. code-block:: python
video = client.get(key = 'xxx')
Accessing video data
--------------------
Expand Down
29 changes: 29 additions & 0 deletions docs/source/searching.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Searching
=========

.. warning::

The search feature might give inacurate results.
I don't know yet why.

One feature of PHUB is that it is able to
send and receive queries.

Expand Down Expand Up @@ -34,3 +39,27 @@ if needed. You can access its content like so:
.. note:: Unlike :meth:`.Client.get`, by default the content
of the video is not fetched yet, unless you ask for it
(by calling `video.title` for example).

Search filters
--------------

PHUB support filtering queries like on the PH website.

.. automethod:: phub.core.Client.search

Category object
^^^^^^^^^^^^^^^

Categories objects are concatenable, e.g.:

.. code-block:: python
from phub import Category
# Represents both french and german categories
my_category = Category.FRENCH | Category.GERMAN
query = client.search(exclude_category = my_category) # (1)!
.. code-annotations::
#. Pornhub doesn't support searching through multiple categories at once, so you can use this feature only with :atth:`exclude_category` and not :attr:`category`.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = phub
version = 3.1.4
version = 3.2
description = An API for PornHub
author = Egsagon
author_email = [email protected]
Expand Down
7 changes: 3 additions & 4 deletions src/phub/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
'''
#### PHUB - An API wrapper.
#### PHUB - An API wrapper for Pornhub.
See https://phub.rtfd.io for documentation.
'''

from phub import ( core, utils, consts, classes, parser )
from phub import ( core, utils, consts, classes, parser, errors )

# Shortcuts
from phub.core import Client
from phub.utils import Quality
from phub.classes import Video, User
from phub.consts import locals
from phub.utils import Quality, Category

# Debugging controls
from sys import stdout
Expand Down
38 changes: 23 additions & 15 deletions src/phub/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@
from datetime import datetime, timedelta
from functools import cached_property, cache

Soup = None
try:
from bs4 import BeautifulSoup as Soup

except ModuleNotFoundError:
print('Warning: BS4 not installed. Feed features will not be available.')

from phub import utils
from phub import consts
from phub import parser
from phub import errors

from phub.utils import (
log,
register_properties,
download_presets as dlp
)

try:
from bs4 import BeautifulSoup as Soup

except ModuleNotFoundError:
log('phub', 'Warning: BS4 not installed. Feed features will not be available.')
Soup = None


@dataclass
class User:
Expand Down Expand Up @@ -106,7 +108,7 @@ def get(cls,
return cls(name = name, path = url, client = client)

else:
raise consts.UserNotFoundError(f'User `{name}` not found.')
raise errors.UserNotFoundError(f'User `{name}` not found.')

@cached_property
def videos(self) -> Query:
Expand Down Expand Up @@ -222,7 +224,7 @@ def _fetch(self, key: str) -> Any:
return value

except ValueError:
raise consts.ParsingError(f'key `{key}` does not exists in video data.')
raise errors.ParsingError(f'key `{key}` does not exists in video data.')

# ========= Download ========= #

Expand Down Expand Up @@ -470,7 +472,7 @@ def __init__(self, client: Client, url: str, corrector: Callable = None) -> None
log('query', 'Initialising new Query object', level = 6)

self.client = client
self.url = (url + '?&'['?' in url] + 'page=').replace(consts.ROOT, '')
self.url = url.replace(consts.ROOT, '')

self._length: int = None
self.index = 0
Expand All @@ -496,7 +498,7 @@ def __len__(self) -> int:
counter = consts.regexes.video_search_counter(self.page)
log('query', 'Collected counters:', counter, level = 4)

if len(counter) != 1: raise consts.CounterNotFound()
if len(counter) != 1: raise errors.CounterNotFound()
return int(counter[0])

def __getitem__(self, index: int | slice) -> Video | Generator[Video, None, None]:
Expand All @@ -517,8 +519,9 @@ def __getitem__(self, index: int | slice) -> Video | Generator[Video, None, None

return self.get(index)

def wrapper(): # We need to wrap this, otherwise the whole __getitem__ will be
# Interpreted as a generator.
def wrapper() -> Generator[Video, None, None]:
# We need to wrap this, otherwise the whole __getitem__ will be
# Interpreted as a generator.

indices = index.indices(len(self))

Expand Down Expand Up @@ -572,10 +575,15 @@ def _get_page(self, index: int) -> None:

log('query', 'Fetching page at index', index, level = 4)

response = self.client._call('GET', self.url + str(index + 1), throw = False)
if index == 0: url = self.url

else:
url = self.url + '?&'['?' in url] + 'page=' + str(index + 1)

response = self.client._call('GET', url, throw = False)

if response.status_code == 404:
raise consts.Noresult('No result for the given query.')
raise errors.Noresult('No result for the given query.')

raw = response.text

Expand Down
100 changes: 18 additions & 82 deletions src/phub/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@
None: None
}

# Search production filters
PROFESSIONAL = 'professional'
HOMEMADE = 'homemade'

# Search sort filters
MOST_RELEVANT = None
MOST_RECENT = 'most recent'
MOST_VIEWED = 'most viewed'
TOP_RATED = 'top rated'
LONGEST = 'longest'

# Search time filters
DAY = 'day'
WEEK = 'week'
MONTH = 'month'
YEAR = 'year'

class regexes:
'''
Compiled regexes methods used for parsing.
Expand Down Expand Up @@ -82,85 +99,4 @@ class FeedType:
COMMENTED = 'stream_grouped_comments_videos'
# TODO more stream types


class locals:
'''
Locales constants.
'''

# Search production types
PROFESSIONAL = 'professional'
HOMEMADE = 'homemade'

# Search sort filters
MOST_RELEVANT = None
MOST_RECENT = 'most recent'
MOST_VIEWED = 'most viewed'
TOP_RATED = 'top rated'
LONGEST = 'longest'

# Search time filters
DAY = 'day'
WEEK = 'week'
MONTH = 'month'
YEAR = 'year'

# Exceptions

class CounterNotFound(Exception):
'''
The video counter wasn't found in the query,
or is badly parsed.
'''

pass

class ParsingError(Exception):
'''
The parser failed to properly resolve the script
for this element.
'''

pass

class UserNotFoundError(Exception):
'''
Failed to find a PH user account.
'''

pass

class NotLoggedIn(Exception):
'''
The client is not logged to a PH account,
but tried to access account data.
'''

class AlreadyLoggedIn(Exception):
'''
The client already established a connection with PH.
'''

class LogginFailed(Exception):
'''
Login phase failed. Credentials may be wrong.
'''

class TooManyRequests(Exception):
'''
The client sent too many requests.
To bypass, consider using proxies or
set a small delay to the client request:
.. code-block:: python
client = phub.Client(delay = True)
'''

class Noresult(Exception):
'''
The search query did not found videos with
its given filters.
'''

# EOF
# EOF
Loading

0 comments on commit d89f6c3

Please sign in to comment.