mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-26 13:40:22 +00:00
Cleanup playlist support; Fix UUID on URLs; Better method to store listTypes; Cache section IDs in library
This commit is contained in:
parent
3138ad1087
commit
748fc68406
9 changed files with 70 additions and 51 deletions
|
@ -14,6 +14,7 @@ class Audio(PlexPartialObject):
|
||||||
super(Audio, self).__init__(data, initpath, server)
|
super(Audio, self).__init__(data, initpath, server)
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
|
self.listType = 'audio'
|
||||||
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
||||||
self.index = data.attrib.get('index', NA)
|
self.index = data.attrib.get('index', NA)
|
||||||
self.key = data.attrib.get('key', NA)
|
self.key = data.attrib.get('key', NA)
|
||||||
|
@ -35,18 +36,20 @@ class Audio(PlexPartialObject):
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.server.query('%s/refresh' % self.key, method=self.server.session.put)
|
self.server.query('%s/refresh' % self.key, method=self.server.session.put)
|
||||||
|
|
||||||
|
def section(self):
|
||||||
|
return self.server.library.sectionByID(self.librarySectionID)
|
||||||
|
|
||||||
|
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Artist(Audio):
|
class Artist(Audio):
|
||||||
TYPE = 'artist'
|
TYPE = 'artist'
|
||||||
LISTTYPE = 'audio'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Audio._loadData(self, data)
|
Audio._loadData(self, data)
|
||||||
self.art = data.attrib.get('art', NA)
|
self.art = data.attrib.get('art', NA)
|
||||||
self.guid = data.attrib.get('guid', NA)
|
self.guid = data.attrib.get('guid', NA)
|
||||||
self.key = self.key.replace('/children', '') # FIX_BUG_50
|
self.key = self.key.replace('/children', '') # FIX_BUG_50
|
||||||
self.location = utils.findLocation(data)
|
self.location = utils.findLocations(data, single=True)
|
||||||
if self.isFullObject():
|
if self.isFullObject():
|
||||||
self.countries = [media.Country(self.server, e) for e in data if e.tag == media.Country.TYPE]
|
self.countries = [media.Country(self.server, e) for e in data if e.tag == media.Country.TYPE]
|
||||||
self.genres = [media.Genre(self.server, e) for e in data if e.tag == media.Genre.TYPE]
|
self.genres = [media.Genre(self.server, e) for e in data if e.tag == media.Genre.TYPE]
|
||||||
|
@ -75,7 +78,6 @@ class Artist(Audio):
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Album(Audio):
|
class Album(Audio):
|
||||||
TYPE = 'album'
|
TYPE = 'album'
|
||||||
LISTTYPE = 'audio'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Audio._loadData(self, data)
|
Audio._loadData(self, data)
|
||||||
|
@ -115,7 +117,6 @@ class Album(Audio):
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Track(Audio, Playable):
|
class Track(Audio, Playable):
|
||||||
TYPE = 'track'
|
TYPE = 'track'
|
||||||
LISTTYPE = 'audio'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Audio._loadData(self, data)
|
Audio._loadData(self, data)
|
||||||
|
|
|
@ -11,11 +11,12 @@ from plexapi.exceptions import BadRequest, NotFound
|
||||||
class Library(object):
|
class Library(object):
|
||||||
|
|
||||||
def __init__(self, server, data):
|
def __init__(self, server, data):
|
||||||
self.server = server
|
|
||||||
self.identifier = data.attrib.get('identifier')
|
self.identifier = data.attrib.get('identifier')
|
||||||
self.mediaTagVersion = data.attrib.get('mediaTagVersion')
|
self.mediaTagVersion = data.attrib.get('mediaTagVersion')
|
||||||
|
self.server = server
|
||||||
self.title1 = data.attrib.get('title1')
|
self.title1 = data.attrib.get('title1')
|
||||||
self.title2 = data.attrib.get('title2')
|
self.title2 = data.attrib.get('title2')
|
||||||
|
self._sectionsByID = {} # cached section UUIDs
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Library:%s>' % self.title1.encode('utf8')
|
return '<Library:%s>' % self.title1.encode('utf8')
|
||||||
|
@ -33,7 +34,9 @@ class Library(object):
|
||||||
stype = elem.attrib['type']
|
stype = elem.attrib['type']
|
||||||
if stype in SECTION_TYPES:
|
if stype in SECTION_TYPES:
|
||||||
cls = SECTION_TYPES[stype]
|
cls = SECTION_TYPES[stype]
|
||||||
items.append(cls(self.server, elem, path))
|
section = cls(self.server, elem, path)
|
||||||
|
self._sectionsByID[section.key] = section
|
||||||
|
items.append(section)
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def section(self, title=None):
|
def section(self, title=None):
|
||||||
|
@ -42,6 +45,11 @@ class Library(object):
|
||||||
return item
|
return item
|
||||||
raise NotFound('Invalid library section: %s' % title)
|
raise NotFound('Invalid library section: %s' % title)
|
||||||
|
|
||||||
|
def sectionByID(self, sectionID):
|
||||||
|
if not self._sectionsByID:
|
||||||
|
self.sections()
|
||||||
|
return self._sectionsByID[sectionID]
|
||||||
|
|
||||||
def all(self):
|
def all(self):
|
||||||
return utils.listItems(self.server, '/library/all')
|
return utils.listItems(self.server, '/library/all')
|
||||||
|
|
||||||
|
@ -94,12 +102,23 @@ class LibrarySection(object):
|
||||||
def __init__(self, server, data, initpath):
|
def __init__(self, server, data, initpath):
|
||||||
self.server = server
|
self.server = server
|
||||||
self.initpath = initpath
|
self.initpath = initpath
|
||||||
self.type = data.attrib.get('type')
|
self.agent = data.attrib.get('agent')
|
||||||
|
self.allowSync = utils.cast(bool, data.attrib.get('allowSync'))
|
||||||
|
self.art = data.attrib.get('art')
|
||||||
|
self.composite = data.attrib.get('composite')
|
||||||
|
self.createdAt = utils.toDatetime(data.attrib.get('createdAt'))
|
||||||
|
self.filters = data.attrib.get('filters')
|
||||||
self.key = data.attrib.get('key')
|
self.key = data.attrib.get('key')
|
||||||
self.title = data.attrib.get('title')
|
|
||||||
self.scanner = data.attrib.get('scanner')
|
|
||||||
self.language = data.attrib.get('language')
|
self.language = data.attrib.get('language')
|
||||||
# TODO: Add Location
|
self.language = data.attrib.get('language')
|
||||||
|
self.locations = utils.findLocations(data)
|
||||||
|
self.refreshing = utils.cast(bool, data.attrib.get('refreshing'))
|
||||||
|
self.scanner = data.attrib.get('scanner')
|
||||||
|
self.thumb = data.attrib.get('thumb')
|
||||||
|
self.title = data.attrib.get('title')
|
||||||
|
self.type = data.attrib.get('type')
|
||||||
|
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
|
||||||
|
self.uuid = data.attrib.get('uuid')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
title = self.title.replace(' ','.')[0:20]
|
title = self.title.replace(' ','.')[0:20]
|
||||||
|
|
|
@ -10,12 +10,12 @@ NA = utils.NA
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Photoalbum(PlexPartialObject):
|
class Photoalbum(PlexPartialObject):
|
||||||
TYPE = 'photoalbum'
|
TYPE = 'photoalbum'
|
||||||
LISTTYPE = 'photo'
|
|
||||||
|
|
||||||
def __init__(self, server, data, initpath):
|
def __init__(self, server, data, initpath):
|
||||||
super(Photoalbum, self).__init__(data, initpath, server)
|
super(Photoalbum, self).__init__(data, initpath, server)
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
|
self.listType = 'photo'
|
||||||
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
||||||
self.art = data.attrib.get('art', NA)
|
self.art = data.attrib.get('art', NA)
|
||||||
self.composite = data.attrib.get('composite', NA)
|
self.composite = data.attrib.get('composite', NA)
|
||||||
|
@ -38,16 +38,19 @@ class Photoalbum(PlexPartialObject):
|
||||||
path = '/library/metadata/%s/children' % self.ratingKey
|
path = '/library/metadata/%s/children' % self.ratingKey
|
||||||
return utils.findItem(self.server, path, title)
|
return utils.findItem(self.server, path, title)
|
||||||
|
|
||||||
|
def section(self):
|
||||||
|
return self.server.library.sectionByID(self.librarySectionID)
|
||||||
|
|
||||||
|
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Photo(PlexPartialObject):
|
class Photo(PlexPartialObject):
|
||||||
TYPE = 'photo'
|
TYPE = 'photo'
|
||||||
LISTTYPE = 'photo'
|
|
||||||
|
|
||||||
def __init__(self, server, data, initpath):
|
def __init__(self, server, data, initpath):
|
||||||
super(Photo, self).__init__(data, initpath, server)
|
super(Photo, self).__init__(data, initpath, server)
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
|
self.listType = 'photo'
|
||||||
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
||||||
self.index = utils.cast(int, data.attrib.get('index', NA))
|
self.index = utils.cast(int, data.attrib.get('index', NA))
|
||||||
self.key = data.attrib.get('key', NA)
|
self.key = data.attrib.get('key', NA)
|
||||||
|
|
|
@ -40,58 +40,50 @@ class Playlist(PlexPartialObject, Playable):
|
||||||
return utils.listItems(self.server, path)
|
return utils.listItems(self.server, path)
|
||||||
|
|
||||||
def addItems(self, items):
|
def addItems(self, items):
|
||||||
# PUT /playlists/29988/items?uri=library%3A%2F%2F32268d7c-3e8c-4ab5-98ad-bad8a3b78c63%2Fitem%2F%252Flibrary%252Fmetadata%252F801
|
|
||||||
if not isinstance(items, (list, tuple)):
|
if not isinstance(items, (list, tuple)):
|
||||||
items = [items]
|
items = [items]
|
||||||
ratingKeys = []
|
ratingKeys = []
|
||||||
for item in items:
|
for item in items:
|
||||||
if item.__class__.LISTTYPE != self.playlistType:
|
if item.listType != self.playlistType:
|
||||||
raise BadRequest('Can not mix media types when building a playlist: %s and %s' % (self.playlistType, item.__class__.LISTTYPE))
|
raise BadRequest('Can not mix media types when building a playlist: %s and %s' % (self.playlistType, item.listType))
|
||||||
ratingKeys.append(item.ratingKey)
|
ratingKeys.append(item.ratingKey)
|
||||||
|
uuid = items[0].section().uuid
|
||||||
|
ratingKeys = ','.join(ratingKeys)
|
||||||
path = '%s/items%s' % (self.key, utils.joinArgs({
|
path = '%s/items%s' % (self.key, utils.joinArgs({
|
||||||
'uri': 'library://__GID__/directory//library/metadata/%s' % ','.join(ratingKeys),
|
'uri': 'library://%s/directory//library/metadata/%s' % (uuid, ratingKeys),
|
||||||
}))
|
}))
|
||||||
return self.server.query(path, method=self.server.session.put)
|
return self.server.query(path, method=self.server.session.put)
|
||||||
|
|
||||||
def removeItem(self, item):
|
def removeItem(self, item):
|
||||||
# DELETE /playlists/29988/items/4866
|
|
||||||
path = '%s/items/%s' % (self.key, item.playlistItemID)
|
path = '%s/items/%s' % (self.key, item.playlistItemID)
|
||||||
return self.server.query(path, method=self.server.session.delete)
|
return self.server.query(path, method=self.server.session.delete)
|
||||||
|
|
||||||
def moveItem(self, item, after=None):
|
def moveItem(self, item, after=None):
|
||||||
# PUT /playlists/29988/items/4556/move?after=4445
|
|
||||||
# PUT /playlists/29988/items/4556/move (to first item)
|
|
||||||
path = '%s/items/%s/move' % (self.key, item.playlistItemID)
|
path = '%s/items/%s/move' % (self.key, item.playlistItemID)
|
||||||
if after:
|
if after: path += '?after=%s' % after.playlistItemID
|
||||||
path += '?after=%s' % after.playlistItemID
|
|
||||||
return self.server.query(path, method=self.server.session.put)
|
return self.server.query(path, method=self.server.session.put)
|
||||||
|
|
||||||
def edit(self, title=None, summary=None):
|
def edit(self, title=None, summary=None):
|
||||||
# PUT /library/metadata/29988?title=You%20Look%20Like%20Gollum2&summary=foobar
|
|
||||||
path = '/library/metadata/%s%s' % (self.ratingKey, utils.joinArgs({'title':title, 'summary':summary}))
|
path = '/library/metadata/%s%s' % (self.ratingKey, utils.joinArgs({'title':title, 'summary':summary}))
|
||||||
return self.server.query(path, method=self.server.session.put)
|
return self.server.query(path, method=self.server.session.put)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
# DELETE /library/metadata/29988
|
|
||||||
return self.server.query(self.key, method=self.server.session.delete)
|
return self.server.query(self.key, method=self.server.session.delete)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, server, title, items):
|
def create(cls, server, title, items):
|
||||||
# NOTE: I have not yet figured out what __GID__ is below or where the proper value
|
|
||||||
# can be obtained. However, the good news is passing anything in seems to work.
|
|
||||||
if not isinstance(items, (list, tuple)):
|
if not isinstance(items, (list, tuple)):
|
||||||
items = [items]
|
items = [items]
|
||||||
# collect a list of itemkeys and make sure all items share the same listtype
|
|
||||||
listtype = items[0].__class__.LISTTYPE
|
|
||||||
ratingKeys = []
|
ratingKeys = []
|
||||||
for item in items:
|
for item in items:
|
||||||
if item.__class__.LISTTYPE != listtype:
|
if item.listType != items[0].listType:
|
||||||
raise BadRequest('Can not mix media types when building a playlist')
|
raise BadRequest('Can not mix media types when building a playlist')
|
||||||
ratingKeys.append(item.ratingKey)
|
ratingKeys.append(item.ratingKey)
|
||||||
# build and send the request
|
uuid = items[0].section().uuid
|
||||||
|
ratingKeys = ','.join(ratingKeys)
|
||||||
path = '/playlists%s' % utils.joinArgs({
|
path = '/playlists%s' % utils.joinArgs({
|
||||||
'uri': 'library://__GID__/directory//library/metadata/%s' % ','.join(ratingKeys),
|
'uri': 'library://%s/directory//library/metadata/%s' % (uuid, ratingKeys),
|
||||||
'type': listtype,
|
'type': items[0].listType,
|
||||||
'title': title,
|
'title': title,
|
||||||
'smart': 0
|
'smart': 0
|
||||||
})
|
})
|
||||||
|
|
|
@ -23,11 +23,9 @@ class PlayQueue(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, server, video, shuffle=0, continuous=0):
|
def create(cls, server, video, shuffle=0, continuous=0):
|
||||||
# TODO: Fix this up, create tests..
|
uuid = video.section().uuid
|
||||||
# NOTE: I have not yet figured out what __GID__ is below or where the proper value
|
|
||||||
# can be obtained. However, the good news is passing anything in seems to work.
|
|
||||||
path = '/playQueues%s' % utils.joinArgs({
|
path = '/playQueues%s' % utils.joinArgs({
|
||||||
'uri': 'library://__GID__/item/%s' % video.key,
|
'uri': 'library://%s/item/%s' % (uuid, video.key),
|
||||||
'key': video.key,
|
'key': video.key,
|
||||||
'type': 'video',
|
'type': 'video',
|
||||||
'shuffle': shuffle,
|
'shuffle': shuffle,
|
||||||
|
|
|
@ -37,6 +37,7 @@ class PlexServer(object):
|
||||||
self.transcoderActiveVideoSessions = int(data.attrib.get('transcoderActiveVideoSessions', 0))
|
self.transcoderActiveVideoSessions = int(data.attrib.get('transcoderActiveVideoSessions', 0))
|
||||||
self.updatedAt = int(data.attrib.get('updatedAt', 0))
|
self.updatedAt = int(data.attrib.get('updatedAt', 0))
|
||||||
self.version = data.attrib.get('version')
|
self.version = data.attrib.get('version')
|
||||||
|
self._library = None # cached library
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s:%s>' % (self.__class__.__name__, self.baseurl)
|
return '<%s:%s>' % (self.__class__.__name__, self.baseurl)
|
||||||
|
@ -50,7 +51,9 @@ class PlexServer(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def library(self):
|
def library(self):
|
||||||
return Library(self, self.query('/library/'))
|
if not self._library:
|
||||||
|
self._library = Library(self, self.query('/library/'))
|
||||||
|
return self._library
|
||||||
|
|
||||||
def account(self):
|
def account(self):
|
||||||
data = self.query('/myplex/account')
|
data = self.query('/myplex/account')
|
||||||
|
|
|
@ -163,11 +163,14 @@ def findItem(server, path, title):
|
||||||
raise NotFound('Unable to find item: %s' % title)
|
raise NotFound('Unable to find item: %s' % title)
|
||||||
|
|
||||||
|
|
||||||
def findLocation(data):
|
def findLocations(data, single=False):
|
||||||
elem = data.find('Location')
|
locations = []
|
||||||
if elem is not None:
|
for elem in data:
|
||||||
return elem.attrib.get('path')
|
if elem.tag == 'Location':
|
||||||
return None
|
locations.append(elem.attrib.get('path'))
|
||||||
|
if single:
|
||||||
|
return locations[0] if locations else None
|
||||||
|
return locations
|
||||||
|
|
||||||
|
|
||||||
def findPlayer(server, data):
|
def findPlayer(server, data):
|
||||||
|
|
|
@ -14,6 +14,7 @@ class Video(PlexPartialObject):
|
||||||
super(Video, self).__init__(data, initpath, server)
|
super(Video, self).__init__(data, initpath, server)
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
|
self.listType = 'video'
|
||||||
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
self.addedAt = utils.toDatetime(data.attrib.get('addedAt', NA))
|
||||||
self.key = data.attrib.get('key', NA)
|
self.key = data.attrib.get('key', NA)
|
||||||
self.lastViewedAt = utils.toDatetime(data.attrib.get('lastViewedAt', NA))
|
self.lastViewedAt = utils.toDatetime(data.attrib.get('lastViewedAt', NA))
|
||||||
|
@ -51,11 +52,13 @@ class Video(PlexPartialObject):
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.server.query('%s/refresh' % self.key, method=self.server.session.put)
|
self.server.query('%s/refresh' % self.key, method=self.server.session.put)
|
||||||
|
|
||||||
|
def section(self):
|
||||||
|
return self.server.library.sectionByID(self.librarySectionID)
|
||||||
|
|
||||||
|
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Movie(Video, Playable):
|
class Movie(Video, Playable):
|
||||||
TYPE = 'movie'
|
TYPE = 'movie'
|
||||||
LISTTYPE = 'video'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Video._loadData(self, data)
|
Video._loadData(self, data)
|
||||||
|
@ -102,7 +105,6 @@ class Movie(Video, Playable):
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Show(Video):
|
class Show(Video):
|
||||||
TYPE = 'show'
|
TYPE = 'show'
|
||||||
LISTTYPE = 'video'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Video._loadData(self, data)
|
Video._loadData(self, data)
|
||||||
|
@ -113,7 +115,7 @@ class Show(Video):
|
||||||
self.duration = utils.cast(int, data.attrib.get('duration', NA))
|
self.duration = utils.cast(int, data.attrib.get('duration', NA))
|
||||||
self.guid = data.attrib.get('guid', NA)
|
self.guid = data.attrib.get('guid', NA)
|
||||||
self.leafCount = utils.cast(int, data.attrib.get('leafCount', NA))
|
self.leafCount = utils.cast(int, data.attrib.get('leafCount', NA))
|
||||||
self.location = utils.findLocation(data)
|
self.location = utils.findLocations(data, single=True)
|
||||||
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt', NA), '%Y-%m-%d')
|
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt', NA), '%Y-%m-%d')
|
||||||
self.rating = utils.cast(float, data.attrib.get('rating', NA))
|
self.rating = utils.cast(float, data.attrib.get('rating', NA))
|
||||||
self.studio = data.attrib.get('studio', NA)
|
self.studio = data.attrib.get('studio', NA)
|
||||||
|
@ -164,7 +166,6 @@ class Show(Video):
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Season(Video):
|
class Season(Video):
|
||||||
TYPE = 'season'
|
TYPE = 'season'
|
||||||
LISTTYPE = 'video'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Video._loadData(self, data)
|
Video._loadData(self, data)
|
||||||
|
@ -201,7 +202,6 @@ class Season(Video):
|
||||||
@utils.register_libtype
|
@utils.register_libtype
|
||||||
class Episode(Video, Playable):
|
class Episode(Video, Playable):
|
||||||
TYPE = 'episode'
|
TYPE = 'episode'
|
||||||
LISTTYPE = 'video'
|
|
||||||
|
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
Video._loadData(self, data)
|
Video._loadData(self, data)
|
||||||
|
|
|
@ -284,12 +284,12 @@ def test_list_playlists(plex, account=None):
|
||||||
|
|
||||||
@register('playlist')
|
@register('playlist')
|
||||||
def test_create_playlist(plex, account=None):
|
def test_create_playlist(plex, account=None):
|
||||||
try:
|
|
||||||
# create the playlist
|
# create the playlist
|
||||||
title = 'test_create_playlist'
|
title = 'test_create_playlist'
|
||||||
log(2, 'Creating playlist %s..' % title)
|
log(2, 'Creating playlist %s..' % title)
|
||||||
episodes = plex.library.section(SHOW_SECTION).get(SHOW_TITLE).episodes()
|
episodes = plex.library.section(SHOW_SECTION).get(SHOW_TITLE).episodes()
|
||||||
playlist = plex.createPlaylist(title, episodes[:3])
|
playlist = plex.createPlaylist(title, episodes[:3])
|
||||||
|
try:
|
||||||
items = playlist.items()
|
items = playlist.items()
|
||||||
log(4, 'Title: %s' % playlist.title)
|
log(4, 'Title: %s' % playlist.title)
|
||||||
log(4, 'Items: %s' % items)
|
log(4, 'Items: %s' % items)
|
||||||
|
|
Loading…
Reference in a new issue