mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-26 05:30:20 +00:00
Initial cleanup of playlist support; getStreamURL not working; Needs tests
This commit is contained in:
parent
3502f454ea
commit
a0cfaafb68
3 changed files with 33 additions and 74 deletions
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in a new issue