Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
811f661
Add LibrarySection.hubSearch()
JonnyWong16 Mar 11, 2021
0398895
Update all library filtering related objects
JonnyWong16 Mar 11, 2021
abbace6
Update library search filtering methods
JonnyWong16 Mar 11, 2021
146a184
Add searchMovies method to MovieSection
JonnyWong16 Mar 11, 2021
13cc13c
Add searchSeasons method to ShowSection
JonnyWong16 Mar 11, 2021
1e8d98f
Add & operator for library search
JonnyWong16 Mar 11, 2021
c77dc4a
Cast librarySectionID to int
JonnyWong16 Mar 11, 2021
b35dc53
Make sure filter values are casted to string
JonnyWong16 Mar 11, 2021
ee161e4
Fix searching using MediaTag
JonnyWong16 Mar 11, 2021
c4f4743
Fix sorting with libtype
JonnyWong16 Mar 11, 2021
ddc5e98
Update library tests
JonnyWong16 Mar 11, 2021
9e063bf
Separate validate functions
JonnyWong16 Mar 11, 2021
0de2349
Rename validateSortField
JonnyWong16 Mar 11, 2021
95c47c6
Remove unused import
JonnyWong16 Mar 11, 2021
b3dd526
Update validate value exception message
JonnyWong16 Mar 11, 2021
6d4c8e5
Fix flake8 search complexity
JonnyWong16 Mar 11, 2021
6e50172
Cast librarySectionID to int
JonnyWong16 Mar 11, 2021
42163b8
Fix smart playlist listFilterChoices
JonnyWong16 Mar 11, 2021
e5607e1
Improve matching of libtype for filter field and sort
JonnyWong16 Mar 11, 2021
cd5b0e3
Update doc strings for list filter methods
JonnyWong16 Mar 11, 2021
08ea6ca
Fallback to assume libtype for a filter
JonnyWong16 Mar 12, 2021
5cece7d
Change unknown search filters to NotFound
JonnyWong16 Mar 12, 2021
2c8c527
Fix build docs
JonnyWong16 Mar 12, 2021
86072c2
Move libtype to validate functions
JonnyWong16 Mar 12, 2021
da5699c
Fix joining search params
JonnyWong16 Mar 12, 2021
cbdda0b
Allow datetime object for filtering date values
JonnyWong16 Mar 12, 2021
93a5ab6
Fix filter libtype fallback
JonnyWong16 Mar 12, 2021
618ed22
Update search doc string with examples
JonnyWong16 Mar 12, 2021
f90b5ac
Update search doc string with plexapi operator examples
JonnyWong16 Mar 12, 2021
d752b35
Update fetchItem doc string
JonnyWong16 Mar 12, 2021
1c180c0
Update screenshots
JonnyWong16 Mar 12, 2021
ba98669
Update search doc string
JonnyWong16 Mar 12, 2021
061ad9f
More PlexAPI filtering docs to fetchItems
JonnyWong16 Mar 12, 2021
b9840ee
Update search docs formatting
JonnyWong16 Mar 12, 2021
4b25d4a
Print available filters when raising NotFound
JonnyWong16 Mar 12, 2021
8adedd6
Add deprecated functions filterFields and listChoices
JonnyWong16 Mar 12, 2021
5bff309
More search doc string updates
JonnyWong16 Mar 13, 2021
8cc90fc
Fix libtype for listFilterChoices
JonnyWong16 Mar 14, 2021
ea18753
Print available libtypes and field types for exception
JonnyWong16 Mar 14, 2021
e1ab49f
Fix & search operator
JonnyWong16 Mar 15, 2021
684bbde
Change search break condition
JonnyWong16 Mar 15, 2021
357818a
Use separate totalViewSize cache for searching
JonnyWong16 Mar 15, 2021
3422bb7
Separate search function for flake8 complexity
JonnyWong16 Mar 15, 2021
1674d08
Add tests for library search
JonnyWong16 Mar 19, 2021
61d73be
Don't use utils.cast for search values
JonnyWong16 Mar 19, 2021
c02a005
Add more search tests
JonnyWong16 Mar 19, 2021
b9798e9
Fix searchSeasons test
JonnyWong16 Mar 19, 2021
813770a
Add additional test for libtype fallback for search field
JonnyWong16 Mar 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/LibrarySection.listSorts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/LibrarySection.search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion plexapi/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def _loadData(self, data):
self.index = utils.cast(int, data.attrib.get('index'))
self.key = data.attrib.get('key', '')
self.lastViewedAt = utils.toDatetime(data.attrib.get('lastViewedAt'))
self.librarySectionID = data.attrib.get('librarySectionID')
self.librarySectionID = utils.cast(int, data.attrib.get('librarySectionID'))
self.librarySectionKey = data.attrib.get('librarySectionKey')
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
self.listType = 'audio'
Expand Down
101 changes: 70 additions & 31 deletions plexapi/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,34 +144,9 @@ def fetchItem(self, ekey, cls=None, **kwargs):
it only returns those items. By default we convert the xml elements
with the best guess PlexObjects based on tag and type attrs.
etag (str): Only fetch items with the specified tag.
**kwargs (dict): Optionally add attribute filters on the items to fetch. For
example, passing in viewCount=0 will only return matching items. Filtering
is done before the Python objects are built to help keep things speedy.
Note: Because some attribute names are already used as arguments to this
function, such as 'tag', you may still reference the attr tag byappending
an underscore. For example, passing in _tag='foobar' will return all items
where tag='foobar'. Also Note: Case very much matters when specifying kwargs
-- Optionally, operators can be specified by append it
to the end of the attribute name for more complex lookups. For example,
passing in viewCount__gte=0 will return all items where viewCount >= 0.
Available operations include:

