コード例 #1
0
ファイル: plexapp.py プロジェクト: Zero0Q/plex-for-kodi
    def shutdown(self):
        if self.timers:
            util.DEBUG_LOG('Waiting for {0} App() timers: Started'.format(len(self.timers)))

            self.cancelAllTimers()

            for timer in self.timers:
                timer.join()

            util.DEBUG_LOG('Waiting for App() timers: Finished')
コード例 #2
0
ファイル: discovery.py プロジェクト: ouelle/script.tablo
    def discover(self, device=None):
        import netif
        ifaces = netif.getInterfaces()
        sockets = []
        for i in ifaces:
            if not i.broadcast:
                continue
            # if i.ip.startswith('127.'): continue
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.settimeout(0.01)  # 10ms
            s.bind((i.ip, 0))
            s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            sockets.append((s, i))
        packet = struct.pack('>4s', 'BnGr')
        util.DEBUG_LOG('  o-> Broadcast Packet({0})'.format(
            binascii.hexlify(packet)))

        for attempt in (0, 1):
            for s, i in sockets:
                util.DEBUG_LOG('  o-> Broadcasting to {0}: {1}'.format(
                    i.name, i.broadcast))
                try:
                    s.sendto(packet, (i.broadcast, DEVICE_DISCOVERY_PORT))
                except:
                    util.ERROR()

            end = time.time() + 0.25  # 250ms

            # Create reply socket
            rs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            rs.settimeout(0.01)  # 10ms
            rs.bind(('', DEVICE_REPLY_PORT))
            rs.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

            while time.time() < end:
                try:
                    message, address = rs.recvfrom(8096)

                    added = self.add(message, address)

                    if added:
                        util.DEBUG_LOG('<-o   Response Packet({0})'.format(
                            binascii.hexlify(message)))
                    elif added is False:
                        util.DEBUG_LOG('<-o   Response Packet(Duplicate)')
                    elif added is None:
                        util.DEBUG_LOG('<-o   INVALID RESPONSE({0})'.format(
                            binascii.hexlify(message)))
                except socket.timeout:
                    pass
                except:
                    traceback.print_exc()

            for d in self.tablos:
                d.check()
コード例 #3
0
    def shutdown(self):
        self.abort()

        if self._task:
            self._task.cancel()

        if self._thread and self._thread.isAlive():
            util.DEBUG_LOG('BGThreader: thread ({0}): Waiting...'.format(
                self.name))
            self._thread.join()
            util.DEBUG_LOG('BGThreader: thread ({0}): Done'.format(self.name))
コード例 #4
0
ファイル: discovery.py プロジェクト: ouelle/script.tablo
 def reDiscover(self):
     self._discoveryTimestamp = time.time()
     self.tablos = []
     self.discover()
     if self.tablos:
         util.DEBUG_LOG('Device(s) found via local discovery')
     else:
         util.DEBUG_LOG(
             'No devices found via local discovery - trying association server'
         )
         self.associationServerDiscover()
コード例 #5
0
 def mergeServer(self, server):
     if server.uuid in self.serversByUuid:
         existing = self.serversByUuid[server.uuid]
         existing.merge(server)
         util.DEBUG_LOG("Merged {0}".format(repr(server.name)))
         return existing
     else:
         self.serversByUuid[server.uuid] = server
         util.DEBUG_LOG("Added new server {0}".format(repr(server.name)))
         self.trigger("new:server", server=server)
         return server
コード例 #6
0
    def _next(self):
        util.DEBUG_LOG('ImageQueue: Requesting next...')
        images = self._handler.next(self)
        if not images:
            util.DEBUG_LOG('ImageQueue: No next images')
            return None

        util.DEBUG_LOG('ImageQueue: {0} returned'.format(len(images)))
        self.queue += images
        self.pos += 1

        return self.current()
コード例 #7
0
    def __call__(self, caller, sItem):
        self.caller = caller
        util.DEBUG_LOG('[{0}] {1}'.format(sItem.typeChar, sItem.display()))
        playables = self.handlers[sItem.vtype](sItem)
        if playables:
            if sItem.vtype == 'dir':
                util.DEBUG_LOG('    - {0}'.format(' x {0}'.format(sItem.count)
                                                  or ''))
        else:
            util.DEBUG_LOG('    - {0}'.format('NOT SHOWING'))

        return playables
