def process(self, opcode, message):
     if opcode not in self.opcode_data:
         return False
     log.debug('Received the following message from Alexa:')
     log.debug(message)
     try:
         message = etree.fromstring(message)
     except Exception as ex:
         log.error('Error decoding message from Alexa: %s' % ex)
         return False
     try:
         if message.attrib['command'] == 'processRemoteControlCommand':
             message = message[0]
         else:
             log.error('Unknown Alexa message received')
             return False
     except:
         log.error('Could not parse Alexa message')
         return False
     process_command(message.attrib['path'][1:],
                     message.attrib,
                     queue=self.mgr.plexCompanion.queue)
     return True
 def process(self, opcode, message):
     if opcode not in self.opcode_data:
         return False
     log.debug('Received the following message from Alexa:')
     log.debug(message)
     try:
         message = etree.fromstring(message)
     except Exception as ex:
         log.error('Error decoding message from Alexa: %s' % ex)
         return False
     try:
         if message.attrib['command'] == 'processRemoteControlCommand':
             message = message[0]
         else:
             log.error('Unknown Alexa message received')
             return False
     except:
         log.error('Could not parse Alexa message')
         return False
     process_command(message.attrib['path'][1:],
                     message.attrib,
                     queue=self.mgr.plexCompanion.queue)
     return True
 def process(self, opcode, message):
     if opcode not in self.opcode_data:
         return
     log.debug('%s: Received the following message from Alexa:' %
               self.__class__.__name__)
     log.debug('%s: %s' % (self.__class__.__name__, message))
     try:
         message = etree.fromstring(message)
     except Exception as ex:
         log.error('%s: Error decoding message from Alexa: %s' %
                   (self.__class__.__name__, ex))
         return
     try:
         if message.attrib['command'] == 'processRemoteControlCommand':
             message = message[0]
         else:
             log.error('%s: Unknown Alexa message received' %
                       self.__class__.__name__)
             return
     except:
         log.error('%s: Could not parse Alexa message' %
                   self.__class__.__name__)
         return
     process_command(message.attrib['path'][1:], message.attrib)
Example #4
0
    def answer_request(self, sendData):
        self.serverlist = self.server.client.getServerList()
        subMgr = self.server.subscriptionManager
        js = self.server.jsonClass
        settings = self.server.settings

        try:
            request_path = self.path[1:]
            request_path = sub(r"\?.*", "", request_path)
            url = urlparse(self.path)
            paramarrays = parse_qs(url.query)
            params = {}
            for key in paramarrays:
                params[key] = paramarrays[key][0]
            log.debug("remote request_path: %s" % request_path)
            log.debug("params received from remote: %s" % params)
            subMgr.updateCommandID(self.headers.get(
                'X-Plex-Client-Identifier',
                self.client_address[0]),
                params.get('commandID', False))
            if request_path == "version":
                self.response(
                    "PlexKodiConnect Plex Companion: Running\nVersion: %s"
                    % settings['version'])
            elif request_path == "verify":
                self.response("XBMC JSON connection test:\n" +
                              js.jsonrpc("ping"))
            elif "resources" == request_path:
                resp = ('%s'
                        '<MediaContainer>'
                        '<Player'
                        ' title="%s"'
                        ' protocol="plex"'
                        ' protocolVersion="1"'
                        ' protocolCapabilities="timeline,playback,navigation,playqueues"'
                        ' machineIdentifier="%s"'
                        ' product="PlexKodiConnect"'
                        ' platform="%s"'
                        ' platformVersion="%s"'
                        ' deviceClass="pc"'
                        '/>'
                        '</MediaContainer>'
                        % (getXMLHeader(),
                           settings['client_name'],
                           settings['uuid'],
                           settings['platform'],
                           settings['plexbmc_version']))
                log.debug("crafted resources response: %s" % resp)
                self.response(resp, js.getPlexHeaders())
            elif "/subscribe" in request_path:
                self.response(getOKMsg(), js.getPlexHeaders())
                protocol = params.get('protocol', False)
                host = self.client_address[0]
                port = params.get('port', False)
                uuid = self.headers.get('X-Plex-Client-Identifier', "")
                commandID = params.get('commandID', 0)
                subMgr.addSubscriber(protocol,
                                     host,
                                     port,
                                     uuid,
                                     commandID)
            elif "/poll" in request_path:
                if params.get('wait', False) == '1':
                    sleep(950)
                commandID = params.get('commandID', 0)
                self.response(
                    sub(r"INSERTCOMMANDID",
                        str(commandID),
                        subMgr.msg(js.getPlayers())),
                    {
                        'X-Plex-Client-Identifier': settings['uuid'],
                        'Access-Control-Expose-Headers':
                            'X-Plex-Client-Identifier',
                        'Access-Control-Allow-Origin': '*',
                        'Content-Type': 'text/xml'
                    })
            elif "/unsubscribe" in request_path:
                self.response(getOKMsg(), js.getPlexHeaders())
                uuid = self.headers.get('X-Plex-Client-Identifier', False) \
                    or self.client_address[0]
                subMgr.removeSubscriber(uuid)
            else:
                # Throw it to companion.py
                process_command(request_path, params, self.server.queue)
                self.response(getOKMsg(), js.getPlexHeaders())
                subMgr.notify()
        except:
            log.error('Error encountered. Traceback:')
            import traceback
            log.error(traceback.print_exc())
