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)
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())
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))