コード例 #8
0
    def _queueLoop(self):
        if self._queue.empty():
            return

        util.DEBUG_LOG('BGThreader: ({0}): Active'.format(self.name))
        try:
            while not self.aborted():
                self._task = self._queue.get_nowait()
                self._runTask(self._task)
                self._queue.task_done()
                self._task = None
        except Queue.Empty:
            util.DEBUG_LOG('BGThreader ({0}): Idle'.format(self.name))
コード例 #9
0
    def preShutdown(self):
        import http
        http.HttpRequest._cancel = True
        if self.pendingRequests:
            util.DEBUG_LOG('Closing down {0} App() requests'.format(
                len(self.pendingRequests)))
            for p in self.pendingRequests.values():
                if p:
                    p.request.cancel()

        if self.timers:
            util.DEBUG_LOG('Canceling App() timers')
            self.cancelAllTimers()
コード例 #10
0
ファイル: main.py プロジェクト: usermonk/plex-for-kodi
def waitForThreads():
    util.DEBUG_LOG('Main: Checking for any remaining threads')
    while len(threading.enumerate()) > 1:
        for t in threading.enumerate():
            if t != threading.currentThread():
                if t.isAlive():
                    util.DEBUG_LOG('Main: Waiting on: {0}...'.format(t.name))
                    if isinstance(t, threading._Timer):
                        t.cancel()
                        t.join()
                    elif isinstance(t, threadutils.KillableThread):
                        t.kill(force_and_wait=True)
                    else:
                        t.join()
コード例 #11
0
    def run(self):
        util.DEBUG_LOG('Timer {0}: {1}'.format(
            repr(self.function), self._reset and 'RESET' or 'STARTED'))
        while not self.event.isSet() and not self.shouldAbort():
            while not self.event.wait(self.timeout) and not self.shouldAbort():
                if self._reset:
                    self._reset = False
                    return

                self.function(*self.args, **self.kwargs)
                if not self.repeat:
                    return

        util.DEBUG_LOG('Timer {0}: FINISHED'.format(repr(self.function)))
コード例 #12
0
    def _queueLoop(self):
        util.DEBUG_LOG('Background queue: Active')
        try:
            while not self.aborted():
                self._task = self._queue.get_nowait()
                self._runTask(self._task)
                self._queue.task_done()
                self._task = None
        except Queue.Empty:
            util.DEBUG_LOG('Background queue: Empty')

        self._queue = Queue.LifoQueue()

        util.DEBUG_LOG('Background queue: Finished')
コード例 #13
0
    def defaultHandler(self, sItem):
        is3D = self.caller.nextQueuedFeature.is3D and sItem.play3D

        if sItem.random:
            util.DEBUG_LOG('    - Random')

            bumpers = [
                x for x in DB.VideoBumpers.select().where(
                    (DB.VideoBumpers.type == sItem.vtype)
                    & (DB.VideoBumpers.is3D == is3D))
            ]
            bumpers = random.sample(bumpers, min(sItem.count, len(bumpers)))
            bumpers = [
                Video(bumper.path,
                      volume=sItem.getLive('volume')).fromModule(sItem)
                for bumper in bumpers
            ]

            if not bumpers and is3D and util.getSettingDefault(
                    'bumper.fallback2D'):
                util.DEBUG_LOG('    - Falling back to 2D bumper')

                bumpers = [
                    x for x in DB.VideoBumpers.select().where((
                        DB.VideoBumpers.type == sItem.vtype))
                ]
                bumpers = random.sample(bumpers, min(sItem.count,
                                                     len(bumpers)))
                bumpers = [
                    Video(bumper.path,
                          volume=sItem.getLive('volume')).fromModule(sItem)
                    for bumper in bumpers
                ]

            if not bumpers:
                util.DEBUG_LOG('    - No matches!')

            return bumpers

        else:
            util.DEBUG_LOG('    - Via source')
            if sItem.source:
                return [
                    Video(sItem.source,
                          volume=sItem.getLive('volume')).fromModule(sItem)
                ]
            else:
                util.DEBUG_LOG('    - Empty path!')

        return []
