Fix server hub searches (#643)

* Add hub search media tag objects

* Fix server search

* Fix hub media tag thumb

* Update server search test with tags
This commit is contained in:
JonnyWong16 2021-01-24 12:48:38 -08:00 committed by GitHub
parent a9a44a6a41
commit dfc5aa1eef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 149 additions and 7 deletions

View file

@ -77,7 +77,7 @@ class PlexObject(object):
if cls is not None:
return cls(self._server, elem, initpath, parent=self)
# cls is not specified, try looking it up in PLEXOBJECTS
etype = elem.attrib.get('type', elem.attrib.get('streamType'))
etype = elem.attrib.get('streamType', elem.attrib.get('tagType', elem.attrib.get('type')))
ehash = '%s.%s' % (elem.tag, etype) if etype else elem.tag
ecls = utils.PLEXOBJECTS.get(ehash, utils.PLEXOBJECTS.get(elem.tag))
# log.debug('Building %s as %s', elem.tag, ecls.__name__)

View file

@ -1247,6 +1247,110 @@ class Hub(PlexObject):
self.size = len(self.items)
class HubMediaTag(PlexObject):
""" Base class of hub media tag search results.
Attributes:
count (int): The number of items where this tag is found.
filter (str): The URL filter for the tag.
id (int): The id of the tag.
key (str): API URL (/library/section/<librarySectionID>/all?<filter>).
librarySectionID (int): The library section ID where the tag is found.
librarySectionKey (str): API URL for the library section (/library/section/<librarySectionID>)
librarySectionTitle (str): The library title where the tag is found.
librarySectionType (int): The library type where the tag is found.
reason (str): The reason for the search result.
reasonID (int): The reason ID for the search result.
reasonTitle (str): The reason title for the search result.
type (str): The type of search result (tag).
tag (str): The title of the tag.
tagType (int): The type ID of the tag.
tagValue (int): The value of the tag.
thumb (str): The URL for the thumbnail of the tag (if available).
"""
TAG = 'Directory'
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
self._data = data
self.count = utils.cast(int, data.attrib.get('count'))
self.filter = data.attrib.get('filter')
self.id = utils.cast(int, data.attrib.get('id'))
self.key = data.attrib.get('key')
self.librarySectionID = utils.cast(int, data.attrib.get('librarySectionID'))
self.librarySectionKey = data.attrib.get('librarySectionKey')
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
self.librarySectionType = utils.cast(int, data.attrib.get('librarySectionType'))
self.reason = data.attrib.get('reason')
self.reasonID = utils.cast(int, data.attrib.get('reasonID'))
self.reasonTitle = data.attrib.get('reasonTitle')
self.type = data.attrib.get('type')
self.tag = data.attrib.get('tag')
self.tagType = utils.cast(int, data.attrib.get('tagType'))
self.tagValue = utils.cast(int, data.attrib.get('tagValue'))
self.thumb = data.attrib.get('thumb')
@utils.registerPlexObject
class Tag(HubMediaTag):
""" Represents a single Tag hub search media tag.
Attributes:
TAGTYPE (int): 0
"""
TAGTYPE = 0
@utils.registerPlexObject
class Genre(HubMediaTag):
""" Represents a single Genre hub search media tag.
Attributes:
TAGTYPE (int): 1
"""
TAGTYPE = 1
@utils.registerPlexObject
class Director(HubMediaTag):
""" Represents a single Director hub search media tag.
Attributes:
TAGTYPE (int): 4
"""
TAGTYPE = 4
@utils.registerPlexObject
class Actor(HubMediaTag):
""" Represents a single Actor hub search media tag.
Attributes:
TAGTYPE (int): 6
"""
TAGTYPE = 6
@utils.registerPlexObject
class AutoTag(HubMediaTag):
""" Represents a single AutoTag hub search media tag.
Attributes:
TAGTYPE (int): 207
"""
TAGTYPE = 207
@utils.registerPlexObject
class Place(HubMediaTag):
""" Represents a single Place hub search media tag.
Attributes:
TAGTYPE (int): 400
"""
TAGTYPE = 400
@utils.registerPlexObject
class Station(PlexObject):
""" Represents the Station area in the MusicSection.

View file

@ -522,17 +522,24 @@ class PlexServer(PlexObject):
Parameters:
query (str): Query to use when searching your library.
mediatype (str): Optionally limit your search to the specified media type.
actor, album, artist, autotag, collection, director, episode, game, genre,
movie, photo, photoalbum, place, playlist, shared, show, tag, track
limit (int): Optionally limit to the specified number of results per Hub.
"""
results = []
params = {'query': query}
if mediatype:
params['section'] = utils.SEARCHTYPES[mediatype]
params = {
'query': query,
'includeCollections': 1,
'includeExternalMedia': 1}
if limit:
params['limit'] = limit
key = '/hubs/search?%s' % urlencode(params)
for hub in self.fetchItems(key, Hub):
results += hub.items
if mediatype:
if hub.type == mediatype:
return hub.items
else:
results += hub.items
return results
def sessions(self):

View file

@ -57,7 +57,7 @@ def registerPlexObject(cls):
define a few helper functions to dynamically convery the XML into objects. See
buildItem() below for an example.
"""
etype = getattr(cls, 'STREAMTYPE', cls.TYPE)
etype = getattr(cls, 'STREAMTYPE', getattr(cls, 'TAGTYPE', cls.TYPE))
ehash = '%s.%s' % (cls.TAG, etype) if etype else cls.TAG
if ehash in PLEXOBJECTS:
raise Exception('Ambiguous PlexObject definition %s(tag=%s, type=%s) with %s' %

View file

@ -109,7 +109,38 @@ def test_server_search(plex, movie):
title = movie.title
# this search seem to fail on my computer but not at travis, wtf.
assert plex.search(title)
assert plex.search(title, mediatype="movie")
results = plex.search(title, mediatype="movie")
assert results[0] == movie
# Test genre search
genre = movie.genres[0]
results = plex.search(genre.tag, mediatype="genre")
hub_tag = results[0]
assert utils.is_int(hub_tag.count)
assert hub_tag.filter == "genre={}".format(hub_tag.id)
assert utils.is_int(hub_tag.id)
assert utils.is_metadata(
hub_tag.key,
prefix=hub_tag.librarySectionKey,
contains="{}/all".format(hub_tag.librarySectionID),
suffix=hub_tag.filter)
assert utils.is_int(hub_tag.librarySectionID)
assert utils.is_metadata(hub_tag.librarySectionKey, prefix="/library/sections")
assert hub_tag.librarySectionTitle == "Movies"
assert hub_tag.librarySectionType == 1
assert hub_tag.reason == "section"
assert hub_tag.reasonID == hub_tag.librarySectionID
assert hub_tag.reasonTitle == hub_tag.librarySectionTitle
assert hub_tag.type == "tag"
assert hub_tag.tag == genre.tag
assert hub_tag.tagType == 1
assert hub_tag.tagValue is None
assert hub_tag.thumb is None
# Test director search
director = movie.directors[0]
assert plex.search(director.tag, mediatype="director")
# Test actor search
role = movie.roles[0]
assert plex.search(role.tag, mediatype="actor")
def test_server_playlist(plex, show):