* __contains: Value contains specified arg.
* __endswith: Value ends with specified arg.
* __exact: Value matches specified arg.
* __exists (bool): Value is or is not present in the attrs.
* __gt: Value is greater than specified arg.
* __gte: Value is greater than or equal to specified arg.
* __icontains: Case insensative value contains specified arg.
* __iendswith: Case insensative value ends with specified arg.
* __iexact: Case insensative value matches specified arg.
* __in: Value is in a specified list or tuple.
* __iregex: Case insensative value matches the specified regular expression.
* __istartswith: Case insensative value starts with specified arg.
* __lt: Value is less than specified arg.
* __lte: Value is less than or equal to specified arg.
* __regex: Value matches the specified regular expression.
* __startswith: Value starts with specified arg.
**kwargs (dict): Optionally add XML attribute to filter the items.
See :func:`~plexapi.base.PlexObject.fetchItems` for more details
on how this is used.
"""
if ekey is None:
raise BadRequest('ekey was not provided')
Expand All @@ -185,12 +160,76 @@ def fetchItem(self, ekey, cls=None, **kwargs):

def fetchItems(self, ekey, cls=None, container_start=None, container_size=None, **kwargs):
""" Load the specified key to find and build all items with the specified tag
and attrs. See :func:`~plexapi.base.PlexObject.fetchItem` for more details
on how this is used.
and attrs.

Parameters:
ekey (str): API URL path in Plex to fetch items from.
cls (:class:`~plexapi.base.PlexObject`): If you know the class of the
items to be fetched, passing this in will help the parser ensure
it only returns those items. By default we convert the xml elements
with the best guess PlexObjects based on tag and type attrs.
etag (str): Only fetch items with the specified tag.
container_start (None, int): offset to get a subset of the data
container_size (None, int): How many items in data
**kwargs (dict): Optionally add XML attribute to filter the items.
See the details below for more info.

**Filtering XML Attributes**

Any XML attribute can be filtered when fetching results. Filtering is done before
the Python objects are built to help keep things speedy. For example, passing in
``viewCount=0`` will only return matching items where the view count is ``0``.
Note that case matters when specifying attributes. Attributes futher down in the XML
tree can be filtered by *prepending* the attribute with each element tag ``Tag__``.

Examples:

.. code-block:: python

fetchItem(ekey, viewCount=0)
fetchItem(ekey, contentRating="PG")
fetchItem(ekey, Genre__tag="Animation")
fetchItem(ekey, Media__videoCodec="h265")
fetchItem(ekey, Media__Part__container="mp4)

Note that because some attribute names are already used as arguments to this
function, such as ``tag``, you may still reference the attr tag by prepending an
underscore. For example, passing in ``_tag='foobar'`` will return all items where
``tag='foobar'``.

**Using PlexAPI Operators**

Optionally, PlexAPI operators can be specified by *appending* it to the end of the
attribute for more complex lookups. For example, passing in ``viewCount__gte=0``
will return all items where ``viewCount >= 0``.

List of Available Operators:

* ``__contains``: Value contains specified arg.
* ``__endswith``: Value ends with specified arg.
* ``__exact``: Value matches specified arg.
* ``__exists`` (*bool*): Value is or is not present in the attrs.
* ``__gt``: Value is greater than specified arg.
* ``__gte``: Value is greater than or equal to specified arg.
* ``__icontains``: Case insensative value contains specified arg.
* ``__iendswith``: Case insensative value ends with specified arg.
* ``__iexact``: Case insensative value matches specified arg.
* ``__in``: Value is in a specified list or tuple.
* ``__iregex``: Case insensative value matches the specified regular expression.
* ``__istartswith``: Case insensative value starts with specified arg.
* ``__lt``: Value is less than specified arg.
* ``__lte``: Value is less than or equal to specified arg.
* ``__regex``: Value matches the specified regular expression.
* ``__startswith``: Value starts with specified arg.

Examples:

.. code-block:: python

fetchItem(ekey, viewCount__gte=0)
fetchItem(ekey, Media__container__in=["mp4", "mkv"])
fetchItem(ekey, guid__iregex=r"(imdb:\/\/|themoviedb:\/\/)")
fetchItem(ekey, Media__Part__file__startswith="D:\\Movies")

"""
url_kw = {}
Expand All @@ -204,7 +243,7 @@ def fetchItems(self, ekey, cls=None, container_start=None, container_size=None,
data = self._server.query(ekey, params=url_kw)
items = self.findItems(data, cls, ekey, **kwargs)

librarySectionID = data.attrib.get('librarySectionID')
librarySectionID = utils.cast(int, data.attrib.get('librarySectionID'))
if librarySectionID:
for item in items:
item.librarySectionID = librarySectionID
Expand Down
2 changes: 1 addition & 1 deletion plexapi/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _loadData(self, data):
self.index = utils.cast(int, data.attrib.get('index'))
self.key = data.attrib.get('key', '').replace('/children', '') # FIX_BUG_50
self.labels = self.findItems(data, media.Label)
self.librarySectionID = data.attrib.get('librarySectionID')
self.librarySectionID = utils.cast(int, data.attrib.get('librarySectionID'))
self.librarySectionKey = data.attrib.get('librarySectionKey')
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
self.maxYear = utils.cast(int, data.attrib.get('maxYear'))
Expand Down
Loading