コード例 #14
0
ファイル: main.py プロジェクト: camster1/RTOTV
    def updateGuide(self):
        newLinup = False

        if self.devices.isOld(): #1 hour
            if self.updateLineup(quiet=True):
                newLinup = True
            else:
                util.DEBUG_LOG('Discovery failed!')
                self.resetNextGuideUpdate(300) #Discovery failed, try again in 5 mins
                return False

        err = None
        guide = None
        try:
            guide = hdhr.guide.Guide(self.lineUp)
        except hdhr.errors.NoDeviceAuthException:
            err = util.T(32030)
        except hdhr.errors.NoGuideDataException:
            err = util.T(32031)
        except:
            err = util.ERROR()

        if err:
            if not self.guideFetchPreviouslyFailed: #Only show notification the first time. Don't need this every 5 mins if internet is down
                util.showNotification(err,header=util.T(32013))
                self.resetNextGuideUpdate(300) #Could not get guide data. Check again in 5 minutes
            self.guideFetchPreviouslyFailed = True
            self.setWinProperties()
            if self.lineUp.hasGuideData:
                util.DEBUG_LOG('Next guide update: {0} minutes'.format(int((self.nextGuideUpdate - time.time())/60)))
                return False

        guide = guide or hdhr.guide.Guide()

        self.guideFetchPreviouslyFailed = False

        #Set guide data for each channel
        for channel in self.lineUp.channels.values():
            guideChan = guide.getChannel(channel.number)
            channel.setGuide(guideChan)

        if newLinup:
            self.fillChannelList(update=True)

        self.lineUp.hasGuideData = True

        self.setWinProperties()
        util.DEBUG_LOG('Next guide update: {0} minutes'.format(int((self.nextGuideUpdate - time.time())/60)))
        return True
コード例 #15
0
ファイル: content.py プロジェクト: camster1/RTOTV
    def _addDirectory(self, current, tree):
        if not util.vfs.exists(current):
            util.DEBUG_LOG('Creating: {0}'.format(util.strRepr(current)))
            util.vfs.mkdirs(current)

        for branch in tree:
            if isinstance(branch, tuple):
                new = util.pathJoin(current, branch[0])
                self._addDirectory(new, branch[1])
            else:
                sub = util.pathJoin(current, branch)
                if util.vfs.exists(sub):
                    continue
                util.DEBUG_LOG('Creating: {0}'.format(util.strRepr(sub)))
                util.vfs.mkdirs(sub)
コード例 #16
0
    def onReachabilityResult(self, connection):
        connection.lastTestedAt = time.time()
        connection.hasPendingRequest = None
        self.pendingReachabilityRequests -= 1
        if connection.isSecure:
            self.pendingSecureRequests -= 1

        util.DEBUG_LOG("Reachability result for {0}: {1} is {2}".format(
            repr(self.name), connection.address, connection.state))

        # Noneate active connection if the state is unreachable
        if self.activeConnection and self.activeConnection.state != plexresource.ResourceConnection.STATE_REACHABLE:
            self.activeConnection = None

        # Pick a best connection. If we already had an active connection and
        # it's still reachable, stick with it. (replace with local if
        # available)
        best = self.activeConnection
        for i in range(len(self.connections) - 1, -1, -1):
            conn = self.connections[i]

            if not best or conn.getScore() > best.getScore():
                best = conn

        if best and best.state == best.STATE_REACHABLE:
            if best.isSecure or self.pendingSecureRequests <= 0:
                self.activeConnection = best
            else:
                util.DEBUG_LOG(
                    "Found a good connection for {0}, but holding out for better"
                    .format(repr(self.name)))

        if self.pendingReachabilityRequests <= 0:
            # Retest the server with fallback enabled. hasFallback will only
            # be True if there are available insecure connections and fallback
            # is allowed.

            if self.hasFallback:
                self.updateReachability(False, True)
            else:
                self.trigger("completed:reachability")

        util.LOG("Active connection for {0} is {1}".format(
            repr(self.name), self.activeConnection))

        import plexservermanager
        plexservermanager.MANAGER.updateReachabilityResult(
            self, bool(self.activeConnection))
