def convert_reply(data): et = parse_xml(data['Result'], 'utf-8') et = et.getroot() items = dbus.Array([],signature='v') def append(item): i = dbus.Dictionary({},signature='sv') for k,v in item.attrib.items(): i[un_namespace(k)] = v res = dbus.Array([],signature='v') for child in item: if un_namespace(child.tag) == 'DIDL-Lite:res': res_dict = dbus.Dictionary({},signature='sv') res_dict['url'] = unicode(child.text) for k,v in child.attrib.items(): res_dict[un_namespace(k)] = v res.append(res_dict) else: i[un_namespace(child.tag)] = child.text if len(res): i['res'] = res items.append(i) for item in et: append(item) dbus_async_cb(items,int(data['NumberReturned']),int(data['TotalMatches']),int(data['UpdateID']))
def gotPage(x): self.debug("got device description from %r" % self.location) data, headers = x xml_data = None try: xml_data = utils.parse_xml(data, 'utf-8') except: self.warning("Invalid device description received from %r", self.location) import traceback self.debug(traceback.format_exc()) if xml_data is not None: tree = xml_data.getroot() major = tree.findtext('./{%s}specVersion/{%s}major' % (ns,ns)) minor = tree.findtext('./{%s}specVersion/{%s}minor' % (ns,ns)) try: self.upnp_version = '.'.join((major,minor)) except: self.upnp_version = 'n/a' try: self.urlbase = tree.findtext('./{%s}URLBase' % ns) except: import traceback self.debug(traceback.format_exc()) d = tree.find('./{%s}device' % ns) if d is not None: self.parse_device(d) # root device
def _cbGotResult(self, result): #print "_cbGotResult 1", result page, headers = result #result = SOAPpy.parseSOAPRPC(page) #print "_cbGotResult 2", result def print_c(e): for c in e.getchildren(): print c, c.tag print_c(c) self.debug("result: %r" % page) tree = parse_xml(page) #print tree, "find %s" % self.action #root = tree.getroot() #print_c(root) body = tree.find('{http://schemas.xmlsoap.org/soap/envelope/}Body') #print "body", body response = body.find('{%s}%sResponse' % (self.namespace[1], self.action)) if response == None: """ fallback for improper SOAP action responses """ response = body.find('%sResponse' % self.action) self.debug("callRemote response ", response) result = {} if response != None: for elem in response: result[elem.tag] = self.decode_result(elem) #print "_cbGotResult 3", result return result
def render_NOTIFY(self, request): self.info("EventServer received notify from %s, code: %d" % (request.client, request.code)) data = request.content.getvalue() request.setResponseCode(200) command = {'method': request.method, 'path': request.path} headers = request.received_headers louie.send('UPnP.Event.Server.message_received', None, command, headers, data) if request.code != 200: self.info("data:", data) else: self.debug("data:", data) headers = request.getAllHeaders() sid = headers['sid'] try: tree = utils.parse_xml(data).getroot() except (SyntaxError,AttributeError): self.warning("malformed event notification from %r", request.client) self.debug("data: %r", data) request.setResponseCode(400) return "" event = Event(sid,tree,raw=data) if len(event) != 0: self.control_point.propagate(event) return ""
def fromString(cls, aString): instance = cls() elt = utils.parse_xml(aString, 'utf-8') elt = elt.getroot() for node in elt.getchildren(): upnp_class_name = node.findtext('{%s}class' % 'urn:schemas-upnp-org:metadata-1-0/upnp/') upnp_class = instance.get_upnp_class(upnp_class_name.strip()) new_node = upnp_class.fromString(ET.tostring(node)) instance.addItem(new_node) return instance
def gotError(error, url): self.warning("error requesting url %r" % url) self.debug(error) try: tree = parse_xml(error.value.response) body = tree.find('{http://schemas.xmlsoap.org/soap/envelope/}Body') return failure.Failure(Exception("%s - %s" % (body.find('.//{urn:schemas-upnp-org:control-1-0}errorCode').text, body.find('.//{urn:schemas-upnp-org:control-1-0}errorDescription').text))) except: import traceback self.debug(traceback.format_exc()) return error
def process_event(self,event): self.info("process event %r %r" % (self,event)) for var_name, var_value in event.items(): if var_name == 'LastChange': self.info("we have a LastChange event") self.get_state_variable(var_name, 0).update(var_value) tree = utils.parse_xml(var_value, 'utf-8').getroot() namespace_uri, tag = tree.tag[1:].split( "}", 1) for instance in tree.findall('{%s}InstanceID' % namespace_uri): instance_id = instance.attrib['val'] self.info("instance_id %r %r" % (instance,instance_id)) for var in instance.getchildren(): self.info("var %r" % var) namespace_uri, tag = var.tag[1:].split("}", 1) self.info("%r %r %r" % (namespace_uri, tag,var.attrib['val'])) self.get_state_variable(tag, instance_id).update(var.attrib['val']) self.info("updated var %r" % var) if len(var.attrib) > 1: self.info("Extended StateVariable %s - %r", var.tag, var.attrib) if var.attrib.has_key('channel') and var.attrib['channel'] != 'Master': # TODO handle attributes that them selves have multiple instances self.info("Skipping update to %s its not for master channel %s", var.tag, var.attrib) pass else: if not self.get_state_variables(instance_id): # TODO Create instance ? self.error("%r update failed (not self.get_state_variables(instance_id)) %r", self, instance_id) elif not self.get_state_variables(instance_id).has_key(tag): # TODO Create instance StateVariable? # SONOS stuff self.error("%r update failed (not self.get_state_variables(instance_id).has_key(tag)) %r", self, tag) else: val = None if var.attrib.has_key('val'): val = var.attrib['val'] #self.debug("%r update %r %r %r", self,namespace_uri, tag, var.attrib['val']) self.get_state_variable(tag, instance_id).update(var.attrib['val']) self.debug("updated 'attributed' var %r", var) louie.send('Coherence.UPnP.DeviceClient.Service.Event.processed',None,self,(var_name,var_value,event.raw)) else: self.get_state_variable(var_name, 0).update(var_value) louie.send('Coherence.UPnP.DeviceClient.Service.Event.processed',None,self,(var_name,var_value,event.raw)) if self.last_time_updated == None: # The clients (e.g. media_server_client) check for last time to detect whether service detection is complete # so we need to set it here and now to avoid a potential race condition self.last_time_updated = time.time() louie.send('Coherence.UPnP.DeviceClient.Service.notified', sender=self.device, service=self) self.info("send signal Coherence.UPnP.DeviceClient.Service.notified for %r" % self) self.last_time_updated = time.time()
def gotPage(x): #print "gotPage" #print x self.scpdXML, headers = x tree = utils.parse_xml(self.scpdXML, 'utf-8').getroot() ns = "urn:schemas-upnp-org:service-1-0" for action_node in tree.findall('.//{%s}action' % ns): name = action_node.findtext('{%s}name' % ns) arguments = [] for argument in action_node.findall('.//{%s}argument' % ns): arg_name = argument.findtext('{%s}name' % ns) arg_direction = argument.findtext('{%s}direction' % ns) arg_state_var = argument.findtext('{%s}relatedStateVariable' % ns) arguments.append(action.Argument(arg_name, arg_direction, arg_state_var)) self._actions[name] = action.Action(self, name, 'n/a', arguments) for var_node in tree.findall('.//{%s}stateVariable' % ns): send_events = var_node.attrib.get('sendEvents','yes') name = var_node.findtext('{%s}name' % ns) data_type = var_node.findtext('{%s}dataType' % ns) values = [] """ we need to ignore this, as there we don't get there our {urn:schemas-beebits-net:service-1-0}X_withVendorDefines attibute there """ for allowed in var_node.findall('.//{%s}allowedValue' % ns): values.append(allowed.text) instance = 0 self._variables.get(instance)[name] = variable.StateVariable(self, name, 'n/a', instance, send_events, data_type, values) """ we need to do this here, as there we don't get there our {urn:schemas-beebits-net:service-1-0}X_withVendorDefines attibute there """ self._variables.get(instance)[name].has_vendor_values = True #print 'service parse:', self, self.device self.detection_completed = True louie.send('Coherence.UPnP.Service.detection_completed', sender=self.device, device=self.device) self.info("send signal Coherence.UPnP.Service.detection_completed for %r" % self) """
def init_var_and_actions(self): """ retrieve all actions and create the Action classes for our (proxy) server retrieve all variables and create the StateVariable classes for our (proxy) server """ xml = self.service.get_scpd_xml() tree = parse_xml(xml, 'utf-8').getroot() ns = "urn:schemas-upnp-org:service-1-0" for action_node in tree.findall('.//{%s}action' % ns): name = action_node.findtext('{%s}name' % ns) arguments = [] for argument in action_node.findall('.//{%s}argument' % ns): arg_name = argument.findtext('{%s}name' % ns) arg_direction = argument.findtext('{%s}direction' % ns) arg_state_var = argument.findtext('{%s}relatedStateVariable' % ns) arguments.append(action.Argument(arg_name, arg_direction, arg_state_var)) self._actions[name] = action.Action(self, name, 'n/a', arguments) for var_node in tree.findall('.//{%s}stateVariable' % ns): send_events = var_node.attrib.get('sendEvents','yes') name = var_node.findtext('{%s}name' % ns) data_type = var_node.findtext('{%s}dataType' % ns) values = [] """ we need to ignore this, as there we don't get there our {urn:schemas-beebits-net:service-1-0}X_withVendorDefines attibute there """ for allowed in var_node.findall('.//{%s}allowedValue' % ns): values.append(allowed.text) instance = 0 self._variables.get(instance)[name] = variable.StateVariable(self, name, 'n/a', instance, send_events, data_type, values) """ we need to do this here, as there we don't get there our {urn:schemas-beebits-net:service-1-0}X_withVendorDefines attibute there """ self._variables.get(instance)[name].has_vendor_values = True
def render(self, request): """Handle a SOAP command.""" data = request.content.read() headers = request.getAllHeaders() self.info('soap_request:', headers) # allow external check of data louie.send('UPnPTest.Control.Client.CommandReceived', None, headers, data) def print_c(e): for c in e.getchildren(): print c, c.tag print_c(c) tree = parse_xml(data) #root = tree.getroot() #print_c(root) body = tree.find('{http://schemas.xmlsoap.org/soap/envelope/}Body') method = body.getchildren()[0] methodName = method.tag ns = None if methodName.startswith('{') and methodName.rfind('}') > 1: ns, methodName = methodName[1:].split('}') args = [] kwargs = {} for child in method.getchildren(): kwargs[child.tag] = self.decode_result(child) args.append(kwargs[child.tag]) #p, header, body, attrs = SOAPpy.parseSOAPRPC(data, 1, 1, 1) #methodName, args, kwargs, ns = p._name, p._aslist, p._asdict, p._ns try: headers['content-type'].index('text/xml') except Exception, e: self._gotError(failure.Failure(errorCode(415)), request, methodName) return server.NOT_DONE_YET
def fromString(cls, data): instance = cls() elt = utils.parse_xml(data) #elt = ElementTree(elt) instance.fromElement(elt.getroot()) return instance