def extend(self, start=None, size=None): path = self.key args = {} if size is not None: args['X-Plex-Container-Start'] = start args['X-Plex-Container-Size'] = size if args: path += util.joinArgs( args ) if '?' not in path else '&' + util.joinArgs(args).lstrip('?') items = plexobjects.listItems(self.server, path) self.offset = plexobjects.PlexValue(start) self.size = plexobjects.PlexValue(len(items)) self.more = plexobjects.PlexValue( (items[0].container.offset.asInt() + items[0].container.size.asInt() < items[0].container.totalSize.asInt()) and '1' or '') return items
def addItem(self, container, node): if node.attrib.get('type') in ('track', 'movie', 'episode', 'photo') and node.tag != 'PlayQueue': item = plexobjects.buildItem(self.server, node, self.address, container=self.container) else: item = plexobjects.PlexObject(node, server=self.container.server, container=self.container) # TODO(rob): handle channel settings. We should be able to utilize # the settings component with some modifications. if not item.isSettings(): self.items.append(item) else: # Decrement the size and total size if applicable if self.container.get("size"): self.container.size = plexobjects.PlexValue( str(self.container.size.asInt() - 1)) if self.container.get("totalSize"): self.container.totalSize = plexobjects.PlexValue( str(self.container.totalSize.asInt() - 1))
def __init__(self, server, contentType, options=None): signalsmixin.SignalsMixin.__init__(self) self.id = None self.selectedId = None self.version = -1 self.isShuffled = False self.isRepeat = False self.isRepeatOne = False self.isLocalPlayQueue = False self.isMixed = None self.totalSize = 0 self.windowSize = 0 self.forcedWindow = False self.container = None # Forced limitations self.allowShuffle = False self.allowSeek = True self.allowRepeat = False self.allowSkipPrev = False self.allowSkipNext = False self.allowAddToQueue = False self.refreshOnTimeline = False self.server = server self.type = contentType self._items = [] self.options = options or util.AttributeDict() self.usage = None self.refreshTimer = None self.canceled = False self.responded = False self.initialized = False self.composite = plexobjects.PlexValue('', parent=self) # Add a few default options for specific PQ types if self.type == "audio": self.options.includeRelated = True elif self.type == "photo": self.setRepeat(True)
def _setData(self, data): PlayableVideo._setData(self, data) if self.isFullObject(): self.directors = plexobjects.PlexItemList(data, media.Director, media.Director.TYPE, server=self.server) self.media = plexobjects.PlexMediaItemList(data, plexmedia.PlexMedia, media.Media.TYPE, initpath=self.initpath, server=self.server, media=self) self.writers = plexobjects.PlexItemList(data, media.Writer, media.Writer.TYPE, server=self.server) else: if data.find(media.Media.TYPE) is not None: self.media = plexobjects.PlexMediaItemList( data, plexmedia.PlexMedia, media.Media.TYPE, initpath=self.initpath, server=self.server, media=self) self._videoStreams = None self._audioStreams = None self._subtitleStreams = None # data for active sessions self.sessionKey = plexobjects.PlexValue( data.attrib.get('sessionKey', ''), self) self.user = self._findUser(data) self.player = self._findPlayer(data) self.transcodeSession = self._findTranscodeSession(data)
def __init__(self, *args, **kwargs): PlexStream.__init__(self, None, *args, **kwargs) self.id = plexobjects.PlexValue("0") self.streamType = plexobjects.PlexValue(str(self.TYPE_SUBTITLE))
def setSelected(self, selected): self.selected = plexobjects.PlexValue(selected and '1' or '0')
def _setData(self, data): for k, v in data.attrib.items(): setattr(self, k, plexobjects.PlexValue(v, self)) self.key = plexobjects.PlexValue(self.key.replace('/children', ''), self)
def _setData(self, data): PlayableVideo._setData(self, data) if self.isFullObject(): self.collections = plexobjects.PlexItemList(data, media.Collection, media.Collection.TYPE, server=self.server) self.countries = plexobjects.PlexItemList(data, media.Country, media.Country.TYPE, server=self.server) self.directors = plexobjects.PlexItemList(data, media.Director, media.Director.TYPE, server=self.server) self.genres = plexobjects.PlexItemList(data, media.Genre, media.Genre.TYPE, server=self.server) self.media = plexobjects.PlexMediaItemList(data, plexmedia.PlexMedia, media.Media.TYPE, initpath=self.initpath, server=self.server, media=self) self.producers = plexobjects.PlexItemList(data, media.Producer, media.Producer.TYPE, server=self.server) self.roles = plexobjects.PlexItemList(data, media.Role, media.Role.TYPE, server=self.server, container=self.container) self.writers = plexobjects.PlexItemList(data, media.Writer, media.Writer.TYPE, server=self.server) self.related = plexobjects.PlexItemList(data.find('Related'), plexlibrary.Hub, plexlibrary.Hub.TYPE, server=self.server, container=self) else: if data.find(media.Media.TYPE) is not None: self.media = plexobjects.PlexMediaItemList( data, plexmedia.PlexMedia, media.Media.TYPE, initpath=self.initpath, server=self.server, media=self) self._videoStreams = None self._audioStreams = None self._subtitleStreams = None # data for active sessions self.sessionKey = plexobjects.PlexValue( data.attrib.get('sessionKey', ''), self) self.user = self._findUser(data) self.player = self._findPlayer(data) self.transcodeSession = self._findTranscodeSession(data)
def onResponse(self, request, response, context): # Close any loading modal regardless of response status # Application().closeLoadingModal() util.DEBUG_LOG('playQueue: Received response') self.responded = True if response.parseResponse(): util.DEBUG_LOG('playQueue: {0} items'.format(len(response.items))) self.container = response.container # Handle an empty PQ if we have specified an pqEmptyCallable if self.options and self.options.pqEmptyCallable: callable = self.options.pqEmptyCallable del self.options["pqEmptyCallable"] if len(response.items) == 0: callable.call() return self.id = response.container.playQueueID.asInt() self.isShuffled = response.container.playQueueShuffled.asBool() self.totalSize = response.container.playQueueTotalCount.asInt() self.windowSize = len(response.items) self.version = response.container.playQueueVersion.asInt() itemsChanged = False if len(response.items) == len(self._items): for i in range(len(self._items)): if self._items[i] != response.items[i]: itemsChanged = True break else: itemsChanged = True if itemsChanged: self._items = response.items # Process any forced limitations self.allowSeek = response.container.allowSeek.asBool() self.allowShuffle = ( self.totalSize > 1 and response.container.allowShuffle.asBool() and not response.container.playQueueLastAddedItemID) self.allowRepeat = response.container.allowRepeat.asBool() self.allowSkipPrev = self.totalSize > 1 and response.container.allowSkipPrevious != "0" self.allowSkipNext = self.totalSize > 1 and response.container.allowSkipNext != "0" # Figure out the selected track index and offset. PMS tries to make some # of this easy, but it might not realize that we've advanced to a new # track, so we can't blindly trust it. On the other hand, it's possible # that PMS completely changed the PQ item IDs (e.g. upon shuffling), so # we might need to use its values. We iterate through the items and try # to find the item that we believe is selected, only settling for what # PMS says if we fail. playQueueOffset = None selectedId = None pmsSelectedId = response.container.playQueueSelectedItemID.asInt() self.deriveIsMixed() # lastItem = None # Not used for index in range(len(self._items)): item = self._items[index] if not playQueueOffset and item.playQueueItemID.asInt( ) == pmsSelectedId: playQueueOffset = response.container.playQueueSelectedItemOffset.asInt( ) - index + 1 # Update the index of everything we've already past, and handle # wrapping indexes (repeat). for i in range(index): pqIndex = playQueueOffset + i if pqIndex < 1: pqIndex = pqIndex + self.totalSize self._items[i].playQueueIndex = plexobjects.PlexValue( str(pqIndex), parent=self._items[i]) if playQueueOffset: pqIndex = playQueueOffset + index if pqIndex > self.totalSize: pqIndex = pqIndex - self.totalSize item.playQueueIndex = plexobjects.PlexValue(str(pqIndex), parent=item) # If we found the item that we believe is selected: we should # continue to treat it as selected. # TODO(schuyler): Should we be checking the metadata ID (rating key) # instead? I don't think it matters in practice, but it may be # more correct. if not selectedId and item.playQueueItemID.asInt( ) == self.selectedId: selectedId = self.selectedId if not selectedId: self.selectedId = pmsSelectedId # TODO(schuyler): Set repeat as soon as PMS starts returning it # Fix up the container for all our items response.container.address = "/playQueues/" + str(self.id) # Create usage limitations self.usage = UsageFactory.createUsage(self) self.initialized = True self.trigger("change") if itemsChanged: self.trigger("items.changed")
def get(self, name): return getattr(self, name, plexobjects.PlexValue('', parent=self))