コード例 #17
0
    def createBumpers(self,
                      basePath,
                      model,
                      type_name,
                      sub_name,
                      pct_start,
                      sub_default=''):
        paths = util.vfs.listdir(basePath)
        total = float(len(paths))

        for ct, sub in enumerate(paths):
            pct = pct_start + int((ct / total) * 20)
            if not self._callback(pct=pct):
                break

            path = util.pathJoin(basePath, sub)
            if not util.isDir(path):
                continue

            if sub.startswith('_Exclude'):
                util.DEBUG_LOG('SKIPPING EXCLUDED DIR: {0}'.format(
                    util.strRepr(sub)))
                continue

            if util.vfs.exists(util.pathJoin(path,
                                             'system.xml')):  # For ratings
                self.loadRatingSystem(util.pathJoin(path, 'system.xml'))

            type_ = sub.replace(' Bumpers', '')
            self.addBumper(model, sub, path, type_name, sub_name, type_,
                           sub_default)
コード例 #18
0
ファイル: myplexaccount.py プロジェクト: J0hnnyD03/Plex
    def switchHomeUser(self, userId, pin=''):
        if userId == self.ID and self.isAuthenticated:
            return True

        # Offline support
        if self.isOffline:
            hashed = 'NONE'
            if pin and self.authToken:
                hashed = hashlib.sha256(pin + self.authToken).digest()

            if not self.isProtected or self.isAuthenticated or hashed == (
                    self.pin or ""):
                util.DEBUG_LOG("OFFLINE access granted")
                self.isAuthenticated = True
                self.validateToken(self.authToken, True)
                return True
        else:
            # build path and post to myplex to swith the user
            path = '/api/home/users/{0}/switch'.format(userId)
            req = myplexrequest.MyPlexRequest(path)
            xml = req.postToStringWithTimeout({'pin': pin})
            data = ElementTree.fromstring(xml)

            if data.attrib.get('authenticationToken'):
                self.isAuthenticated = True
                # validate the token (trigger change:user) on user change or channel startup
                if userId != self.ID or not locks.LOCKS.isLocked("idleLock"):
                    self.validateToken(data.attrib.get('authenticationToken'),
                                       True)
                return True

        return False
コード例 #19
0
ファイル: myplexaccount.py プロジェクト: J0hnnyD03/Plex
    def updateHomeUsers(self):
        # Ignore request and clear any home users we are not signed in
        if not self.isSignedIn:
            self.homeUsers = []
            if self.isOffline:
                self.homeUsers.append(MyPlexAccount())

            self.lastHomeUserUpdate = None
            return

        # Cache home users for 60 seconds, mainly to stop back to back tests
        epoch = time.time()
        if not self.lastHomeUserUpdate:
            self.lastHomeUserUpdate = epoch
        elif self.lastHomeUserUpdate + 60 > epoch:
            util.DEBUG_LOG(
                "Skipping home user update (updated {0} seconds ago)".format(
                    epoch - self.lastHomeUserUpdate))
            return

        req = myplexrequest.MyPlexRequest("/api/home/users")
        xml = req.getToStringWithTimeout()
        data = ElementTree.fromstring(xml)
        if data.attrib.get('size') and data.find('User') is not None:
            self.homeUsers = []
            for user in data.findall('User'):
                homeUser = HomeUser(user.attrib)
                homeUser.isAdmin = homeUser.admin == "1"
                homeUser.isManaged = homeUser.restricted == "1"
                homeUser.isProtected = homeUser.protected == "1"
                self.homeUsers.append(homeUser)

            self.lastHomeUserUpdate = epoch

        util.LOG("home users: {0}".format(self.homeUsers))
