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 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 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 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 render_NOTIFY(self, request): self.info("EventServer received notify from %s, code: %d" % (request.client, request.code)) data = request.content.getvalue() self.debug("EventServer notify data (%i) %s", len(data), data) 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: %s", data) else: headers = request.getAllHeaders() sid = headers['sid'] try: tree = utils.parse_xml(data).getroot() ns = "urn:schemas-upnp-org:event-1-0" event = Event(sid) for prop in tree.findall('{%s}property' % ns): for var in prop.getchildren(): tag = var.tag idx = tag.find('}') + 1 event.update({tag[idx:]: var.text}) self.control_point.propagate(event) except (SyntaxError,AttributeError): self.warning("malformed event notification from %s", request.client) self.exception("data: %s", data) return "" except Exception: self.exception("data: %s", data) return ""
def got_page(result): if self.retrieveGenreList_attemptCount == 0: self.info("Connection to ShoutCast service successful for genre listing") else: self.warning("Connection to ShoutCast service successful for genre listing after %d attempts." % self.retrieveGenreList_attemptCount) result = utils.parse_xml(result, encoding='utf-8') genres = {} main_synonym_genre = {} for main_genre, sub_genres in synonym_genres.items(): genres[main_genre] = sub_genres for genre in sub_genres: main_synonym_genre[genre] = main_genre for genre in result.findall('genre'): name = genre.get('name') if name not in main_synonym_genre: genres[name] = [name] main_synonym_genre[name] = name for main_genre, sub_genres in genres.items(): if not self.genre_parent_items.has_key(main_genre): genre_families["Misc"].append(main_genre) self.init_completed()
def got_page(result): result = utils.parse_xml(result, encoding='utf-8') self.getting_tracks = False print self.getting_tracks print "got Tracks" for track in result.findall('trackList/track'): data = {} def get_data(name): #print track.find(name).text.encode('utf-8') return track.find(name).text.encode('utf-8') #Fixme: This section needs some work print "adding Track" data['mimetype'] = 'audio/mpeg' data['name'] = get_data('creator') + " - " + get_data('title') data['title'] = get_data('title') data['artist'] = get_data('creator') data['creator'] = get_data('creator') data['album'] = get_data('album') data['duration'] = get_data('duration') #FIXME: Image is the wrong tag. data['image'] = get_data('image') data['url'] = track.find('location').text.encode('utf-8') item = self.parent.store.append(data, self.parent) self.tracks.append(item)
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 got_page(result): if self.retrieveGenreList_attemptCount == 0: self.info( "Connection to ShoutCast service successful for genre listing" ) else: self.warning( "Connection to ShoutCast service successful for genre listing after %d attempts." % self.retrieveGenreList_attemptCount) result = utils.parse_xml(result, encoding='utf-8') genres = {} main_synonym_genre = {} for main_genre, sub_genres in synonym_genres.items(): genres[main_genre] = sub_genres for genre in sub_genres: main_synonym_genre[genre] = main_genre for genre in result.findall('genre'): name = genre.get('name') if name not in main_synonym_genre: genres[name] = [name] main_synonym_genre[name] = name for main_genre, sub_genres in genres.items(): if not self.genre_parent_items.has_key(main_genre): genre_families["Misc"].append(main_genre) self.init_completed()
def got_page(result): if self.retrieveGenreList_attemptCount == 0: self.info('Connection to ShoutCast service ' + 'successful for genre listing') else: self.warning( f'Connection to ShoutCast service successful for genre ' + f'listing after {self.retrieveGenreList_attemptCount} ' + f'attempts.') result = utils.parse_xml(result, encoding='utf-8') genres = {} main_synonym_genre = {} for main_genre, sub_genres in list(synonym_genres.items()): genres[main_genre] = sub_genres for genre in sub_genres: main_synonym_genre[genre] = main_genre for genre in result.findall('genre'): name = genre.get('name') if name not in main_synonym_genre: genres[name] = [name] main_synonym_genre[name] = name for main_genre, sub_genres in list(genres.items()): if main_genre not in self.genre_parent_items: genre_families['Misc'].append(main_genre) self.init_completed()
def got_page(result): result = utils.parse_xml(result, encoding='utf-8') self.getting_tracks = False print(self.getting_tracks) print('got Tracks') for track in result.findall('trackList/track'): data = {} def get_data(name): # print track.find(name).text.encode('utf-8') return track.find(name).text.encode('utf-8') # Fixme: This section needs some work print('adding Track') data['mimetype'] = 'audio/mpeg' data['name'] = get_data('creator') + ' - ' + get_data('title') data['title'] = get_data('title') data['artist'] = get_data('creator') data['creator'] = get_data('creator') data['album'] = get_data('album') data['duration'] = get_data('duration') # FIXME: Image is the wrong tag. data['image'] = get_data('image') data['url'] = track.find('location').text.encode('utf-8') item = self.parent.store.append(data, self.parent) self.tracks.append(item)
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 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 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 got_page(result): if self.retrieveList_attemptCount == 0: self.info( 'Connection to ShoutCast service successful for TV listing' ) else: self.warning( f'Connection to ShoutCast service ' + f'successful for TV listing after ' + f'{self.retrieveList_attemptCount:d} attempts.' ) result = result[0] result = utils.parse_xml(result, encoding='utf-8') genres = [] stations = {} for stationResult in result.findall('station'): mimetype = VIDEO_MIMETYPE station_id = stationResult.get('id') bitrate = stationResult.get('br') rating = stationResult.get('rt') name = stationResult.get('name').encode('utf-8') genre = stationResult.get('genre') url = SHOUTCAST_TUNEIN_URL % (station_id) if genres.count(genre) == 0: genres.append(genre) sameStation = stations.get(name) if sameStation is None or bitrate > sameStation['bitrate']: station = { 'name': name, 'station_id': station_id, 'mimetype': mimetype, 'id': station_id, 'url': url, 'bitrate': bitrate, 'rating': rating, 'genre': genre, } stations[name] = station genreItems = {} for genre in genres: genreItem = self.appendGenre(genre, parent) genreItems[genre] = genreItem for station in list(stations.values()): genre = station.get('genre') parentItem = genreItems[genre] self.appendFeed( { 'name': station.get('name'), 'mimetype': station['mimetype'], 'id': station.get('station_id'), 'url': station.get('url'), }, parentItem, )
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 got_something(result): print "got_something", result result = parse_xml(result[0], encoding='utf-8') result = result.getroot() if(result.attrib['stat'] == 'ok' and result.find('photoid') != None): photoid = result.find('photoid').text return photoid else: error = result.find('err') return failure.Failure(Exception(error.attrib['msg']))
def gotError(failure, url): # failure.value should be an Error object self.error("error requesting %s %s %s [%s]", url, failure, failure.value.status, failure.value.response ) if int(failure.value.status) == 500: # generic error, do we have abody? # if so parse and return. tree = parse_xml(failure.value.response) self.log_dom(tree.getroot()) return failure
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.debug("process event %s" % self) for var_name, var_value in event.items(): if var_name == 'LastChange': self.debug("we have a LastChange event %s", var_value) 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.debug("instance_id %r %r" % (instance,instance_id)) for var in instance.getchildren(): self.debug("var %r" % var) namespace_uri, tag = var.tag[1:].split("}", 1) if len(var.attrib) > 1: self.debug("Extended StateVariable %s - %s", 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("Skiiping update to %s its not for master channel %s", var.tag, var.attrib) pass else: if self.get_state_variables(instance_id) is None: # TODO Create instance ? self.info("%r Create new service instance %r", self, instance_id) self.create_new_instance(instance_id) if not self.get_state_variables(instance_id).has_key(tag): # SONOS stuff, it returns attributes that are not listed in the # state description. The soap reply propogates the changes as state updates. nv = variable.StateVariable(self, tag, 'n/a', instance_id, True, "string", []) self.get_state_variables(instance_id)[tag] = nv self.info("%r Create new variable %r", self, tag) val = None if var.attrib.has_key('val'): val = var.attrib['val'] self.get_state_variable(tag, instance_id).update(val) self.info("updated var %r" % var) else: # what if not exist self.info("updated var %s - %s ", var_name, var_value) self.get_state_variable(var_name, 0).update(var_value) self.debug("process event complete %s" % self) if self.last_time_updated == None: self.last_time_updated = time.time() # needs to be set before louie call. 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 self.scpdXML = self.scpdXML.replace('diretion', 'direction') parsed = utils.parse_xml(self.scpdXML, 'utf-8') if not parsed: return tree = parsed.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 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 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) if len(var_value) == 0: continue 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 got_page(result): result = utils.parse_xml(result, encoding='utf-8') for genre in result.findall('genre'): self.append( { 'name': genre.get('name').encode('utf-8'), 'mimetype': 'directory', 'url': '%s?genre=%s' % (self.config.get( 'genrelist', 'http://www.shoutcast.com/sbin/newxml.phtml'), genre.get('name')) }, parent)
def got_page(result): if self.retrieveList_attemptCount == 0: self.info("Connection to ShoutCast service successful for TV listing") else: self.warning("Connection to ShoutCast service successful for TV listing after %d attempts." % self.retrieveList_attemptCount) result = result[0] result = utils.parse_xml(result, encoding='utf-8') genres = [] stations = {} for stationResult in result.findall('station'): mimetype = VIDEO_MIMETYPE station_id = stationResult.get('id') bitrate = stationResult.get('br') rating = stationResult.get('rt') name = stationResult.get('name').encode('utf-8') genre = stationResult.get('genre') url = SHOUTCAST_TUNEIN_URL % (station_id) if genres.count(genre) == 0: genres.append(genre) sameStation = stations.get(name) if sameStation == None or bitrate>sameStation['bitrate']: station = {'name':name, 'station_id':station_id, 'mimetype':mimetype, 'id':station_id, 'url':url, 'bitrate':bitrate, 'rating':rating, 'genre':genre } stations[name] = station genreItems = {} for genre in genres: genreItem = self.appendGenre(genre, parent) genreItems[genre] = genreItem for station in stations.values(): genre = station.get('genre') parentItem = genreItems[genre] self.appendFeed({'name':station.get('name'), 'mimetype':station['mimetype'], 'id':station.get('station_id'), 'url':station.get('url')}, parentItem)
def got_page(result): result = utils.parse_xml(result, encoding='utf-8') tunein = result.find('tunein') if tunein != None: tunein = tunein.get('base', '/sbin/tunein-station.pls') prot, host_port, path, _, _ = urlsplit( self.store.config.get( 'genrelist', 'http://www.shoutcast.com/sbin/newxml.phtml')) tunein = prot + '://' + host_port + tunein def append_new(result, s): result = result[0].split('\n') for line in result: if line.startswith('File1='): s['url'] = line[6:] self.store.append(s, self) break l = [] for station in result.findall('station'): if station.get('mt') == 'audio/mpeg': d2 = utils.getPage('%s?id=%s' % (tunein, station.get('id')), timeout=20) d2.addCallback( append_new, { 'name': station.get('name').encode('utf-8'), 'mimetype': station.get('mt'), 'id': station.get('id'), 'url': None }) d2.addErrback(got_error) l.append(d2) dl = defer.DeferredList(l) def process_items(result): self.info("process_item", result, self.children) if self.children == None: return [] if request_count == 0: return self.children[start:] else: return self.children[start:request_count] dl.addCallback(process_items) return dl
def got_page(result): self.info(f'connection to ShoutCast service ' f'successful for genre: {genre}') result = utils.parse_xml(result, encoding='utf-8') tunein = result.find('tunein') if tunein is not None: tunein = tunein.get('base', '/sbin/tunein-station.pls') prot, host_port, path, _, _ = urlsplit(url_genre) tunein = SC_TUNEIN_URL + tunein stations = {} for stationResult in result.findall('station'): mimetype = stationResult.get('mt') station_id = stationResult.get('id') bitrate = stationResult.get('br') name = stationResult.get('name') # remove useless substrings (eg. '[Shoutcast.com]' ) from title for substring in useless_title_content: name = name.replace(substring, '') lower_name = name.lower() url = f'{tunein}?id={stationResult.get("id")}' sameStation = stations.get(lower_name) if sameStation is None or bitrate > sameStation['bitrate']: station = { 'name': name, 'station_id': station_id, 'mimetype': mimetype, 'id': station_id, 'url': url, 'bitrate': bitrate, } stations[lower_name] = station for station in list(stations.values()): item = IRadioItem( int(parent.get_id()), int(station.get('station_id')), '/', title=station.get('name'), url=utils.to_bytes(station.get('url')), mimetype=station.get('mimetype'), is_proxy=True, ) parent.add_child(item, external_id=station_id) return True
def got_page(result): self.info( 'connection to ShoutCast service successful for genre %s' % genre) result = utils.parse_xml(result, encoding='utf-8') tunein = result.find('tunein') if tunein != None: tunein = tunein.get('base', '/sbin/tunein-station.pls') prot, host_port, path, _, _ = urlsplit(self.shoutcast_ws_url) tunein = prot + '://' + host_port + tunein stations = {} for stationResult in result.findall('station'): mimetype = stationResult.get('mt') station_id = stationResult.get('id') bitrate = stationResult.get('br') name = stationResult.get('name').encode('utf-8') # remove useless substrings (eg. '[Shoutcast.com]' ) from title for substring in useless_title_content: name = name.replace(substring, "") lower_name = name.lower() url = '%s?id=%s' % (tunein, stationResult.get('id')) sameStation = stations.get(lower_name) if sameStation == None or bitrate > sameStation['bitrate']: station = { 'name': name, 'station_id': station_id, 'mimetype': mimetype, 'id': station_id, 'url': url, 'bitrate': bitrate } stations[lower_name] = station for station in stations.values(): station_id = station.get('station_id') name = station.get('name') url = station.get('url') mimetype = station.get('mimetype') item = IRadioItem(station_id, name, url, mimetype) parent.add_child(item, external_id=station_id) return True
def render_NOTIFY(self, request): self.info("EventServer received notify from %s, code: %d" % (request.client, request.code)) data = request.content.getvalue() self.debug("EventServer notify data (%i) %s", len(data), data) 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: %s", data) else: headers = request.getAllHeaders() sid = headers["sid"] try: tree = utils.parse_xml(data).getroot() ns = "urn:schemas-upnp-org:event-1-0" event = Event(sid) for prop in tree.findall("{%s}property" % ns): for var in prop.getchildren(): tag = var.tag idx = tag.find("}") + 1 self.debug("EventServer Event %s %s", var, ET.tostring(var)) if var.text is not None: event.update({tag[idx:]: var.text}) else: # this is solwise DMP1120w not escaping LastChange txt = ET.tostring(var)[12:-13] self.debug("EventServer Event %s", txt) event.update({tag[idx:]: txt}) self.control_point.propagate(event) except (SyntaxError, AttributeError): self.warning("malformed event notification from %r", request.client) self.exception("data: %r", data) return "" except Exception: self.exception("data: %r", data) return ""
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 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 process_event(self,event): self.info("process event %r" % self) 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) if len(var.attrib) > 1: self.info("Extended StateVariable %s - %s", 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("Skiiping 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 var %r", var) else: self.get_state_variable(var_name, 0).update(var_value) if self.last_time_updated == None: 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): self.debug("got device description from %r" % self.location) data, headers = x tree = utils.parse_xml(data, 'utf-8').getroot() # This is the base for all relative URLs self.url_base = tree.findtext('./{%s}URLBase' % ns) if self.url_base is None or len(self.url_base) == 0: # not given in description so use location # TODO should we parse out only protocol and host or use as is # I think the url_base could contain part of a path as well. parsed = urlparse(self.location) # ensure has trailing slash self.url_base = "%s://%s/" % (parsed[0], parsed[1]) self.debug("url_base %r" % self.url_base) d = tree.find('.//{%s}device' % ns) if d is not None: self.parse_device(d) # root device
def _cbGotResult(self, result): page, headers = result self.debug( "_cbGotResult %s [%s]", headers, page ) tree = parse_xml(page) self.log_dom(tree.getroot()) 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 %s", response) result = {} if response != None: for elem in response: result[elem.tag] = self.decode_result(elem) self.debug( "result %s", result ) return result
def got_page(result): self.info('connection to ShoutCast service successful for genre %s' % genre) result = utils.parse_xml(result, encoding='utf-8') tunein = result.find('tunein') if tunein != None: tunein = tunein.get('base','/sbin/tunein-station.pls') prot,host_port,path,_,_ = urlsplit(self.shoutcast_ws_url) tunein = prot + '://' + host_port + tunein stations = {} for stationResult in result.findall('station'): mimetype = stationResult.get('mt') station_id = stationResult.get('id') bitrate = stationResult.get('br') name = stationResult.get('name').encode('utf-8') # remove useless substrings (eg. '[Shoutcast.com]' ) from title for substring in useless_title_content: name = name.replace(substring, "") lower_name = name.lower() url = '%s?id=%s' % (tunein, stationResult.get('id')) sameStation = stations.get(lower_name) if sameStation == None or bitrate>sameStation['bitrate']: station = {'name':name, 'station_id':station_id, 'mimetype':mimetype, 'id':station_id, 'url':url, 'bitrate':bitrate } stations[lower_name] = station for station in stations.values(): station_id = station.get('station_id') name = station.get('name') url = station.get('url') mimetype = station.get('mimetype') item = IRadioItem(station_id, name, url, mimetype) parent.add_child(item, external_id = station_id) return True
def got_page(result): result = utils.parse_xml(result, encoding='utf-8') tunein = result.find('tunein') if tunein != None: tunein = tunein.get('base','/sbin/tunein-station.pls') prot,host_port,path,_,_ = urlsplit(self.store.config.get('genrelist','http://www.shoutcast.com/sbin/newxml.phtml')) tunein = prot + '://' + host_port + tunein def append_new(result, s): result = result[0].split('\n') for line in result: if line.startswith('File1='): s['url'] = line[6:] self.store.append(s,self) break l = [] for station in result.findall('station'): if station.get('mt') == 'audio/mpeg': d2 = utils.getPage('%s?id=%s' % (tunein, station.get('id')), timeout=20) d2.addCallback(append_new, {'name':station.get('name').encode('utf-8'), 'mimetype':station.get('mt'), 'id':station.get('id'), 'url':None}) d2.addErrback(got_error) l.append(d2) dl = defer.DeferredList(l) def process_items(result): print "process_item", result, self.children if self.children == None: return [] if request_count == 0: return self.children[start:] else: return self.children[start:request_count] dl.addCallback(process_items) return dl
def fromString(cls, data): instance = cls() elt = utils.parse_xml(data) #elt = ElementTree(elt) instance.fromElement(elt.getroot()) return instance
def __init__(self, server, *args, **kwargs): print "TestStore kwargs", kwargs BackendStore.__init__(self,server,**kwargs) self.name = kwargs.get('name', 'TestServer') self.next_id = 1000 self.update_id = 0 self.store = {} self.store[ROOT_CONTAINER_ID] = \ Container(ROOT_CONTAINER_ID,self,-1, self.name) items = kwargs.get('item', []) if not isinstance( items, list): items = [items] for item in items: if isinstance(item,basestring): xml = parse_xml(item) print xml.getroot() item = {} for child in xml.getroot(): item[child.tag] = child.text type = item.get('type','file') try: name = item.get('name',None) if type == 'file': location = FilePath(item.get('location')) if type == 'url': location = item.get('location') mimetype = item.get('mimetype') item_id = self.get_next_id() if type in ('file','url'): new_item = Item(self.store[ROOT_CONTAINER_ID], item_id, name, location,self.urlbase + str(item_id)) elif type == 'gstreamer': pipeline = item.get('pipeline') try: pipeline = GStreamerPipeline(pipeline,mimetype) new_item = ResourceItem(self.store[ROOT_CONTAINER_ID], item_id, name, pipeline,self.urlbase + str(item_id)) except NameError: self.warning("Can't enable GStreamerPipeline, probably pygst not installed") continue elif type == 'process': pipeline = item.get('command') pipeline = ExternalProcessPipeline(pipeline,mimetype) new_item = ResourceItem(self.store[ROOT_CONTAINER_ID], item_id, name, pipeline,self.urlbase + str(item_id)) try: new_item.upnp_class = self.get_upnp_class(item.get('upnp_class','object.item')) except: pass #item.description = u'some text what's the file about' #item.date = something #item.size = something new_item.mimetype = mimetype new_item.fourth_field = item.get('fourth_field','*') self.store[ROOT_CONTAINER_ID].add_child(new_item) self.store[item_id] = new_item except: import traceback self.warning(traceback.format_exc()) self.init_completed()
def __init__(self, server, *args, **kwargs): print "TestStore kwargs", kwargs BackendStore.__init__(self, server, **kwargs) self.name = kwargs.get('name', 'TestServer') self.next_id = 1000 self.update_id = 0 self.store = {} self.store[ROOT_CONTAINER_ID] = \ Container(ROOT_CONTAINER_ID,self,-1, self.name) items = kwargs.get('item', []) if not isinstance(items, list): items = [items] for item in items: if isinstance(item, basestring): xml = parse_xml(item) print xml.getroot() item = {} for child in xml.getroot(): item[child.tag] = child.text type = item.get('type', 'file') try: name = item.get('title', None) if type == 'file': location = FilePath(item.get('location')) if type == 'url': location = item.get('location') mimetype = item.get('mimetype') item_id = self.get_next_id() extension = item.get('extension') if extension == None: extension = '' if len(extension) and extension[0] != '.': extension = '.' + extension if extension != None: item_id = str(item_id) + extension if type in ('file', 'url'): new_item = Item(self.store[ROOT_CONTAINER_ID], item_id, name, location, self.urlbase + str(item_id)) elif type == 'gstreamer': pipeline = item.get('pipeline') try: pipeline = GStreamerPipeline(pipeline, mimetype) new_item = ResourceItem(self.store[ROOT_CONTAINER_ID], item_id, name, pipeline, self.urlbase + str(item_id)) except NameError: self.warning( "Can't enable GStreamerPipeline, probably pygst not installed" ) continue elif type == 'process': pipeline = item.get('command') pipeline = ExternalProcessPipeline(pipeline, mimetype) new_item = ResourceItem(self.store[ROOT_CONTAINER_ID], item_id, name, pipeline, self.urlbase + str(item_id)) try: new_item.upnp_class = self.get_upnp_class( item.get('upnp_class', 'object.item')) except: pass #item.description = u'some text what's the file about' #item.date = something #item.size = something new_item.mimetype = mimetype new_item.fourth_field = item.get('fourth_field', '*') self.store[ROOT_CONTAINER_ID].add_child(new_item) self.store[item_id] = new_item except: import traceback self.warning(traceback.format_exc()) #print self.store self.init_completed()
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) if len(var_value) == 0: continue 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 reply(r): #print "browse_reply - %s of %s returned" % (r['NumberReturned'],r['TotalMatches']) from coherence.upnp.core import DIDLLite from coherence.extern.et import ET child = self.store.iter_children(iter) if child: upnp_class, = self.store.get(child, UPNP_CLASS_COLUMN) if upnp_class == 'placeholder': self.store.remove(child) title, = self.store.get(iter, NAME_COLUMN) try: title = title[:title.rindex('(')] self.store.set_value( iter, NAME_COLUMN, "%s(%d)" % (title, int(r['TotalMatches']))) except ValueError: pass elt = parse_xml(r['Result'], 'utf-8') elt = elt.getroot() for child in elt: #stored_didl_string = DIDLLite.element_to_didl(child) stored_didl_string = DIDLLite.element_to_didl( ET.tostring(child)) didl = DIDLLite.DIDLElement.fromString(stored_didl_string) item = didl.getItems()[0] #print item.title, item.id, item.upnp_class if item.upnp_class.startswith('object.container'): icon = self.folder_icon service, = self.store.get(iter, SERVICE_COLUMN) child_count = item.childCount try: title = "%s (%d)" % (item.title, item.childCount) except TypeError: title = "%s (n/a)" % item.title child_count = -1 else: icon = None service = '' child_count = -1 title = item.title if item.upnp_class.startswith('object.item.audioItem'): icon = self.audio_icon elif item.upnp_class.startswith('object.item.videoItem'): icon = self.video_icon elif item.upnp_class.startswith('object.item.imageItem'): icon = self.image_icon res = item.res.get_matching(['*:*:*:*'], protocol_type='http-get') if len(res) > 0: res = res[0] service = res.data new_iter = self.store.append( iter, (title, item.id, item.upnp_class, child_count, '', service, icon, stored_didl_string, None)) if item.upnp_class.startswith('object.container'): self.store.append(new_iter, ('...loading...', '', 'placeholder', -1, '', '', None, '', None)) if ((int(r['TotalMatches']) > 0 and force == False) or expand == True): view.expand_row(row_path, False) if (requested_count != int(r['NumberReturned']) and int(r['NumberReturned']) < (int(r['TotalMatches']) - starting_index)): print "seems we have been returned only a part of the result" print "requested %d, starting at %d" % (requested_count, starting_index) print "got %d out of %d" % (int( r['NumberReturned']), int(r['TotalMatches'])) print "requesting more starting now at %d" % ( starting_index + int(r['NumberReturned'])) self.browse(view, row_path, column, starting_index=starting_index + int(r['NumberReturned']), force=True)
def button_action(self, widget, event): #print "TreeWidget button_action", widget, event, event.button x = int(event.x) y = int(event.y) path = widget.get_path_at_pos(x, y) if path == None: return True row_path, column, _, _ = path if event.button == 1 and self.details_store != None: store = widget.get_model() iter = store.get_iter(row_path) didl, = store.get(iter, DIDL_COLUMN) self.details_store.clear() #print didl et = parse_xml(didl, 'utf-8') et = et.getroot() def un_namespace(text): for k, v in namespaces.items(): if text.startswith(k): return text.replace(k, v) return text def append(item, row=None): for k, v in item.attrib.items(): self.details_store.append(row, (un_namespace(k), v)) for child in item: new_row = self.details_store.append( row, (un_namespace(child.tag), child.text)) if un_namespace(child.tag) == 'DIDL-Lite:res': append(child, new_row) for item in et: append(item) if event.button == 3: if self.cb_item_right_click != None: return self.cb_item_right_click(widget, event) else: store = widget.get_model() iter = store.get_iter(row_path) title, object_id, upnp_class = self.store.get( iter, NAME_COLUMN, ID_COLUMN, UPNP_CLASS_COLUMN) menu = None if upnp_class == 'root' or upnp_class.startswith( 'object.container'): def refresh(treeview, path): expanded = treeview.row_expanded(path) store = treeview.get_model() iter = store.get_iter(row_path) child = store.iter_children(iter) while child: store.remove(child) child = store.iter_children(iter) self.browse(treeview, path, None, starting_index=0, requested_count=0, force=True, expand=expanded) menu = gtk.Menu() item = gtk.MenuItem("refresh container") item.connect("activate", lambda x: refresh(widget, row_path)) menu.append(item) if upnp_class != 'root': url, didl = self.store.get(iter, SERVICE_COLUMN, DIDL_COLUMN) if upnp_class.startswith('object.container'): from coherence.upnp.core import DIDLLite url = '' item = DIDLLite.DIDLElement.fromString( didl).getItems()[0] res = item.res.get_matching(['*:*:*:*'], protocol_type='http-get') if len(res) > 0: for r in res: if r.data.startswith('dlna-playcontainer://'): url = r.data break if url != '': print "prepare to play", url def handle_error(e): print 'we have an error', e def handle_result(r): print "done", r def start(r, service): print "call start", service action = service.get_action('Play') d = action.call(InstanceID=0, Speed=1) d.addCallback(handle_result) d.addErrback(handle_error) def set_uri(r, service, url, didl): print "call set", service, url, didl action = service.get_action('SetAVTransportURI') d = action.call(InstanceID=0, CurrentURI=url, CurrentURIMetaData=didl) d.addCallback(start, service) d.addErrback(handle_error) return d def play(service, url, didl): print "call stop", service action = service.get_action('Stop') print action d = action.call(InstanceID=0) d.addCallback(set_uri, service, url, didl) d.addErrback(handle_error) if menu == None: menu = gtk.Menu() else: menu.append(gtk.SeparatorMenuItem()) item = gtk.MenuItem("play on MediaRenderer...") item.set_sensitive(False) menu.append(item) menu.append(gtk.SeparatorMenuItem()) for device in self.coherence.devices: if device.get_device_type().split( ':')[3].lower() == 'mediarenderer': item = gtk.MenuItem(device.get_friendly_name()) service = device.get_service_by_type( 'AVTransport') item.connect( "activate", lambda x: play(service, url, didl)) menu.append(item) if menu != None: menu.show_all() menu.popup(None, None, None, event.button, event.time) return True return 0
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: self._gotError(failure.Failure(errorCode(415)), request, methodName) return server.NOT_DONE_YET self.debug('headers: %r' % headers) function, useKeywords = self.lookupFunction(methodName) #print 'function', function, 'keywords', useKeywords, 'args', args, 'kwargs', kwargs if not function: self._methodNotFound(request, methodName) return server.NOT_DONE_YET else: keywords = {'soap_methodName':methodName} if(headers.has_key('user-agent') and headers['user-agent'].find('Xbox/') == 0): keywords['X_UPnPClient'] = 'XBox' #if(headers.has_key('user-agent') and # headers['user-agent'].startswith("""Mozilla/4.0 (compatible; UPnP/1.0; Windows""")): # keywords['X_UPnPClient'] = 'XBox' if(headers.has_key('x-av-client-info') and headers['x-av-client-info'].find('"PLAYSTATION3') > 0): keywords['X_UPnPClient'] = 'PLAYSTATION3' if(headers.has_key('user-agent') and headers['user-agent'].find('Philips-Software-WebClient/4.32') == 0): keywords['X_UPnPClient'] = 'Philips-TV' for k, v in kwargs.items(): keywords[str(k)] = v self.info('call', methodName, keywords) if hasattr(function, "useKeywords"): d = defer.maybeDeferred(function, **keywords) else: d = defer.maybeDeferred(function, *args, **keywords) d.addCallback(self._gotResult, request, methodName, ns) d.addErrback(self._gotError, request, methodName, ns) return server.NOT_DONE_YET
def got_page(result): result = utils.parse_xml(result, encoding='utf-8') for genre in result.findall('genre'): self.append({'name':genre.get('name').encode('utf-8'), 'mimetype':'directory', 'url':'%s?genre=%s' % (self.config.get('genrelist','http://www.shoutcast.com/sbin/newxml.phtml'),genre.get('name'))},parent)
def reply(r): #print "browse_reply - %s of %s returned" % (r['NumberReturned'],r['TotalMatches']) from coherence.upnp.core import DIDLLite from coherence.extern.et import ET child = self.store.iter_children(iter) if child: upnp_class, = self.store.get(child,UPNP_CLASS_COLUMN) if upnp_class == 'placeholder': self.store.remove(child) title, = self.store.get(iter,NAME_COLUMN) try: title = title[:title.rindex('(')] self.store.set_value(iter,NAME_COLUMN, "%s(%d)" % (title,int(r['TotalMatches']))) except ValueError: pass elt = parse_xml(r['Result'], 'utf-8') elt = elt.getroot() for child in elt: #stored_didl_string = DIDLLite.element_to_didl(child) stored_didl_string = DIDLLite.element_to_didl(ET.tostring(child)) didl = DIDLLite.DIDLElement.fromString(stored_didl_string) item = didl.getItems()[0] #print item.title, item.id, item.upnp_class if item.upnp_class.startswith('object.container'): icon = self.folder_icon service, = self.store.get(iter,SERVICE_COLUMN) child_count = item.childCount try: title = "%s (%d)" % (item.title,item.childCount) except TypeError: title = "%s (n/a)" % item.title child_count = -1 else: icon=None service = '' child_count = -1 title = item.title if item.upnp_class.startswith('object.item.audioItem'): icon = self.audio_icon elif item.upnp_class.startswith('object.item.videoItem'): icon = self.video_icon elif item.upnp_class.startswith('object.item.imageItem'): icon = self.image_icon res = item.res.get_matching(['*:*:*:*'], protocol_type='http-get') if len(res) > 0: res = res[0] service = res.data new_iter = self.store.append(iter, (title,item.id,item.upnp_class,child_count,'',service,icon,stored_didl_string,None)) if item.upnp_class.startswith('object.container'): self.store.append(new_iter, ('...loading...','','placeholder',-1,'','',None,'',None)) if((int(r['TotalMatches']) > 0 and force==False) or expand==True): view.expand_row(row_path, False) if(requested_count != int(r['NumberReturned']) and int(r['NumberReturned']) < (int(r['TotalMatches'])-starting_index)): print "seems we have been returned only a part of the result" print "requested %d, starting at %d" % (requested_count,starting_index) print "got %d out of %d" % (int(r['NumberReturned']), int(r['TotalMatches'])) print "requesting more starting now at %d" % (starting_index+int(r['NumberReturned'])) self.browse(view,row_path,column, starting_index=starting_index+int(r['NumberReturned']), force=True)
def reply(r, service): if iter: child = model.iter_children(iter) if child: upnp_class = model.get(child, self.MS_UPNP_CLASS_COLUMN)[0] if upnp_class == 'placeholder': model.remove(child) title = model.get(iter, self.MS_NAME_COLUMN)[0] if title: try: title = title[:title.rindex('(')] model.set_value( iter, self.MS_NAME_COLUMN, "%s(%d)" % (title, int(r['TotalMatches']))) except ValueError: pass elt = parse_xml(r['Result'], 'utf-8') elt = elt.getroot() for child in elt: stored_didl_string = DIDLLite.element_to_didl( ET.tostring(child)) didl = DIDLLite.DIDLElement.fromString(stored_didl_string) item = didl.getItems()[0] if item.upnp_class.startswith('object.container'): icon = self.folder_icon #service = model.get(iter, self.MS_SERVICE_PATH_COLUMN)[0] child_count = item.childCount try: title = "%s (%d)" % (item.title, item.childCount) except TypeError: title = "%s (n/a)" % item.title child_count = -1 else: icon = None service = '' child_count = -1 title = item.title if item.upnp_class.startswith('object.item.audioItem'): icon = self.audio_icon elif item.upnp_class.startswith('object.item.videoItem'): icon = self.video_icon elif item.upnp_class.startswith('object.item.imageItem'): icon = self.image_icon res = item.res.get_matching(['*:*:*:*'], protocol_type='http-get') if len(res) > 0: res = res[0] service = res.data new_iter = model.append( iter, (title, item.id, item.upnp_class, child_count, '', service, icon, stored_didl_string, None)) if item.upnp_class.startswith('object.container'): model.append(new_iter, ('...loading...', '', 'placeholder', -1, '', '', None, '', None)) if ((int(r['TotalMatches']) > 0 and force==False) or \ expand==True): if view: view.expand_row(row_path, False) if(requested_count != int(r['NumberReturned']) and \ int(r['NumberReturned']) < (int(r['TotalMatches'])-starting_index)): self.browse(view, row_path, column, starting_index=starting_index + int(r['NumberReturned']), force=True)
def got_result(result, method): self.debug('flickr_call %r result %r', method, result) result = parse_xml(result, encoding='utf-8') return result
def button_action(self, widget, event): #print "TreeWidget button_action", widget, event, event.button x = int(event.x) y = int(event.y) path = widget.get_path_at_pos(x, y) if path == None: return True row_path,column,_,_ = path if event.button == 1 and self.details_store != None: store = widget.get_model() iter = store.get_iter(row_path) didl,= store.get(iter,DIDL_COLUMN) self.details_store.clear() #print didl et = parse_xml(didl, 'utf-8') et = et.getroot() def un_namespace(text): for k,v in namespaces.items(): if text.startswith(k): return text.replace(k,v) return text def append(item,row=None): for k,v in item.attrib.items(): self.details_store.append(row,(un_namespace(k),v)) for child in item: new_row=self.details_store.append(row,(un_namespace(child.tag),child.text)) if un_namespace(child.tag) == 'DIDL-Lite:res': append(child,new_row) for item in et: append(item) if event.button == 3: if self.cb_item_right_click != None: return self.cb_item_right_click(widget, event) else: store = widget.get_model() iter = store.get_iter(row_path) title,object_id,upnp_class = self.store.get(iter,NAME_COLUMN,ID_COLUMN,UPNP_CLASS_COLUMN) menu = None if upnp_class == 'root' or upnp_class.startswith('object.container'): def refresh(treeview,path): expanded = treeview.row_expanded(path) store = treeview.get_model() iter = store.get_iter(row_path) child = store.iter_children(iter) while child: store.remove(child) child = store.iter_children(iter) self.browse(treeview,path,None, starting_index=0,requested_count=0,force=True,expand=expanded) menu = Gtk.Menu() item = Gtk.MenuItem("refresh container") item.connect("activate", lambda x: refresh(widget,row_path)) menu.append(item) if upnp_class != 'root': url,didl = self.store.get(iter,SERVICE_COLUMN,DIDL_COLUMN) if upnp_class.startswith('object.container'): from coherence.upnp.core import DIDLLite url = '' item = DIDLLite.DIDLElement.fromString(didl).getItems()[0] res = item.res.get_matching(['*:*:*:*'], protocol_type='http-get') if len(res) > 0: for r in res: if r.data.startswith('dlna-playcontainer://'): url = r.data break if url != '': print "prepare to play", url def handle_error(e): print 'we have an error', e def handle_result(r): print "done", r def start(r,service): print "call start", service, service.device.get_friendly_name() action = service.get_action('Play') d = action.call(InstanceID=0,Speed=1) d.addCallback(handle_result) d.addErrback(handle_error) def set_uri(r,service,url,didl): print "call set", service,service.device.get_friendly_name(),url,didl action = service.get_action('SetAVTransportURI') d = action.call(InstanceID=0,CurrentURI=url, CurrentURIMetaData=didl) d.addCallback(start,service) d.addErrback(handle_error) return d def play(service,url,didl): print "call stop", service, service.device.get_friendly_name() action = service.get_action('Stop') print action d = action.call(InstanceID=0) d.addCallback(set_uri,service,url,didl) d.addErrback(handle_error) if menu == None: menu = Gtk.Menu() else: menu.append(Gtk.SeparatorMenuItem()) item = Gtk.MenuItem("play on MediaRenderer...") item.set_sensitive(False) menu.append(item) menu.append(Gtk.SeparatorMenuItem()) for device in self.coherence.devices: if device.get_device_type().split(':')[3].lower() == 'mediarenderer': service = device.get_service_by_type('AVTransport') if service != None: item = Gtk.MenuItem(device.get_friendly_name()) item.connect("activate", lambda x,s,u,d: play(s,u,d),service,url,didl) menu.append(item) if menu != None: menu.show_all() menu.popup(None,None,None,event.button,event.time) return True return 0