From 0a66414fcde9811472feec62957b4844ffa11173 Mon Sep 17 00:00:00 2001 From: Michael Shepanski Date: Fri, 3 Feb 2017 02:15:41 -0500 Subject: [PATCH] Add ability to dig deeper in the MediaTag search results. For example: Genre.items() will return the list of items for that tag if the key attribute is available --- plexapi/media.py | 47 +++++++++++++++++++++++++++++++++++++++++++++-- plexapi/server.py | 4 ++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/plexapi/media.py b/plexapi/media.py index 63218beb..0ac80ea6 100644 --- a/plexapi/media.py +++ b/plexapi/media.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -from plexapi.utils import cast +from plexapi.exceptions import BadRequest +from plexapi.utils import cast, listItems class Media(object): @@ -161,6 +162,31 @@ class TranscodeSession(object): class MediaTag(object): + """ Base class for media tags used for filtering and searching your library + items or navigating the metadata of media items in your library. Tags are + the construct used for things such as Country, Director, Genre, etc. + + Parameters: + server (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional) + data (ElementTree): Response from PlexServer used to build this object (optional). + + Attributes: + server (:class:`~plexapi.server.PlexServer`): Server this client is connected to. + id (id): Tag ID (This seems meaningless except to use it as a unique id). + role (str): Unknown + tag (str): Name of the tag. This will be Animation, SciFi etc for Genres. The name of + person for Directors and Roles (ex: Animation, Stephen Graham, etc). + : Attributes only applicable in search results from + PlexServer :func:`~plexapi.server.PlexServer.search()`. They provide details of which + library section the tag was found as well as the url to dig deeper into the results. + + * key (str): API URL to dig deeper into this tag (ex: /library/sections/1/all?actor=9081). + * librarySectionID (int): Section ID this tag was generated from. + * librarySectionTitle (str): Library section title this tag was found. + * librarySectionType (str): Media type of the library section this tag was found. + * tagType (int): Tag type ID. + * thumb (str): URL to thumbnail image. + """ TYPE = None def __init__(self, server, data): @@ -168,10 +194,27 @@ class MediaTag(object): self.id = cast(int, data.attrib.get('id')) self.role = data.attrib.get('role') self.tag = data.attrib.get('tag') + # additional attributes only from hub search + self.key = data.attrib.get('key') + self.librarySectionID = cast(int, data.attrib.get('librarySectionID')) + self.librarySectionTitle = data.attrib.get('librarySectionTitle') + self.librarySectionType = data.attrib.get('librarySectionType') + self.tagType = cast(int, data.attrib.get('tagType')) + self.thumb = data.attrib.get('thumb') def __repr__(self): tag = self.tag.replace(' ', '.')[0:20].encode('utf-8') - return '<%s:%s:%s>' % (self.__class__.__name__, self.id, tag) + if self.librarySectionTitle: + return u'<%s:%s:%s:%s>' % (self.__class__.__name__, self.id, tag, self.librarySectionTitle) + return u'<%s:%s:%s>' % (self.__class__.__name__, self.id, tag) + + def items(self, *args, **kwargs): + """ Return the list of items within this tag. This function is only applicable + in search results from PlexServer :func:`~plexapi.server.PlexServer.search()`. + """ + if not self.key: + raise BadRequest('Key is not defined for this tag: %s' % self.tag) + return listItems(self.server, self.key) class Collection(MediaTag): diff --git a/plexapi/server.py b/plexapi/server.py index ebc1a370..9cbac4d0 100644 --- a/plexapi/server.py +++ b/plexapi/server.py @@ -4,14 +4,14 @@ from requests.status_codes import _codes as codes from plexapi import BASE_HEADERS, CONFIG, TIMEOUT from plexapi import log, logfilter, utils from plexapi.client import PlexClient -from plexapi.compat import ElementTree, quote, urlencode +from plexapi.compat import ElementTree, urlencode from plexapi.exceptions import BadRequest, NotFound from plexapi.library import Library from plexapi.playlist import Playlist from plexapi.playqueue import PlayQueue from plexapi.utils import NA, cast # import media to populate utils.LIBRARY_TYPES. -from plexapi import audio, video, photo, playlist +from plexapi import audio, video, photo, playlist as _pl class PlexServer(object):