コード例 #20
0
    def buildDirectPlay(self, obj, partIndex):
        util.DEBUG_LOG('buildDirectPlay()')
        part = self.media.parts[partIndex]

        server = self.item.getServer()

        # Check if we should include our token or not for this request
        obj.isRequestToServer = server.isRequestToServer(
            server.buildUrl(part.getAbsolutePath("key")))
        obj.streamUrls = [
            server.buildUrl(part.getAbsolutePath("key"), obj.isRequestToServer)
        ]
        obj.token = obj.isRequestToServer and server.getToken() or None
        if self.media.protocol == "hls":
            obj.streamFormat = "hls"
            obj.switchingStrategy = "full-adaptation"
            obj.live = self.isLiveHLS(obj.streamUrls[0],
                                      self.media.indirectHeaders)
        else:
            obj.streamFormat = self.media.get('container', 'mp4')
            if obj.streamFormat == "mov" or obj.streamFormat == "m4v":
                obj.streamFormat = "mp4"

        obj.streamBitrates = [self.media.bitrate.asInt()]
        obj.isTranscoded = False

        if self.choice.audioStream is not None:
            obj.audioLanguageSelected = self.choice.audioStream.languageCode

        return obj
コード例 #21
0
    def buildTranscodeHls(self, obj):
        util.DEBUG_LOG('buildTranscodeHls()')
        obj.streamFormat = "hls"
        obj.streamBitrates = [0]
        obj.switchingStrategy = "no-adaptation"
        obj.transcodeEndpoint = "/video/:/transcode/universal/start.m3u8"

        builder = http.HttpRequest(
            obj.transcodeServer.buildUrl(obj.transcodeEndpoint, True))
        builder.extras = []
        builder.addParam("protocol", "hls")

        if self.choice.subtitleDecision == self.choice.SUBTITLES_SOFT_ANY:
            builder.addParam("skipSubtitles", "1")
        else:  # elif self.choice.hasBurnedInSubtitles is True:  # Must burn transcoded because we can't set offset
            captionSize = captions.CAPTIONS.getBurnedSize()
            if captionSize is not None:
                builder.addParam("subtitleSize", captionSize)

        # Augment the server's profile for things that depend on the Roku's configuration.
        if self.item.settings.supportsAudioStream("ac3", 6):
            builder.extras.append(
                "append-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3)"
            )
            builder.extras.append(
                "add-direct-play-profile(type=videoProfile&container=matroska&videoCodec=*&audioCodec=ac3)"
            )

        return builder
コード例 #22
0
ファイル: content.py プロジェクト: camster1/RTOTV
    def log(self, msg):
        util.DEBUG_LOG(msg)

        if not self._callback:
            return

        self._callback(msg)
コード例 #23
0
def addItemToPlayQueue(item, addNext=False):
    # See if we have an active play queue for this self.dia type or if we need to
    # create one.

    if item.isMusicOrDirectoryItem():
        player = AudioPlayer()
    elif item.isVideoOrDirectoryItem():
        player = VideoPlayer()
    elif item.isPhotoOrDirectoryItem():
        player = PhotoPlayer()
    else:
        player = None

    if not player:
        util.ERROR_LOG("Don't know how to add item to play queue: " +
                       str(item))
        return None
    elif not player.allowAddToQueue():
        util.DEBUG_LOG("Not allowed to add to this player")
        return None

    if player.playQueue:
        playQueue = player.playQueue
        playQueue.addItem(item, addNext)
    else:
        options = PlayOptions()
        options.context = options.CONTEXT_SELF
        playQueue = createPlayQueueForItem(item, None, options)
        if playQueue:
            player.setPlayQueue(playQueue, False)

    return playQueue
コード例 #24
0
ファイル: plexapp.py プロジェクト: J0hnnyD03/Plex
    def preShutdown(self):
        import http
        http.HttpRequest._cancel = True
        if self.pendingRequests:
            util.DEBUG_LOG('Closing down {0} App() requests...'.format(len(self.pendingRequests)))
            for p in self.pendingRequests.values():
                if p:
                    p.request.cancel()

        if self.timers:
            util.DEBUG_LOG('Canceling App() timers...')
            self.cancelAllTimers()

        if SERVERMANAGER.selectedServer:
            util.DEBUG_LOG('Closing server...')
            SERVERMANAGER.selectedServer.close()
