Initial cleanup of playlist support; getStreamURL not working; Needs tests

This commit is contained in:
Michael Shepanski 2016-03-21 23:52:58 -04:00
parent 3502f454ea
commit a0cfaafb68
3 changed files with 33 additions and 74 deletions

View file

@ -42,11 +42,6 @@ class Audio(utils.PlexPartialObject):
params['protocol'] = kwargs['protocol']
return self.server.url('/audio/:/transcode/universal/start.m3u8?%s' % urlencode(params))
def reload(self):
self.initpath = '/library/metadata/%s' % self.ratingKey
data = self.server.query(self.initpath)
self._loadData(data[0])
@utils.register_libtype
class Artist(Audio):

View file

@ -1,52 +1,35 @@
# -*- coding: utf-8 -*-
"""
PlexPlaylist
"""
import re
from plexapi.client import Client
#from plexapi.media import Media, Genre, Producer, Country #, TranscodeSession
from plexapi.myplex import MyPlexUser
from plexapi.exceptions import NotFound, UnknownType, Unsupported
from plexapi.utils import PlexPartialObject, NA
from plexapi import utils
from plexapi.compat import urlencode
from plexapi.exceptions import Unsupported
from plexapi.utils import cast, toDatetime
from plexapi.video import Video # TODO: remove this when the Playlist class can stand on its own legs
try:
from urllib import urlencode # Python2
except ImportError:
from urllib.parse import urlencode # Python3
NA = utils.NA
class Playlist(Video): # TODO: inherit from PlexPartialObject, like the Video class does
@utils.register_libtype
class Playlist(utils.PlexPartialObject):
TYPE = 'playlist'
def _loadData(self, data):
self.type = data.attrib.get('type', NA)
self.key = data.attrib.get('key', NA)
self.ratingKey = data.attrib.get('ratingKey', NA)
self.title = data.attrib.get('title', NA)
self.summary = data.attrib.get('summary', NA)
self.smart = cast(bool, data.attrib.get('smart', NA))
self.playlistType = data.attrib.get('playlistType', NA)
self.addedAt = toDatetime(data.attrib.get('addedAt', NA))
self.updatedAt = toDatetime(data.attrib.get('updatedAt', NA))
self.composite = data.attrib.get('composite', NA) # plex uri to thumbnail
self.composite = data.attrib.get('composite', NA) # uri to thumbnail
self.duration = cast(int, data.attrib.get('duration', NA))
self.leafCount = cast(int, data.attrib.get('leafCount', NA)) # number of items in playlist
self.durationInSeconds = cast(int, data.attrib.get('durationInSeconds', NA))
self.guid = data.attrib.get('guid', NA)
self.user = self._find_user(data) # for active sessions
self.player = self._find_player(data) # for active sessions
if False: #self.isFullObject():
# These are auto-populated when requested
self.media = [Media(self.server, elem, self.initpath, self) for elem in data if elem.tag == Media.TYPE]
self.genres = [Genre(self.server, elem) for elem in data if elem.tag == Genre.TYPE]
self.producers = [Producer(self.server, elem) for elem in data if elem.tag == Producer.TYPE]
# will we ever see other elements?
#self.actors = [Actor(self.server, elem) for elem in data if elem.tag == Actor.TYPE]
#self.writers = [Writer(self.server, elem) for elem in data if elem.tag == Writer.TYPE]
self.key = data.attrib.get('key', NA).replace('/items', '') # plex bug? http://bit.ly/1Sc2J3V
self.leafCount = cast(int, data.attrib.get('leafCount', NA))
self.playlistType = data.attrib.get('playlistType', NA)
self.ratingKey = data.attrib.get('ratingKey', NA)
self.smart = cast(bool, data.attrib.get('smart', NA))
self.summary = data.attrib.get('summary', NA)
self.title = data.attrib.get('title', NA)
self.type = data.attrib.get('type', NA)
self.updatedAt = toDatetime(data.attrib.get('updatedAt', NA))
# TODO: FIXME (Let's move getStreamURL to utils and make it more generic)
def getStreamUrl(self, offset=0, **kwargs):
""" Fetch URL to stream audio directly.
offset: Start time (in seconds) audio will initiate from (ex: 300).
@ -64,35 +47,11 @@ class Playlist(Video): # TODO: inherit from PlexPartialObject, like the Video cl
params['protocol'] = kwargs['protocol']
return self.server.url('/audio/:/transcode/universal/start.m3u8?%s' % urlencode(params))
def items(self, watched=None):
if self.playlistType == 'audio':
from audio import list_items
elif self.playlistType == 'video':
from video import list_items
return list_items(self.server, self.key, watched=watched)
def items(self):
path = '%s/items' % self.key
return utils.listItems(self.server, path)
# TODO: figure out if we really need to override these methods, or if there is a bug in the default
# implementation
def isFullObject(self):
return self.initpath == '/playlists/{0!s}'.format(self.ratingKey)
def isPartialObject(self):
return self.initpath != '/playlists/{0!s}'.format(self.ratingKey)
def reload(self):
self.initpath = '/playlists/{0!s}'.format(self.ratingKey)
data = self.server.query(self.initpath)
self._loadData(data[0])
def list_items(server, path, playlisttype=None, watched=None):
# playlisttype may be 'audio', 'video' or None (for both)
items = []
for elem in server.query(path):
if playlisttype and elem.attrib.get('type') != playlisttype: continue
if watched is True and elem.attrib.get('viewCount', 0) == 0: continue
if watched is False and elem.attrib.get('viewCount', 0) >= 1: continue
try:
items.append(Playlist(server, elem, path))
except UnknownType:
pass
return items
# plex bug? http://bit.ly/1Sc2J3V
fixed_key = self.key.replace('/items', '')
return self.initpath == fixed_key

View file

@ -77,6 +77,15 @@ class PlexServer(object):
if self.token:
headers['X-Plex-Token'] = self.token
return headers
def playlists(self):
return utils.listItems(self, '/playlists')
def playlist(self, title=None): # noqa
for item in self.playlists():
if item.title == title:
return item
raise NotFound('Invalid playlist title: %s' % title)
def query(self, path, method=None, **kwargs):
global TOTAL_QUERIES
@ -105,7 +114,3 @@ class PlexServer(object):
delim = '&' if '?' in path else '?'
return '%s%s%sX-Plex-Token=%s' % (self.baseuri, path, delim, self.token)
return '%s%s' % (self.baseuri, path)
def playlists(self, playlisttype=None):
'Get playlists. `playlisttype` may be "audio", "video" or None (for both types)'
return playlist.list_items(self, '/playlists')