2016-03-22 03:52:58 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from plexapi import utils
|
2016-04-11 03:49:23 +00:00
|
|
|
from plexapi.exceptions import BadRequest
|
2016-02-03 18:07:53 +00:00
|
|
|
from plexapi.utils import cast, toDatetime
|
2016-04-08 02:48:45 +00:00
|
|
|
from plexapi.utils import PlexPartialObject, Playable
|
2016-02-03 18:07:53 +00:00
|
|
|
|
|
|
|
|
2016-03-22 03:52:58 +00:00
|
|
|
@utils.register_libtype
|
2016-04-08 02:48:45 +00:00
|
|
|
class Playlist(PlexPartialObject, Playable):
|
2016-02-03 18:07:53 +00:00
|
|
|
TYPE = 'playlist'
|
|
|
|
|
2016-04-04 03:55:29 +00:00
|
|
|
def __init__(self, server, data, initpath):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Playlist stuff.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
server (Plexserver): The PMS server your connected to
|
|
|
|
data (Element): Element built from server.query
|
|
|
|
initpath (str): Relativ path fx /library/sections/1/all
|
|
|
|
|
|
|
|
"""
|
2016-04-04 03:55:29 +00:00
|
|
|
super(Playlist, self).__init__(data, initpath, server)
|
|
|
|
|
2016-02-03 18:07:53 +00:00
|
|
|
def _loadData(self, data):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Used to set the attributes
|
|
|
|
|
|
|
|
Args:
|
|
|
|
data (Element): Usually built from server.query
|
|
|
|
"""
|
2016-04-08 02:48:45 +00:00
|
|
|
Playable._loadData(self, data)
|
2017-02-04 17:43:50 +00:00
|
|
|
self.addedAt = toDatetime(data.attrib.get('addedAt'))
|
|
|
|
self.composite = data.attrib.get('composite') # url to thumbnail
|
|
|
|
self.duration = cast(int, data.attrib.get('duration'))
|
|
|
|
self.durationInSeconds = cast(int, data.attrib.get('durationInSeconds'))
|
|
|
|
self.guid = data.attrib.get('guid')
|
|
|
|
self.key = data.attrib.get('key')
|
2016-04-11 03:49:23 +00:00
|
|
|
self.key = self.key.replace('/items', '') if self.key else self.key # FIX_BUG_50
|
2017-02-04 17:43:50 +00:00
|
|
|
self.leafCount = cast(int, data.attrib.get('leafCount'))
|
|
|
|
self.playlistType = data.attrib.get('playlistType')
|
|
|
|
self.ratingKey = cast(int, data.attrib.get('ratingKey'))
|
|
|
|
self.smart = cast(bool, data.attrib.get('smart'))
|
|
|
|
self.summary = data.attrib.get('summary')
|
|
|
|
self.title = data.attrib.get('title')
|
|
|
|
self.type = data.attrib.get('type')
|
|
|
|
self.updatedAt = toDatetime(data.attrib.get('updatedAt'))
|
2016-02-03 18:07:53 +00:00
|
|
|
|
2016-03-22 03:52:58 +00:00
|
|
|
def items(self):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Return all items in the playlist."""
|
2016-03-22 03:52:58 +00:00
|
|
|
path = '%s/items' % self.key
|
|
|
|
return utils.listItems(self.server, path)
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
def addItems(self, items):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Add items to a playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
if not isinstance(items, (list, tuple)):
|
|
|
|
items = [items]
|
|
|
|
ratingKeys = []
|
|
|
|
for item in items:
|
2016-04-12 02:43:21 +00:00
|
|
|
if item.listType != self.playlistType:
|
|
|
|
raise BadRequest('Can not mix media types when building a playlist: %s and %s' % (self.playlistType, item.listType))
|
2017-01-09 14:21:54 +00:00
|
|
|
ratingKeys.append(str(item.ratingKey))
|
2016-04-12 02:43:21 +00:00
|
|
|
uuid = items[0].section().uuid
|
2017-02-02 14:09:34 +00:00
|
|
|
ratingKeys = ','.join(ratingKeys)
|
2016-04-11 03:49:23 +00:00
|
|
|
path = '%s/items%s' % (self.key, utils.joinArgs({
|
2016-04-12 02:43:21 +00:00
|
|
|
'uri': 'library://%s/directory//library/metadata/%s' % (uuid, ratingKeys),
|
2016-04-11 03:49:23 +00:00
|
|
|
}))
|
|
|
|
return self.server.query(path, method=self.server.session.put)
|
|
|
|
|
|
|
|
def removeItem(self, item):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Remove a file from a playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
path = '%s/items/%s' % (self.key, item.playlistItemID)
|
|
|
|
return self.server.query(path, method=self.server.session.delete)
|
|
|
|
|
|
|
|
def moveItem(self, item, after=None):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Move a to a new position in playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
path = '%s/items/%s/move' % (self.key, item.playlistItemID)
|
2017-01-02 21:06:40 +00:00
|
|
|
if after:
|
|
|
|
path += '?after=%s' % after.playlistItemID
|
2016-04-11 03:49:23 +00:00
|
|
|
return self.server.query(path, method=self.server.session.put)
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
def edit(self, title=None, summary=None):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Edit playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
path = '/library/metadata/%s%s' % (self.ratingKey, utils.joinArgs({'title':title, 'summary':summary}))
|
|
|
|
return self.server.query(path, method=self.server.session.put)
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
def delete(self):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Delete playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
return self.server.query(self.key, method=self.server.session.delete)
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
@classmethod
|
|
|
|
def create(cls, server, title, items):
|
2017-01-02 21:06:40 +00:00
|
|
|
"""Create a playlist."""
|
2016-04-11 03:49:23 +00:00
|
|
|
if not isinstance(items, (list, tuple)):
|
|
|
|
items = [items]
|
|
|
|
ratingKeys = []
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
for item in items:
|
2016-04-12 02:43:21 +00:00
|
|
|
if item.listType != items[0].listType:
|
2016-04-11 03:49:23 +00:00
|
|
|
raise BadRequest('Can not mix media types when building a playlist')
|
2016-12-21 13:17:28 +00:00
|
|
|
ratingKeys.append(str(item.ratingKey))
|
|
|
|
|
2016-04-12 02:43:21 +00:00
|
|
|
ratingKeys = ','.join(ratingKeys)
|
2016-04-13 03:52:47 +00:00
|
|
|
uuid = items[0].section().uuid
|
2016-04-11 03:49:23 +00:00
|
|
|
path = '/playlists%s' % utils.joinArgs({
|
2016-04-12 02:43:21 +00:00
|
|
|
'uri': 'library://%s/directory//library/metadata/%s' % (uuid, ratingKeys),
|
|
|
|
'type': items[0].listType,
|
2016-04-11 03:49:23 +00:00
|
|
|
'title': title,
|
|
|
|
'smart': 0
|
|
|
|
})
|
2016-12-21 13:17:28 +00:00
|
|
|
|
2016-04-11 03:49:23 +00:00
|
|
|
data = server.query(path, method=server.session.post)[0]
|
|
|
|
return cls(server, data, initpath=path)
|