コード例 #25
0
    def onManualConnectionsResponse(self, request, response, context):
        if not response.isSuccess():
            return

        data = response.getBodyXml()
        if data is not None:
            serverAddress = context.serverAddress
            util.DEBUG_LOG(
                "Received manual connection response for {0}".format(
                    serverAddress))

            machineID = data.attrib.get('machineIdentifier')
            name = context.address
            if not name or not machineID:
                return

            # TODO(rob): Do we NOT want to consider manual connections local?
            conn = plexconnection.PlexConnection(
                plexresource.ResourceConnection.SOURCE_MANUAL, serverAddress,
                True, None)
            server = plexserver.createPlexServerForConnection(conn)
            server.uuid = machineID
            server.name = name
            server.sourceType = plexresource.ResourceConnection.SOURCE_MANUAL
            self.updateFromConnectionType(
                [server], plexresource.ResourceConnection.SOURCE_MANUAL)
コード例 #26
0
    def buildTranscodeMkv(self, obj):
        util.DEBUG_LOG('buildTranscodeMkv()')
        obj.streamFormat = "mkv"
        obj.streamBitrates = [0]
        obj.transcodeEndpoint = "/video/:/transcode/universal/start.mkv"

        builder = http.HttpRequest(obj.transcodeServer.buildUrl(obj.transcodeEndpoint, True))
        builder.extras = []
        # builder.addParam("protocol", "http")
        builder.addParam("copyts", "1")

        obj.subtitleUrl = None
        if True:  # if self.choice.subtitleDecision == self.choice.SUBTITLES_BURN:  # Must burn transcoded because we can't set offset
            builder.addParam("subtitles", "burn")
            captionSize = captions.CAPTIONS.getBurnedSize()
            if captionSize is not None:
                builder.addParam("subtitleSize", captionSize)

        else:
            # TODO(rob): can we safely assume the id will also be 3 (one based index).
            # If not, we will have to get tricky and select the subtitle stream after
            # video playback starts via roCaptionRenderer: GetSubtitleTracks() and
            # ChangeSubtitleTrack()

            obj.subtitleConfig = {'TrackName': "mkv/3"}

            # Allow text conversion of subtitles if we only burn image formats
            if self.item.settings.getPreference("burn_subtitles") == "image":
                builder.addParam("advancedSubtitles", "text")

            builder.addParam("subtitles", "auto")

        # Augment the server's profile for things that depend on the Roku's configuration.
        if self.item.settings.supportsSurroundSound():
            if self.choice.audioStream is not None:
                numChannels = self.choice.audioStream.channels.asInt(6)
            else:
                numChannels = 6

            for codec in ("ac3", "eac3", "dca"):
                if self.item.settings.supportsAudioStream(codec, numChannels):
                    builder.extras.append("append-transcode-target-audio-codec(type=videoProfile&context=streaming&audioCodec=" + codec + ")")
                    builder.extras.append("add-direct-play-profile(type=videoProfile&container=matroska&videoCodec=*&audioCodec=" + codec + ")")
                    if codec == "dca":
                        builder.extras.append(
                            "add-limitation(scope=videoAudioCodec&scopeName=dca&type=upperBound&name=audio.channels&value=6&isRequired=false)"
                        )

        # AAC sample rate cannot be less than 22050hz (HLS is capable).
        if self.choice.audioStream is not None and self.choice.audioStream.samplingRate.asInt(22050) < 22050:
            builder.extras.append("add-limitation(scope=videoAudioCodec&scopeName=aac&type=lowerBound&name=audio.samplingRate&value=22050&isRequired=false)")

        # HEVC and VP9 support!
        if self.item.settings.getGlobal("hevcSupport"):
            builder.extras.append("append-transcode-target-codec(type=videoProfile&context=streaming&videoCodec=hevc)")

        if self.item.settings.getGlobal("vp9Support"):
            builder.extras.append("append-transcode-target-codec(type=videoProfile&context=streaming&videoCodec=vp9)")

        return builder
