Example #1
0
        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
Example #2
0
        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']))
Example #3
0
        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"]))
Example #4
0
        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']))
Example #5
0
    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 ""
Example #6
0
        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()                
Example #7
0
        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)
Example #8
0
    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
Example #9
0
        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()
Example #10
0
        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()
Example #11
0
        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)
Example #12
0
        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
Example #13
0
    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 ""
Example #14
0
    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 ""
Example #15
0
    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
Example #16
0
        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,
                )
Example #17
0
 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
Example #18
0
 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']))
Example #19
0
        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
Example #20
0
 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
Example #21
0
 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
Example #22
0
    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()
Example #23
0
        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)
            """
Example #24
0
        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)
            """
Example #25
0
 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()
Example #26
0
 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)
Example #27
0
        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)
Example #28
0
            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
Example #29
0
        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
Example #30
0
        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
Example #31
0
    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 ""
Example #32
0
 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
Example #33
0
    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
Example #34
0
    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
Example #35
0
    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()
Example #36
0
        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
Example #37
0
    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
Example #38
0
        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
Example #39
0
            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
Example #40
0
 def fromString(cls, data):
     instance = cls()
     elt = utils.parse_xml(data)
     #elt = ElementTree(elt)
     instance.fromElement(elt.getroot())
     return instance
Example #41
0
    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()
Example #42
0
    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()
Example #43
0
 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()
Example #44
0
        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)
Example #45
0
    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
Example #46
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
Example #47
0
 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)
Example #48
0
        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)
Example #49
0
        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)
Example #50
0
 def got_result(result, method):
     self.debug('flickr_call %r result %r', method, result)
     result = parse_xml(result, encoding='utf-8')
     return result
Example #51
0
    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
Example #52
0
 def fromString(cls, data):
     instance = cls()
     elt = utils.parse_xml(data)
     #elt = ElementTree(elt)
     instance.fromElement(elt.getroot())
     return instance