Example #5
0
    def answer_request(self, send_data):
        self.serverlist = self.server.client.getServerList()
        sub_mgr = self.server.subscription_manager

        request_path = self.path[1:]
        request_path = sub(r"\?.*", "", request_path)
        url = urlparse(self.path)
        paramarrays = parse_qs(url.query)
        params = {}
        for key in paramarrays:
            params[key] = paramarrays[key][0]
        LOG.debug("remote request_path: %s", request_path)
        LOG.debug("params received from remote: %s", params)
        sub_mgr.update_command_id(
            self.headers.get('X-Plex-Client-Identifier',
                             self.client_address[0]), params.get('commandID'))
        if request_path == "version":
            self.response(
                "PlexKodiConnect Plex Companion: Running\nVersion: %s" %
                v.ADDON_VERSION)
        elif request_path == "verify":
            self.response("XBMC JSON connection test:\n" + js.ping())
        elif request_path == 'resources':
            self.response(
                RESOURCES_XML.format(
                    title=v.DEVICENAME,
                    machineIdentifier=v.PKC_MACHINE_IDENTIFIER),
                getXArgsDeviceInfo(include_token=False))
        elif request_path == 'player/timeline/poll':
            # Plex web does polling if connected to PKC via Companion
            # Only reply if there is indeed something playing
            # Otherwise, all clients seem to keep connection open
            if params.get('wait') == '1':
                MONITOR.waitForAbort(0.95)
            if self.client_address[0] not in CLIENT_DICT:
                CLIENT_DICT[self.client_address[0]] = []
            tracker = CLIENT_DICT[self.client_address[0]]
            tracker.append(self.client_address[1])
            while (not PLAYER.isPlaying() and not MONITOR.abortRequested()
                   and sub_mgr.stop_sent_to_web
                   and not (len(tracker) >= 4
                            and tracker[0] == self.client_address[1])):
                # Keep at most 3 connections open, then drop the first one
                # Doesn't need to be thread-save
                # Silly stuff really
                MONITOR.waitForAbort(1)
            # Let PKC know that we're releasing this connection
            tracker.pop(0)
            msg = sub_mgr.msg(
                js.get_players()).format(command_id=params.get('commandID', 0))
            if sub_mgr.isplaying:
                self.response(
                    msg, {
                        'X-Plex-Client-Identifier': v.PKC_MACHINE_IDENTIFIER,
                        'X-Plex-Protocol': '1.0',
                        'Access-Control-Allow-Origin': '*',
                        'Access-Control-Max-Age': '1209600',
                        'Access-Control-Expose-Headers':
                        'X-Plex-Client-Identifier',
                        'Content-Type': 'text/xml;charset=utf-8'
                    })
            elif not sub_mgr.stop_sent_to_web:
                sub_mgr.stop_sent_to_web = True
                LOG.debug('Signaling STOP to Plex Web')
                self.response(
                    msg, {
                        'X-Plex-Client-Identifier': v.PKC_MACHINE_IDENTIFIER,
                        'X-Plex-Protocol': '1.0',
                        'Access-Control-Allow-Origin': '*',
                        'Access-Control-Max-Age': '1209600',
                        'Access-Control-Expose-Headers':
                        'X-Plex-Client-Identifier',
                        'Content-Type': 'text/xml;charset=utf-8'
                    })
            else:
                # Fail connection with HTTP 500 error - has been open too long
                self.response(
                    'Need to close this connection on the PKC side', {
                        'X-Plex-Client-Identifier': v.PKC_MACHINE_IDENTIFIER,
                        'X-Plex-Protocol': '1.0',
                        'Access-Control-Allow-Origin': '*',
                        'Access-Control-Max-Age': '1209600',
                        'Access-Control-Expose-Headers':
                        'X-Plex-Client-Identifier',
                        'Content-Type': 'text/xml;charset=utf-8'
                    },
                    code=500)
        elif "/subscribe" in request_path:
            self.response(v.COMPANION_OK_MESSAGE,
                          getXArgsDeviceInfo(include_token=False))
            protocol = params.get('protocol')
            host = self.client_address[0]
            port = params.get('port')
            uuid = self.headers.get('X-Plex-Client-Identifier')
            command_id = params.get('commandID', 0)
            sub_mgr.add_subscriber(protocol, host, port, uuid, command_id)
        elif "/unsubscribe" in request_path:
            self.response(v.COMPANION_OK_MESSAGE,
                          getXArgsDeviceInfo(include_token=False))
            uuid = self.headers.get('X-Plex-Client-Identifier') \
                or self.client_address[0]
            sub_mgr.remove_subscriber(uuid)
        else:
            # Throw it to companion.py
            process_command(request_path, params)
            self.response('', getXArgsDeviceInfo(include_token=False))