コード例 #27
0
    def __call__(self, caller, sItem):
        duration = sItem.getLive('duration')

        util.DEBUG_LOG('[{0}] {1}m'.format(sItem.typeChar, duration))

        durationLimit = duration * 60
        queue = ImageQueue(self, sItem).fromModule(sItem)
        queue.transition = sItem.getLive('transition')
        queue.transitionDuration = sItem.getLive('transitionDuration')

        vqueue = VideoQueue(self, sItem).fromModule(sItem)

        for slides in self.getTriviaImages(sItem):
            if isinstance(slides, Video):
                vqueue.append(slides)
            else:
                queue += slides

            if queue.duration + vqueue.duration >= durationLimit:
                break

        ret = []

        if queue.duration:
            ret.append(queue)
            queue.maxDuration -= vqueue.duration
        if vqueue.duration:
            ret.append(vqueue)

        self.addMusic(sItem, queue)

        return ret
コード例 #28
0
ファイル: main.py プロジェクト: camster1/RTOTV
    def updateChannels(self):
        util.DEBUG_LOG('Updating channels')

        self.nextChannelUpdate = MAX_TIME_INT

        for mli in self.channelList:
            self.updateListItem(mli.dataSource['channel'],mli)
コード例 #29
0
ファイル: sequence.py プロジェクト: camster1/RTOTV
def getItemsFromString(dstring):
    try:
        data = json.loads(dstring)
        return [Item.fromDict(ddict) for ddict in data['items']]
    except ValueError:
        if dstring and dstring.startswith('{'):
            util.DEBUG_LOG(repr(dstring))
            util.ERROR()
        else:
            try:
                return getItemsFromXMLString(dstring)
            except:
                util.DEBUG_LOG(repr(dstring[:100]))
                util.ERROR()

    return None
コード例 #30
0
    def collectDataFromRoot(self, data):
        # Make sure we're processing data for our server, and not some other
        # server that happened to be at the same IP.
        if self.uuid != data.attrib.get('machineIdentifier'):
            util.LOG(
                "Got a reachability response, but from a different server")
            return False

        self.serverClass = data.attrib.get('serverClass')
        self.supportsAudioTranscoding = data.attrib.get(
            'transcoderAudio') == '1'
        self.supportsVideoTranscoding = data.attrib.get(
            'transcoderVideo') == '1' or data.attrib.get(
                'transcoderVideoQualities')
        self.supportsVideoRemuxOnly = data.attrib.get(
            'transcoderVideoRemuxOnly') == '1'
        self.supportsPhotoTranscoding = data.attrib.get(
            'transcoderPhoto') == '1' or (
                not data.attrib.get('transcoderPhoto') and not self.synced
                and not self.isSecondary())
        self.allowChannelAccess = data.attrib.get(
            'allowChannelAccess') == '1' or (
                not data.attrib.get('allowChannelAccess') and self.owned
                and not self.synced and not self.isSecondary())
        self.supportsScrobble = not self.isSecondary() or self.synced
        self.allowsMediaDeletion = not self.synced and self.owned and data.attrib.get(
            'allowMediaDeletion') == '1'
        self.multiuser = data.attrib.get('multiuser') == '1'
        self.name = data.attrib.get('friendlyName') or self.name
        self.platform = data.attrib.get('platform')

        # TODO(schuyler): Process transcoder qualities

        self.rawVersion = data.attrib.get('version')
        if self.rawVersion:
            self.versionNorm = util.normalizedVersion(self.rawVersion)

        features = {
            'mkvTranscode': '0.9.11.11',
            'themeTranscode': '0.9.14.0',
            'allPartsStreamSelection': '0.9.12.5',
            'claimServer': '0.9.14.2',
            'streamingBrain': '1.2.0'
        }

        for f, v in features.items():
            if verlib.suggest_normalized_version(v) <= self.versionNorm:
                self.features[f] = True

        appMinVer = plexapp.INTERFACE.getGlobal('minServerVersionArr',
                                                '0.0.0.0')
        self.isSupported = self.isSecondary(
        ) or verlib.suggest_normalized_version(appMinVer) <= self.versionNorm

        util.DEBUG_LOG(
            "Server information updated from reachability check: {0}".format(
                self))

        return True