Exemple #1
0
    def upnp_PrepareForConnection(self, *args, **kwargs):
        self.info('upnp_PrepareForConnection')
        """ check if we really support that mimetype """
        RemoteProtocolInfo = kwargs['RemoteProtocolInfo']
        """ if we are a MR and this in not 'Input'
            then there is something strange going on
        """
        Direction = kwargs['Direction']
        if (self.device.device_type == 'MediaRenderer'
                and Direction == 'Output'):
            return failure.Failure(errorCode(702))
        if (self.device.device_type == 'MediaServer' and Direction != 'Input'):
            return failure.Failure(errorCode(702))
        """ the InstanceID of the MS ? """
        PeerConnectionID = kwargs['PeerConnectionID']
        """ ??? """
        PeerConnectionManager = kwargs['PeerConnectionManager']
        local_protocol_infos = None
        if self.device.device_type == 'MediaRenderer':
            local_protocol_infos = self.get_variable('SinkProtocolInfo').value
        if self.device.device_type == 'MediaServer':
            local_protocol_infos = self.get_variable(
                'SourceProtocolInfo').value
        self.debug('ProtocalInfos:', RemoteProtocolInfo, '--',
                   local_protocol_infos)

        try:
            remote_protocol, remote_network, remote_content_format, _ = RemoteProtocolInfo.split(
                ':')
        except:
            self.warning("unable to process RemoteProtocolInfo",
                         RemoteProtocolInfo)
            return failure.Failure(errorCode(701))

        for protocol_info in local_protocol_infos.split(','):
            #print remote_protocol,remote_network,remote_content_format
            #print protocol_info
            local_protocol, local_network, local_content_format, _ = protocol_info.split(
                ':')
            #print local_protocol,local_network,local_content_format
            if ((remote_protocol == local_protocol or remote_protocol == '*'
                 or local_protocol == '*')
                    and (remote_network == local_network
                         or remote_network == '*' or local_network == '*')
                    and (remote_content_format == local_content_format
                         or remote_content_format == '*'
                         or local_content_format == '*')):

                connection_id, avt_id, rcs_id = \
                    self.add_connection(RemoteProtocolInfo,
                                        Direction,
                                        PeerConnectionID,
                                        PeerConnectionManager)
                return {
                    'ConnectionID': connection_id,
                    'AVTransportID': avt_id,
                    'RcsID': rcs_id
                }

        return failure.Failure(errorCode(701))
Exemple #2
0
    def upnp_ImportResource(self, *args, **kwargs):
        print 'upnp_ImportResource', args, kwargs
        SourceURI = kwargs['SourceURI']
        DestinationURI = kwargs['DestinationURI']

        if DestinationURI.endswith('?import'):
            id = DestinationURI.split('/')[-1]
            id = id[:-7]  # remove the ?import
        else:
            return failure.Failure(errorCode(718))

        item = self.get_by_id(id)
        if item == None:
            return failure.Failure(errorCode(718))

        def gotPage(result):

            try:
                import cStringIO as StringIO
            except ImportError:
                import StringIO

            self.backend_import(item, StringIO.StringIO(result[0]))

        def gotError(error, url):
            self.warning("error requesting %s", url)
            self.info(error)
            return failure.Failure(errorCode(718))

        d = getPage(SourceURI)
        d.addCallbacks(gotPage, gotError, None, None, [SourceURI], None)

        transfer_id = 0  # FIXME

        return {'TransferID': transfer_id}
Exemple #3
0
    def soap__generic(self, *args, **kwargs):
        """ generic UPnP service control method,
            which will be used if no soap_ACTIONNAME method
            in the server service control class can be found
        """
        try:
            action = self.actions[kwargs['soap_methodName']]
        except:
            return failure.Failure(errorCode(401))

        try:
            instance = int(kwargs['InstanceID'])
        except:
            instance = 0

        self.info("soap__generic", action, __name__, kwargs)
        del kwargs['soap_methodName']
        if (kwargs.has_key('X_UPnPClient')
                and kwargs['X_UPnPClient'] == 'XBox'):
            if (action.name == 'Browse' and kwargs.has_key('ContainerID')):
                """ XXX: THIS IS SICK """
                kwargs['ObjectID'] = kwargs['ContainerID']
                del kwargs['ContainerID']

        in_arguments = action.get_in_arguments()
        for arg_name, arg in kwargs.iteritems():
            if arg_name.find('X_') == 0:
                continue
            l = [a for a in in_arguments if arg_name == a.get_name()]
            if len(l) > 0:
                in_arguments.remove(l[0])
            else:
                self.critical('argument %s not valid for action %s' %
                              (arg_name, action.name))
                return failure.Failure(errorCode(402))
        if len(in_arguments) > 0:
            self.critical('argument %s missing for action %s' %
                          ([a.get_name() for a in in_arguments], action.name))
            return failure.Failure(errorCode(402))

        def callit(*args, **kwargs):
            #print 'callit args', args
            #print 'callit kwargs', kwargs
            result = {}
            callback = action.get_callback()
            if callback != None:
                return callback(**kwargs)
            return result

        def got_error(x):
            #print 'failure', x
            self.info('soap__generic error during call processing')
            return x

        # call plugin method for this action
        d = defer.maybeDeferred(callit, *args, **kwargs)
        d.addCallback(self.get_action_results, action, instance)
        d.addErrback(got_error)
        return d
Exemple #4
0
    def soap__generic(self, *args, **kwargs):
        """ generic UPnP service control method,
            which will be used if no soap_ACTIONNAME method
            in the server service control class can be found
        """
        try:
            action = self.actions[kwargs['soap_methodName']]
        except:
            return failure.Failure(errorCode(401))

        try:
            instance = int(kwargs['InstanceID'])
        except:
            instance = 0

        self.info("soap__generic", action, __name__, kwargs)
        del kwargs['soap_methodName']
        if( kwargs.has_key('X_UPnPClient') and
                kwargs['X_UPnPClient'] == 'XBox'):
            if(action.name == 'Browse' and
                    kwargs.has_key('ContainerID')):
                """ XXX: THIS IS SICK """
                kwargs['ObjectID'] = kwargs['ContainerID']
                del kwargs['ContainerID']

        in_arguments = action.get_in_arguments()
        for arg_name, arg in kwargs.iteritems():
            if arg_name.find('X_') == 0:
                continue
            l = [ a for a in in_arguments if arg_name == a.get_name()]
            if len(l) > 0:
                in_arguments.remove(l[0])
            else:
                self.critical('argument %s not valid for action %s' % (arg_name,action.name))
                return failure.Failure(errorCode(402))
        if len(in_arguments) > 0:
            self.critical('argument %s missing for action %s' %
                                ([ a.get_name() for a in in_arguments],action.name))
            return failure.Failure(errorCode(402))

        def callit( *args, **kwargs):
            #print 'callit args', args
            #print 'callit kwargs', kwargs
            result = {}
            callback = action.get_callback()
            if callback != None:
                return callback( **kwargs)
            return result

        def got_error(x):
            #print 'failure', x
            self.info('soap__generic error during call processing')
            return x

        # call plugin method for this action
        d = defer.maybeDeferred( callit, *args, **kwargs)
        d.addCallback( self.get_action_results, action, instance)
        d.addErrback(got_error)
        return d
    def upnp_Seek(self, *args, **kwargs):
        InstanceID = int(kwargs['InstanceID'])
        Unit = kwargs['Unit']
        Target = kwargs['Target']
        if InstanceID != 0:
            return failure.Failure(errorCode(718))
        if Unit in ['TRACK_NR']:
            if self.playcontainer == None:
                NextURI = self.server.av_transport_server.get_variable(
                    'NextAVTransportURI').value
                if NextURI != '':
                    self.server.av_transport_server.set_variable(
                        InstanceID, 'TransportState', 'TRANSITIONING')
                    NextURIMetaData = self.server.av_transport_server.get_variable(
                        'NextAVTransportURIMetaData').value
                    self.server.av_transport_server.set_variable(
                        InstanceID, 'NextAVTransportURI', '')
                    self.server.av_transport_server.set_variable(
                        InstanceID, 'NextAVTransportURIMetaData', '')
                    r = self.upnp_SetAVTransportURI(
                        self,
                        InstanceID=InstanceID,
                        CurrentURI=NextURI,
                        CurrentURIMetaData=NextURIMetaData)
                    return r
            else:
                Target = int(Target)
                if 0 < Target <= len(self.playcontainer[2]):
                    self.server.av_transport_server.set_variable(
                        InstanceID, 'TransportState', 'TRANSITIONING')
                    next_track = ()
                    item = self.playcontainer[2][Target - 1]
                    local_protocol_infos = self.server.connection_manager_server.get_variable(
                        'SinkProtocolInfo').value.split(',')
                    res = item.res.get_matching(local_protocol_infos,
                                                protocol_type='internal')
                    if len(res) == 0:
                        res = item.res.get_matching(local_protocol_infos)
                    if len(res) > 0:
                        res = res[0]
                        remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(
                            ':')
                        didl = DIDLLite.DIDLElement()
                        didl.addItem(item)
                        next_track = (res.data, didl.toString(),
                                      remote_content_format)
                        self.playcontainer[0] = Target - 1

                    if len(next_track) == 3:
                        self.server.av_transport_server.set_variable(
                            self.server.connection_manager_server.
                            lookup_avt_id(self.current_connection_id),
                            'CurrentTrack', Target)
                        self.load(next_track[0], next_track[1], next_track[2])
                        self.play()
                        return {}
            return failure.Failure(errorCode(711))

        return failure.Failure(errorCode(710))
    def upnp_Seek(self, *args, **kwargs):
        InstanceID = int(kwargs['InstanceID'])
        Unit = kwargs['Unit']
        Target = kwargs['Target']
        if InstanceID != 0:
            return failure.Failure(errorCode(718))
        if Unit in ['ABS_TIME','REL_TIME']:
            old_state = self.server.av_transport_server.get_variable('TransportState').value
            self.server.av_transport_server.set_variable(InstanceID, 'TransportState', 'TRANSITIONING')

            sign = ''
            if Target[0] == '+':
                Target = Target[1:]
                sign = '+'
            if Target[0] == '-':
                Target = Target[1:]
                sign = '-'

            h,m,s = Target.split(':')
            seconds = int(h)*3600 + int(m)*60 + int(s)
            self.seek(sign+str(seconds), old_state)
        if Unit in ['TRACK_NR']:
            if self.playcontainer == None:
                NextURI = self.server.av_transport_server.get_variable('NextAVTransportURI',InstanceID).value
                if NextURI != '':
                    self.server.av_transport_server.set_variable(InstanceID, 'TransportState', 'TRANSITIONING')
                    NextURIMetaData = self.server.av_transport_server.get_variable('NextAVTransportURIMetaData').value
                    self.server.av_transport_server.set_variable(InstanceID, 'NextAVTransportURI', '')
                    self.server.av_transport_server.set_variable(InstanceID, 'NextAVTransportURIMetaData', '')
                    r = self.upnp_SetAVTransportURI(self, InstanceID=InstanceID,CurrentURI=NextURI,CurrentURIMetaData=NextURIMetaData)
                    return r
            else:
                Target = int(Target)
                if 0 < Target <= len(self.playcontainer[2]):
                    self.server.av_transport_server.set_variable(InstanceID, 'TransportState', 'TRANSITIONING')
                    next_track = ()
                    item = self.playcontainer[2][Target-1]
                    local_protocol_infos=self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
                    res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
                    if len(res) == 0:
                        res = item.res.get_matching(local_protocol_infos)
                    if len(res) > 0:
                        res = res[0]
                        remote_protocol,remote_network,remote_content_format,_ = res.protocolInfo.split(':')
                        didl = DIDLLite.DIDLElement()
                        didl.addItem(item)
                        next_track = (res.data,didl.toString(),remote_content_format)
                        self.playcontainer[0] = Target-1

                    if len(next_track) == 3:
                        self.server.av_transport_server.set_variable(self.server.connection_manager_server.lookup_avt_id(self.current_connection_id), 'CurrentTrack',Target)
                        self.load(next_track[0],next_track[1],next_track[2])
                        self.play()
                        return {}
            return failure.Failure(errorCode(711))

        return {}
Exemple #7
0
    def upnp_ImportResource(self, *args, **kwargs):
        SourceURI = kwargs['SourceURI']
        DestinationURI = kwargs['DestinationURI']

        if DestinationURI.endswith('?import'):
            id = DestinationURI.split('/')[-1]
            id = id[:-7]  # remove the ?import
        else:
            return failure.Failure(errorCode(718))

        item = self.get_by_id(id)
        if item is None:
            return failure.Failure(errorCode(718))

        def gotPage(headers):
            # print('gotPage', headers)
            content_type = headers.get('content-type', [])
            if not isinstance(content_type, list):
                content_type = list(content_type)
            if len(content_type) > 0:
                extension = mimetypes.guess_extension(content_type[0],
                                                      strict=False)
                item.set_path(None, extension)
            shutil.move(tmp_path, item.get_path())
            item.rebuild(self.urlbase)
            if hasattr(self, 'update_id'):
                self.update_id += 1
                if self.server:
                    if hasattr(self.server, 'content_directory_server'):
                        self.server.content_directory_server.set_variable(
                            0, 'SystemUpdateID', self.update_id)
                if item.parent is not None:
                    value = (item.parent.get_id(), item.parent.get_update_id())
                    if self.server:
                        if hasattr(self.server, 'content_directory_server'):
                            self.server.content_directory_server.set_variable(
                                0, 'ContainerUpdateIDs', value)

        def gotError(error, url):
            self.warning(f'error requesting {url}')
            self.info(error)
            os.unlink(tmp_path)
            return failure.Failure(errorCode(718))

        tmp_fp, tmp_path = tempfile.mkstemp()
        os.close(tmp_fp)

        utils.downloadPage(SourceURI,
                           tmp_path).addCallbacks(gotPage, gotError, None,
                                                  None, [SourceURI], None)

        transfer_id = 0  # FIXME

        return {'TransferID': transfer_id}
    def upnp_PrepareForConnection(self, *args, **kwargs):
        self.info('upnp_PrepareForConnection')
        """ check if we really support that mimetype """
        RemoteProtocolInfo = kwargs['RemoteProtocolInfo']
        """ if we are a MR and this in not 'Input'
            then there is something strange going on
        """
        Direction = kwargs['Direction']
        if( self.device.device_type == 'MediaRenderer' and
            Direction == 'Output'):
            return failure.Failure(errorCode(702))
        if( self.device.device_type == 'MediaServer' and
            Direction != 'Input'):
            return failure.Failure(errorCode(702))
        """ the InstanceID of the MS ? """
        PeerConnectionID = kwargs['PeerConnectionID']
        """ ??? """
        PeerConnectionManager = kwargs['PeerConnectionManager']
        local_protocol_infos = None
        if self.device.device_type == 'MediaRenderer':
            local_protocol_infos = self.get_variable('SinkProtocolInfo').value
        if self.device.device_type == 'MediaServer':
            local_protocol_infos = self.get_variable('SourceProtocolInfo').value
        self.debug('ProtocalInfos:',RemoteProtocolInfo, '--', local_protocol_infos)

        try:
            remote_protocol,remote_network,remote_content_format,_ = RemoteProtocolInfo.split(':')
        except:
            self.warning("unable to process RemoteProtocolInfo", RemoteProtocolInfo)
            return failure.Failure(errorCode(701))

        for protocol_info in local_protocol_infos.split(','):
            #print remote_protocol,remote_network,remote_content_format
            #print protocol_info
            local_protocol,local_network,local_content_format,_ = protocol_info.split(':')
            #print local_protocol,local_network,local_content_format
            if((remote_protocol == local_protocol or
                remote_protocol == '*' or
                local_protocol == '*') and
               (remote_network == local_network or
                remote_network == '*' or
                local_network == '*') and
               (remote_content_format == local_content_format or
                remote_content_format == '*' or
                local_content_format == '*')):

                connection_id, avt_id, rcs_id = \
                    self.add_connection(RemoteProtocolInfo,
                                        Direction,
                                        PeerConnectionID,
                                        PeerConnectionManager)
                return {'ConnectionID': connection_id, 'AVTransportID': avt_id, 'RcsID': rcs_id}

        return failure.Failure(errorCode(701))
Exemple #9
0
    def soap__generic(self, *args, **kwargs):
        '''Generic UPnP service control method, which will be used
        if no soap_ACTIONNAME method in the server service control
        class can be found.'''
        try:
            action = self.actions[kwargs['soap_methodName']]
        except KeyError:
            return failure.Failure(errorCode(401))

        try:
            instance = int(kwargs['InstanceID'])
        except (ValueError, KeyError):
            instance = 0

        self.info(f'soap__generic {action} {__name__} {kwargs}')
        del kwargs['soap_methodName']

        in_arguments = action.get_in_arguments()
        for arg_name, arg in kwargs.items():
            if arg_name.find('X_') == 0:
                continue
            al = [a for a in in_arguments if arg_name == a.get_name()]
            if len(al) > 0:
                in_arguments.remove(al[0])
            else:
                self.critical(
                    f'argument {arg_name} not valid for action {action.name}')
                return failure.Failure(errorCode(402))
        if len(in_arguments) > 0:
            args_names = [a.get_name() for a in in_arguments]
            self.critical(f'argument {args_names} '
                          f'missing for action {action.name}')
            return failure.Failure(errorCode(402))

        def got_error(x):
            self.info('dbus error during call processing')
            return x

        # call plugin method for this action
        # print 'callit args', args
        # print 'callit kwargs', kwargs
        # print 'callit action', action
        # print 'callit dbus action', self.service.service.action
        d = defer.Deferred()
        self.service.service.call_action(
            action.name,
            dbus.Dictionary(kwargs, signature='ss'),
            reply_handler=d.callback,
            error_handler=d.errback,
            utf8_strings=True,
        )
        d.addCallback(self.get_action_results, action, instance)
        d.addErrback(got_error)
        return d
    def hidden_upnp_DestroyObject(self, *args, **kwargs):
        ObjectID = kwargs['ObjectID']

        item = self.get_by_id(ObjectID)
        if item == None:
            return failure.Failure(errorCode(701))

        print "upnp_DestroyObject", item.location
        try:
            item.location.remove()
        except Exception, msg:
            print Exception, msg
            return failure.Failure(errorCode(715))
    def upnp_ImportResource(self, *args, **kwargs):
        SourceURI = kwargs['SourceURI']
        DestinationURI = kwargs['DestinationURI']

        if DestinationURI.endswith('?import'):
            id = DestinationURI.split('/')[-1]
            id = id[:-7] # remove the ?import
        else:
            return failure.Failure(errorCode(718))

        item = self.get_by_id(id)
        if item == None:
            return failure.Failure(errorCode(718))

        def gotPage(headers):
            #print "gotPage", headers
            content_type = headers.get('content-type',[])
            if not isinstance(content_type, list):
                content_type = list(content_type)
            if len(content_type) > 0:
                extension = mimetypes.guess_extension(content_type[0], strict=False)
                item.set_path(None,extension)
            shutil.move(tmp_path, item.get_path())
            item.rebuild(self.urlbase)
            if hasattr(self, 'update_id'):
                self.update_id += 1
                if self.server:
                    if hasattr(self.server,'content_directory_server'):
                        self.server.content_directory_server.set_variable(0, 'SystemUpdateID', self.update_id)
                if item.parent is not None:
                    value = (item.parent.get_id(),item.parent.get_update_id())
                    if self.server:
                        if hasattr(self.server,'content_directory_server'):
                            self.server.content_directory_server.set_variable(0, 'ContainerUpdateIDs', value)

        def gotError(error, url):
            self.warning("error requesting", url)
            self.info(error)
            os.unlink(tmp_path)
            return failure.Failure(errorCode(718))

        tmp_fp, tmp_path = tempfile.mkstemp()
        os.close(tmp_fp)

        utils.downloadPage(SourceURI,
                           tmp_path).addCallbacks(gotPage, gotError, None, None, [SourceURI], None)

        transfer_id = 0  #FIXME

        return {'TransferID': transfer_id}
Exemple #12
0
    def hidden_upnp_DestroyObject(self, *args, **kwargs):
        ObjectID = kwargs['ObjectID']

        item = self.get_by_id(ObjectID)
        if item is None:
            return failure.Failure(errorCode(701))

        self.info(f'upnp_DestroyObject: {item.location}')
        try:
            item.location.remove()
        except Exception as msg:
            self.error(f'upnp_DestroyObject [{Exception}]: {msg}')
            return failure.Failure(errorCode(715))

        return {}
Exemple #13
0
    def hidden_upnp_DestroyObject(self, *args, **kwargs):
        ObjectID = kwargs['ObjectID']

        item = self.get_by_id(ObjectID)
        if item == None:
            return failure.Failure(errorCode(701))

        print("upnp_DestroyObject", item.location)
        try:
            item.location.remove()
        except Exception as msg:
            print(Exception, msg)
            return failure.Failure(errorCode(715))

        return {}
Exemple #14
0
    def hidden_upnp_DestroyObject(self, *args, **kwargs):
        ObjectID = kwargs['ObjectID']

        item = self.get_by_id(ObjectID)
        if item is None:
            return failure.Failure(errorCode(701))

        def handle_success(deleted):
            print('deleted', deleted, kwargs['ObjectID'])
            if not deleted:
                return failure.Failure(errorCode(715))
            return {}

        def handle_error(error):
            return failure.Failure(errorCode(701))

        d = defer.Deferred()
        self.store_interface.Delete(
            int(item.real_id),
            reply_handler=lambda x: d.callback(x),
            error_handler=lambda x: d.errback(x),
        )
        d.addCallback(handle_success)
        d.addErrback(handle_error)
        return d
Exemple #15
0
 def upnp_SetAVTransportURI(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     CurrentURI = kwargs['CurrentURI']
     CurrentURIMetaData = kwargs['CurrentURIMetaData']
     local_protocol_infos = \
         self.server.connection_manager_server.get_variable(
             'SinkProtocolInfo').value.split(',')
     # print '>>>', local_protocol_infos
     if len(CurrentURIMetaData) == 0:
         self.load(CurrentURI, CurrentURIMetaData)
     else:
         elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
         if elt.numItems() == 1:
             item = elt.getItems()[0]
             res = item.res.get_matching(local_protocol_infos,
                                         protocol_type='internal')
             if len(res) == 0:
                 res = item.res.get_matching(local_protocol_infos)
             if len(res) > 0:
                 res = res[0]
                 remote_protocol, remote_network, \
                     remote_content_format, _ = res.protocolInfo.split(
                         ':')
                 self.load(res.data, CurrentURIMetaData)
                 return {}
     return failure.Failure(errorCode(714))
Exemple #16
0
    def upnp_GetCurrentConnectionInfo(self, *args, **kwargs):
        ConnectionID = int(kwargs['ConnectionID'])
        """ return for this ConnectionID
            the associated InstanceIDs @ AVTransportID and RcsID
            ProtocolInfo
            PeerConnectionManager
            PeerConnectionID
            Direction
            Status

            or send a 706 if there isn't such a ConnectionID
        """
        connection = self.lookup_connection(ConnectionID)
        if connection == None:
            return failure.Failure(errorCode(706))
        else:
            return {
                'AVTransportID': connection['AVTransportID'],
                'RcsID': connection['RcsID'],
                'ProtocolInfo': connection['ProtocolInfo'],
                'PeerConnectionManager': connection['PeerConnectionManager'],
                'PeerConnectionID': connection['PeerConnectionID'],
                'Direction': connection['Direction'],
                'Status': connection['Status'],
            }
Exemple #17
0
    def upnp_CreateObject(self, *args, **kwargs):
        print "upnp_CreateObject", args, kwargs
        ContainerID = kwargs['ContainerID']
        Elements = kwargs['Elements']

        parent_item = self.get_by_id(ContainerID)
        if parent_item == None:
            return failure.Failure(errorCode(710))
        if parent_item.item.restricted:
            return failure.Failure(errorCode(713))

        if len(Elements) == 0:
            return failure.Failure(errorCode(712))

        elt = DIDLElement.fromString(Elements)
        if elt.numItems() != 1:
            return failure.Failure(errorCode(712))

        item = elt.getItems()[0]
        if(item.id != '' or
           item.parentID != ContainerID or
           item.restricted == True or
           item.title == ''):
            return failure.Failure(errorCode(712))

        if item.upnp_class.startswith('object.container'):
            if len(item.res) != 0:
                return failure.Failure(errorCode(712))

            return failure.Failure(errorCode(712))
            ### FIXME

            new_item = self.get_by_id(new_id)
            didl = DIDLElement()
            didl.addItem(new_item.item)
            return {'ObjectID': id, 'Result': didl.toString()}

        if item.upnp_class.startswith('object.item.imageItem'):
            new_id = self.getnextID()
            new_id = 'upload.' + str(new_id)
            title = item.title or 'unknown'
            mimetype = 'image/jpeg'
            self.uploads[new_id] = FlickrItem(new_id, title, self.store[UNSORTED_CONTAINER_ID], mimetype, self.urlbase,
                                        ImageItem, store=self, update=False, proxy=self.proxy)

            new_item = self.uploads[new_id]
            for res in new_item.item.res:
                res.importUri = new_item.url + '?import'
                res.data = None
            didl = DIDLElement()
            didl.addItem(new_item.item)
            r = {'ObjectID': new_id, 'Result': didl.toString()}
            print r
            return r

        return failure.Failure(errorCode(712))
Exemple #18
0
    def upnp_SetPlayMode(self, *args, **kwargs):
        InstanceID = int(kwargs['InstanceID'])
        NewPlayMode = kwargs['NewPlayMode']

        supported_play_modes = self.server.av_transport_server.get_variable(
            'CurrentPlayMode', instance=InstanceID).allowed_values
        if NewPlayMode not in supported_play_modes:
            return failure.Failure(errorCode(712))
        if self.server:
            self.server.av_transport_server.set_variable(
                InstanceID, 'CurrentPlayMode', NewPlayMode)
        return {}
Exemple #19
0
 def upnp_X_COHERENCE_SetDisplayTime(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     NewDisplayTime = int(kwargs['NewDisplayTime'])
     if 0 <= NewDisplayTime <= 65535:
         self.display_time = NewDisplayTime
         try:
             self.display_loop.delay(self.display_time)
         except:
             pass
         if self.server:
             self.server.av_transport_server.set_variable(
                 InstanceID, 'X_COHERENCE_DisplayTime', self.display_time)
         return {}
     return failure.Failure(errorCode(601))
Exemple #20
0
 def upnp_X_COHERENCE_SetDisplayTransition(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     NewDisplayTransition = kwargs['NewDisplayTransition']
     supported_transition_modes = self.server.av_transport_server.get_variable(
         'X_COHERENCE_DisplayTransition',
         instance=InstanceID).allowed_values
     if NewDisplayTransition in supported_transition_modes:
         self.display_transition = NewDisplayTransition
         self.controller.set_transition(NewDisplayTransition)
         if self.server:
             self.server.av_transport_server.set_variable(
                 InstanceID, 'X_COHERENCE_DisplayTransition',
                 self.display_transition)
         return {}
     return failure.Failure(errorCode(600))
Exemple #21
0
 def upnp_SetAVTransportURI(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     CurrentURI = kwargs['CurrentURI']
     CurrentURIMetaData = kwargs['CurrentURIMetaData']
     local_protocol_info=self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
     if len(CurrentURIMetaData)==0:
         self.load(CurrentURI,CurrentURIMetaData)
         return {}
     else:
         elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
         print elt.numItems()
         if elt.numItems() == 1:
             item = elt.getItems()[0]
             for res in item.res:
                 print res.protocolInfo,local_protocol_info
                 if res.protocolInfo in local_protocol_info:
                     self.load(CurrentURI,CurrentURIMetaData)
                     return {}
     return failure.Failure(errorCode(714))
    def upnp_SetAVTransportURI(self, *args, **kwargs):
        InstanceID = int(kwargs['InstanceID'])
        CurrentURI = kwargs['CurrentURI']
        CurrentURIMetaData = kwargs['CurrentURIMetaData']
        #print "upnp_SetAVTransportURI",InstanceID, CurrentURI, CurrentURIMetaData
        if CurrentURI.startswith('dlna-playcontainer://'):

            def handle_result(r):
                self.load(r[0], r[1], mimetype=r[2])
                return {}

            def pass_error(r):
                return r

            d = defer.maybeDeferred(self.playcontainer_browse, CurrentURI)
            d.addCallback(handle_result)
            d.addErrback(pass_error)
            return d
        elif len(CurrentURIMetaData) == 0:
            self.playcontainer = None
            self.load(CurrentURI, CurrentURIMetaData)
            return {}
        else:
            local_protocol_infos = self.server.connection_manager_server.get_variable(
                'SinkProtocolInfo').value.split(',')
            #print local_protocol_infos
            elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
            if elt.numItems() == 1:
                item = elt.getItems()[0]
                res = item.res.get_matching(local_protocol_infos,
                                            protocol_type='internal')
                if len(res) == 0:
                    res = item.res.get_matching(local_protocol_infos)
                if len(res) > 0:
                    res = res[0]
                    remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(
                        ':')
                    self.playcontainer = None
                    self.load(res.data,
                              CurrentURIMetaData,
                              mimetype=remote_content_format)
                    return {}
        return failure.Failure(errorCode(714))
Exemple #23
0
 def upnp_SetAVTransportURI(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     CurrentURI = kwargs['CurrentURI']
     CurrentURIMetaData = kwargs['CurrentURIMetaData']
     local_protocol_info = self.server.connection_manager_server.get_variable(  # noqa: E501
         'SinkProtocolInfo').value.split(',')
     if len(CurrentURIMetaData) == 0:
         self.load(CurrentURI, CurrentURIMetaData)
         return {}
     else:
         elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
         print(elt.numItems())
         if elt.numItems() == 1:
             item = elt.getItems()[0]
             for res in item.res:
                 print(res.protocolInfo, local_protocol_info)
                 if res.protocolInfo in local_protocol_info:
                     self.load(CurrentURI, CurrentURIMetaData)
                     return {}
     return failure.Failure(errorCode(714))
Exemple #24
0
 def upnp_SetAVTransportURI(self, *args, **kwargs):
     InstanceID = int(kwargs['InstanceID'])
     CurrentURI = kwargs['CurrentURI']
     CurrentURIMetaData = kwargs['CurrentURIMetaData']
     local_protocol_infos = self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
     #print '>>>', local_protocol_infos
     if len(CurrentURIMetaData) == 0:
         self.load(CurrentURI, CurrentURIMetaData)
     else:
         elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
         if elt.numItems() == 1:
             item = elt.getItems()[0]
             res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
             if len(res) == 0:
                 res = item.res.get_matching(local_protocol_infos)
             if len(res) > 0:
                 res = res[0]
                 remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(':')
                 self.load(res.data, CurrentURIMetaData)
                 return {}
     return failure.Failure(errorCode(714))
    def upnp_SetAVTransportURI(self, *args, **kwargs):
        InstanceID = int(kwargs["InstanceID"])
        CurrentURI = kwargs["CurrentURI"]
        CurrentURIMetaData = kwargs["CurrentURIMetaData"]
        # print "upnp_SetAVTransportURI",InstanceID, CurrentURI, CurrentURIMetaData
        if CurrentURI.startswith("dlna-playcontainer://"):

            def handle_result(r):
                self.load(r[0], r[1], mimetype=r[2])
                return {}

            def pass_error(r):
                return r

            d = defer.maybeDeferred(self.playcontainer_browse, CurrentURI)
            d.addCallback(handle_result)
            d.addErrback(pass_error)
            return d
        elif len(CurrentURIMetaData) == 0:
            self.playcontainer = None
            self.load(CurrentURI, CurrentURIMetaData)
            return {}
        else:
            local_protocol_infos = self.server.connection_manager_server.get_variable("SinkProtocolInfo").value.split(
                ","
            )
            # print local_protocol_infos
            elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
            if elt.numItems() == 1:
                item = elt.getItems()[0]
                res = item.res.get_matching(local_protocol_infos, protocol_type="internal")
                if len(res) == 0:
                    res = item.res.get_matching(local_protocol_infos)
                if len(res) > 0:
                    res = res[0]
                    remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(":")
                    self.playcontainer = None
                    self.load(res.data, CurrentURIMetaData, mimetype=remote_content_format)
                    return {}
        return failure.Failure(errorCode(714))
    def upnp_GetCurrentConnectionInfo(self, *args, **kwargs):
        ConnectionID = int(kwargs['ConnectionID'])
        """ return for this ConnectionID
            the associated InstanceIDs @ AVTransportID and RcsID
            ProtocolInfo
            PeerConnectionManager
            PeerConnectionID
            Direction
            Status

            or send a 706 if there isn't such a ConnectionID
        """
        connection = self.lookup_connection(ConnectionID)
        if connection == None:
            return failure.Failure(errorCode(706))
        else:
            return {'AVTransportID':connection['AVTransportID'],
                    'RcsID':connection['RcsID'],
                    'ProtocolInfo':connection['ProtocolInfo'],
                    'PeerConnectionManager':connection['PeerConnectionManager'],
                    'PeerConnectionID':connection['PeerConnectionID'],
                    'Direction':connection['Direction'],
                    'Status':connection['Status'],
                    }
    def playcontainer_browse(self,uri):
        """
        dlna-playcontainer://uuid%3Afe814e3e-5214-4c24-847b-383fb599ff01?sid=urn%3Aupnp-org%3AserviceId%3AContentDirectory&cid=1441&fid=1444&fii=0&sc=&md=0
        """
        from urllib import unquote
        from cgi import parse_qs
        from coherence.extern.et import ET
        from coherence.upnp.core.utils import parse_xml

        def handle_reply(r,uri,action,kw):
            try:
                next_track = ()
                elt = DIDLLite.DIDLElement.fromString(r['Result'])
                item = elt.getItems()[0]
                local_protocol_infos=self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
                res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
                if len(res) == 0:
                    res = item.res.get_matching(local_protocol_infos)
                if len(res) > 0:
                    res = res[0]
                    remote_protocol,remote_network,remote_content_format,_ = res.protocolInfo.split(':')
                    didl = DIDLLite.DIDLElement()
                    didl.addItem(item)
                    next_track = (res.data,didl.toString(),remote_content_format)
                """ a list with these elements:

                    the current track index
                     - will change during playback of the container items
                    the initial complete playcontainer-uri
                    a list of all the items in the playcontainer
                    the action methods to do the Browse call on the device
                    the kwargs for the Browse call
                     - kwargs['StartingIndex'] will be modified during further Browse requests
                """
                self.playcontainer = [int(kw['StartingIndex']),uri,elt.getItems()[:],action,kw]

                def browse_more(starting_index,number_returned,total_matches):
                    self.info("browse_more", starting_index,number_returned,total_matches)
                    try:

                        def handle_error(r):
                            pass

                        def handle_reply(r,starting_index):
                            elt = DIDLLite.DIDLElement.fromString(r['Result'])
                            self.playcontainer[2] += elt.getItems()[:]
                            browse_more(starting_index,int(r['NumberReturned']),int(r['TotalMatches']))

                        if((number_returned != 5 or
                           number_returned < (total_matches-starting_index)) and
                            (total_matches-number_returned) != starting_index):
                            self.info("seems we have been returned only a part of the result")
                            self.info("requested %d, starting at %d" % (5,starting_index))
                            self.info("got %d out of %d" % (number_returned, total_matches))
                            self.info("requesting more starting now at %d" % (starting_index+number_returned))
                            self.playcontainer[4]['StartingIndex'] = str(starting_index+number_returned)
                            d = self.playcontainer[3].call(**self.playcontainer[4])
                            d.addCallback(handle_reply,starting_index+number_returned)
                            d.addErrback(handle_error)
                    except:
                        import traceback
                        traceback.print_exc()

                browse_more(int(kw['StartingIndex']),int(r['NumberReturned']),int(r['TotalMatches']))

                if len(next_track) == 3:
                    return next_track
            except:
                import traceback
                traceback.print_exc()

            return failure.Failure(errorCode(714))

        def handle_error(r):
            return failure.Failure(errorCode(714))

        try:
            udn,args =  uri[21:].split('?')
            udn = unquote(udn)
            args = parse_qs(args)

            type = args['sid'][0].split(':')[-1]

            try:
                sc = args['sc'][0]
            except:
                sc = ''

            device = self.server.coherence.get_device_with_id(udn)
            service = device.get_service_by_type(type)
            action = service.get_action('Browse')

            kw = {'ObjectID':args['cid'][0],
                  'BrowseFlag':'BrowseDirectChildren',
                  'StartingIndex':args['fii'][0],
                  'RequestedCount':str(5),
                  'Filter':'*',
                  'SortCriteria':sc}

            d = action.call(**kw)
            d.addCallback(handle_reply,uri,action,kw)
            d.addErrback(handle_error)
            return d
        except:
            return failure.Failure(errorCode(714))
        def handle_reply(r,uri,action,kw):
            try:
                next_track = ()
                elt = DIDLLite.DIDLElement.fromString(r['Result'])
                item = elt.getItems()[0]
                local_protocol_infos=self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
                res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
                if len(res) == 0:
                    res = item.res.get_matching(local_protocol_infos)
                if len(res) > 0:
                    res = res[0]
                    remote_protocol,remote_network,remote_content_format,_ = res.protocolInfo.split(':')
                    didl = DIDLLite.DIDLElement()
                    didl.addItem(item)
                    next_track = (res.data,didl.toString(),remote_content_format)
                """ a list with these elements:

                    the current track index
                     - will change during playback of the container items
                    the initial complete playcontainer-uri
                    a list of all the items in the playcontainer
                    the action methods to do the Browse call on the device
                    the kwargs for the Browse call
                     - kwargs['StartingIndex'] will be modified during further Browse requests
                """
                self.playcontainer = [int(kw['StartingIndex']),uri,elt.getItems()[:],action,kw]

                def browse_more(starting_index,number_returned,total_matches):
                    self.info("browse_more", starting_index,number_returned,total_matches)
                    try:

                        def handle_error(r):
                            pass

                        def handle_reply(r,starting_index):
                            elt = DIDLLite.DIDLElement.fromString(r['Result'])
                            self.playcontainer[2] += elt.getItems()[:]
                            browse_more(starting_index,int(r['NumberReturned']),int(r['TotalMatches']))

                        if((number_returned != 5 or
                           number_returned < (total_matches-starting_index)) and
                            (total_matches-number_returned) != starting_index):
                            self.info("seems we have been returned only a part of the result")
                            self.info("requested %d, starting at %d" % (5,starting_index))
                            self.info("got %d out of %d" % (number_returned, total_matches))
                            self.info("requesting more starting now at %d" % (starting_index+number_returned))
                            self.playcontainer[4]['StartingIndex'] = str(starting_index+number_returned)
                            d = self.playcontainer[3].call(**self.playcontainer[4])
                            d.addCallback(handle_reply,starting_index+number_returned)
                            d.addErrback(handle_error)
                    except:
                        import traceback
                        traceback.print_exc()

                browse_more(int(kw['StartingIndex']),int(r['NumberReturned']),int(r['TotalMatches']))

                if len(next_track) == 3:
                    return next_track
            except:
                import traceback
                traceback.print_exc()

            return failure.Failure(errorCode(714))
		def handle_reply(r, uri, action, kw):
			try:
				next_track = ()
				elt = DIDLLite.DIDLElement.fromString(r['Result'])
				item = elt.getItems()[0]
				local_protocol_infos = self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
				res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
				if len(res) == 0:
					res = item.res.get_matching(local_protocol_infos)
				if len(res) > 0:
					res = res[0]
					remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(':')
					didl = DIDLLite.DIDLElement()
					didl.addItem(item)
					next_track = (res.data, didl.toString(), remote_content_format)
				""" a list with these elements:

					the current track index
					- will change during playback of the container items
					the initial complete playcontainer-uri
					a list of all the items in the playcontainer
					the action methods to do the Browse call on the device
					the kwargs for the Browse call
					- kwargs['StartingIndex'] will be modified during further Browse requests
				"""
				self.playcontainer = [int(kw['StartingIndex']), uri, elt.getItems()[:], action, kw]

				def browse_more(starting_index, number_returned, total_matches):
					self.info("browse_more", starting_index, number_returned, total_matches)
					try:

						def handle_error(r):
							pass

						def handle_reply(r, starting_index):
							elt = DIDLLite.DIDLElement.fromString(r['Result'])
							self.playcontainer[2] += elt.getItems()[:]
							browse_more(starting_index, int(r['NumberReturned']), int(r['TotalMatches']))

						if((number_returned != 5 or
							number_returned < (total_matches - starting_index)) and
							(total_matches - number_returned) != starting_index):
							self.info("seems we have been returned only a part of the result")
							self.info("requested %d, starting at %d" % (5, starting_index))
							self.info("got %d out of %d" % (number_returned, total_matches))
							self.info("requesting more starting now at %d" % (starting_index + number_returned))
							self.playcontainer[4]['StartingIndex'] = str(starting_index + number_returned)
							d = self.playcontainer[3].call(**self.playcontainer[4])
							d.addCallback(handle_reply, starting_index + number_returned)
							d.addErrback(handle_error)
					except:
						import traceback
						traceback.print_exc()

				browse_more(int(kw['StartingIndex']), int(r['NumberReturned']), int(r['TotalMatches']))

				if len(next_track) == 3:
					return next_track
			except:
				import traceback
				traceback.print_exc()

			return failure.Failure(errorCode(714))
    def upnp_Seek(self, *args, **kwargs):
        InstanceID = int(kwargs["InstanceID"])
        Unit = kwargs["Unit"]
        Target = kwargs["Target"]
        if InstanceID != 0:
            return failure.Failure(errorCode(718))
        if Unit in ["ABS_TIME", "REL_TIME"]:
            old_state = self.server.av_transport_server.get_variable("TransportState").value
            self.server.av_transport_server.set_variable(InstanceID, "TransportState", "TRANSITIONING")

            sign = ""
            if Target[0] == "+":
                Target = Target[1:]
                sign = "+"
            if Target[0] == "-":
                Target = Target[1:]
                sign = "-"

            h, m, s = Target.split(":")
            seconds = int(h) * 3600 + int(m) * 60 + int(s)
            self.seek(sign + str(seconds), old_state)
        if Unit in ["TRACK_NR"]:
            if self.playcontainer == None:
                NextURI = self.server.av_transport_server.get_variable("NextAVTransportURI", InstanceID).value
                if NextURI != "":
                    self.server.av_transport_server.set_variable(InstanceID, "TransportState", "TRANSITIONING")
                    NextURIMetaData = self.server.av_transport_server.get_variable("NextAVTransportURIMetaData").value
                    self.server.av_transport_server.set_variable(InstanceID, "NextAVTransportURI", "")
                    self.server.av_transport_server.set_variable(InstanceID, "NextAVTransportURIMetaData", "")
                    r = self.upnp_SetAVTransportURI(
                        self, InstanceID=InstanceID, CurrentURI=NextURI, CurrentURIMetaData=NextURIMetaData
                    )
                    return r
            else:
                Target = int(Target)
                if 0 < Target <= len(self.playcontainer[2]):
                    self.server.av_transport_server.set_variable(InstanceID, "TransportState", "TRANSITIONING")
                    next_track = ()
                    item = self.playcontainer[2][Target - 1]
                    local_protocol_infos = self.server.connection_manager_server.get_variable(
                        "SinkProtocolInfo"
                    ).value.split(",")
                    res = item.res.get_matching(local_protocol_infos, protocol_type="internal")
                    if len(res) == 0:
                        res = item.res.get_matching(local_protocol_infos)
                    if len(res) > 0:
                        res = res[0]
                        remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(":")
                        didl = DIDLLite.DIDLElement()
                        didl.addItem(item)
                        next_track = (res.data, didl.toString(), remote_content_format)
                        self.playcontainer[0] = Target - 1

                    if len(next_track) == 3:
                        self.server.av_transport_server.set_variable(
                            self.server.connection_manager_server.lookup_avt_id(self.current_connection_id),
                            "CurrentTrack",
                            Target,
                        )
                        self.load(next_track[0], next_track[1], next_track[2])
                        self.play()
                        return {}
            return failure.Failure(errorCode(711))

        return {}
Exemple #31
0
 def errback(r):
     return failure.Failure(errorCode(701))
    def upnp_Browse(self, *args, **kwargs):
        try:
            ObjectID = kwargs['ObjectID']
        except KeyError:
            self.debug('hmm, a Browse action and no ObjectID argument? ' +
                       'An XBox maybe?')
            try:
                ObjectID = kwargs['ContainerID']
            except KeyError:
                ObjectID = 0
        BrowseFlag = kwargs['BrowseFlag']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        parent_container = None
        requested_id = None

        item = None
        total = 0
        items = []

        if BrowseFlag == 'BrowseDirectChildren':
            parent_container = str(ObjectID)
        else:
            requested_id = str(ObjectID)

        self.info(f'upnp_Browse request {ObjectID} {BrowseFlag} ' +
                  f'{StartingIndex} {RequestedCount}')
        # self.debug(f'\t- kwargs: {kwargs}')

        didl = DIDLElement(
            upnp_client=kwargs.get('X_UPnPClient', ''),
            requested_id=requested_id,
            parent_container=parent_container,
            transcoding=self.transcoding,
        )

        def got_error(r):
            return r

        def process_result(result, total=None, found_item=None):
            if result is None:
                result = []
            if BrowseFlag == 'BrowseDirectChildren':
                cl = []

                def process_items(result, tm):
                    if result is None:
                        result = []
                    for i in result:
                        if i[0]:
                            didl.addItem(i[1])

                    return build_response(tm)

                for i in result:
                    d = defer.maybeDeferred(i.get_item)
                    cl.append(d)

                if found_item is not None:

                    def got_child_count(count):
                        dl = defer.DeferredList(cl)
                        dl.addCallback(process_items, count)
                        return dl

                    d = defer.maybeDeferred(found_item.get_child_count)
                    d.addCallback(got_child_count)

                    return d
                elif total is None:
                    total = item.get_child_count()

                dl = defer.DeferredList(cl)
                dl.addCallback(process_items, total)
                return dl
            else:
                didl.addItem(result)
                total = 1

            return build_response(total)

        def build_response(tm):
            r = {
                'Result': didl.toString(),
                'TotalMatches': tm,
                'NumberReturned': didl.numItems(),
            }

            if hasattr(item, 'update_id'):
                r['UpdateID'] = item.update_id
            elif hasattr(self.backend, 'update_id'):
                r['UpdateID'] = self.backend.update_id  # FIXME
            else:
                r['UpdateID'] = 0

            return r

        def proceed(result):
            if BrowseFlag == 'BrowseDirectChildren':
                d = defer.maybeDeferred(
                    result.get_children,
                    StartingIndex,
                    StartingIndex + RequestedCount,
                )
            else:
                d = defer.maybeDeferred(result.get_item)

            d.addCallback(process_result, found_item=result)
            d.addErrback(got_error)
            return d

        root_id = ObjectID

        wmc_mapping = getattr(self.backend, 'wmc_mapping', None)
        if (kwargs.get('X_UPnPClient', '') == 'XBox'
                and wmc_mapping is not None and ObjectID in wmc_mapping):
            # fake a Windows Media Connect Server
            root_id = wmc_mapping[ObjectID]
            if callable(root_id):
                item = root_id()
                if item is not None:
                    if isinstance(item, list):
                        total = len(item)
                        if int(RequestedCount) == 0:
                            items = item[StartingIndex:]
                        else:
                            items = item[StartingIndex:StartingIndex +
                                         RequestedCount]
                        return process_result(items, total=total)
                    else:
                        if isinstance(item, defer.Deferred):
                            item.addCallback(proceed)
                            return item
                        else:
                            return proceed(item)

            item = self.backend.get_by_id(root_id)
            if item is None:
                return process_result([], total=0)

            if isinstance(item, defer.Deferred):
                item.addCallback(proceed)
                return item
            else:
                return proceed(item)

        item = self.backend.get_by_id(root_id)
        if item is None:
            return failure.Failure(errorCode(701))

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
Exemple #33
0
 def gotError(error, url):
     self.warning(f'error requesting {url}')
     self.info(error)
     os.unlink(tmp_path)
     return failure.Failure(errorCode(718))
Exemple #34
0
 def errback(r):
     return failure.Failure(errorCode(701))
    def upnp_Search(self, *args, **kwargs):
        ContainerID = kwargs['ContainerID']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        SearchCriteria = kwargs['SearchCriteria']

        total = 0
        root_id = 0
        item = None
        items = []

        parent_container = str(ContainerID)

        didl = DIDLElement(upnp_client=kwargs.get('X_UPnPClient', ''),
                           parent_container=parent_container,
                           transcoding=self.transcoding)

        def build_response(tm):
            r = {'Result': didl.toString(), 'TotalMatches': tm,
                 'NumberReturned': didl.numItems()}

            if hasattr(item, 'update_id'):
                r['UpdateID'] = item.update_id
            elif hasattr(self.backend, 'update_id'):
                r['UpdateID'] = self.backend.update_id  # FIXME
            else:
                r['UpdateID'] = 0

            return r

        def got_error(r):
            return r

        def process_result(result, total=None, found_item=None):
            if result == None:
                result = []

            l = []

            def process_items(result, tm):
                if result is None:
                    result = []
                for i in result:
                    if i[0]:
                        didl.addItem(i[1])

                return build_response(tm)

            for i in result:
                d = defer.maybeDeferred(i.get_item)
                l.append(d)

            if found_item is not None:
                def got_child_count(count):
                    dl = defer.DeferredList(l)
                    dl.addCallback(process_items, count)
                    return dl

                d = defer.maybeDeferred(found_item.get_child_count)
                d.addCallback(got_child_count)

                return d
            elif total is None:
                total = item.get_child_count()

            dl = defer.DeferredList(l)
            dl.addCallback(process_items, total)
            return dl

        def proceed(result):
            if(kwargs.get('X_UPnPClient', '') == 'XBox' and
               hasattr(result, 'get_artist_all_tracks')):
                d = defer.maybeDeferred(result.get_artist_all_tracks, StartingIndex, StartingIndex + RequestedCount)
            else:
                d = defer.maybeDeferred(result.get_children, StartingIndex, StartingIndex + RequestedCount)
            d.addCallback(process_result, found_item=result)
            d.addErrback(got_error)
            return d

        try:
            root_id = ContainerID
        except:
            pass

        wmc_mapping = getattr(self.backend, "wmc_mapping", None)
        if kwargs.get('X_UPnPClient', '') == 'XBox':
            if(wmc_mapping is not None and
               wmc_mapping.has_key(ContainerID)):
                """ fake a Windows Media Connect Server
                """
                root_id = wmc_mapping[ContainerID]
                if callable(root_id):
                    item = root_id()
                    if item is not None:
                        if isinstance(item, list):
                            total = len(item)
                            if int(RequestedCount) == 0:
                                items = item[StartingIndex:]
                            else:
                                items = item[StartingIndex:StartingIndex + RequestedCount]
                            return process_result(items, total=total)
                        else:
                            if isinstance(item, defer.Deferred):
                                item.addCallback(proceed)
                                return item
                            else:
                                return proceed(item)

                item = self.backend.get_by_id(root_id)
                if item is None:
                    return process_result([], total=0)

                if isinstance(item, defer.Deferred):
                    item.addCallback(proceed)
                    return item
                else:
                    return proceed(item)

        item = self.backend.get_by_id(root_id)
        if item is None:
            return failure.Failure(errorCode(701))

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
Exemple #36
0
    def upnp_CreateObject(self, *args, **kwargs):
        # print(f'CreateObject {kwargs}')
        if kwargs['ContainerID'] == 'DLNA.ORG_AnyContainer':
            if self.import_folder is not None:
                ContainerID = self.import_folder_id
            else:
                return failure.Failure(errorCode(712))
        else:
            ContainerID = kwargs['ContainerID']
        Elements = kwargs['Elements']

        parent_item = self.get_by_id(ContainerID)
        if parent_item is None:
            return failure.Failure(errorCode(710))
        if parent_item.item.restricted:
            return failure.Failure(errorCode(713))

        if len(Elements) == 0:
            return failure.Failure(errorCode(712))

        elt = DIDLElement.fromString(Elements)
        if elt.numItems() != 1:
            return failure.Failure(errorCode(712))

        item = elt.getItems()[0]
        if item.parentID == 'DLNA.ORG_AnyContainer':
            item.parentID = ContainerID
        if (item.id != '' or item.parentID != ContainerID
                or item.restricted is True or item.title == ''):
            return failure.Failure(errorCode(712))

        if '..' in item.title or '~' in item.title or os.sep in item.title:
            return failure.Failure(errorCode(712))

        if item.upnp_class == 'object.container.storageFolder':
            if len(item.res) != 0:
                return failure.Failure(errorCode(712))
            path = os.path.join(parent_item.get_path(), item.title)
            id = self.create('directory', path, parent_item)
            try:
                os.mkdir(path)
            except Exception:
                self.remove(id)
                return failure.Failure(errorCode(712))

            if self.inotify is not None:
                mask = (IN_CREATE
                        | IN_DELETE
                        | IN_MOVED_FROM
                        | IN_MOVED_TO
                        | IN_CHANGED)
                self.inotify.watch(
                    path,
                    mask=mask,
                    autoAdd=False,
                    callbacks=[partial(self.notify, parameter=id)],
                )

            new_item = self.get_by_id(id)
            didl = DIDLElement()
            didl.addItem(new_item.item)
            return {'ObjectID': id, 'Result': didl.toString()}

        if item.upnp_class.startswith('object.item'):
            _, _, content_format, _ = item.res[0].protocolInfo.split(':')
            extension = mimetypes.guess_extension(content_format, strict=False)
            path = os.path.join(parent_item.get_realpath(),
                                item.title + extension)
            id = self.create('item', path, parent_item)

            new_item = self.get_by_id(id)
            for res in new_item.item.res:
                res.importUri = new_item.url + '?import'
                res.data = None
            didl = DIDLElement()
            didl.addItem(new_item.item)
            return {'ObjectID': id, 'Result': didl.toString()}

        return failure.Failure(errorCode(712))
    def upnp_Browse(self, *args, **kwargs):
        try:
            ObjectID = kwargs['ObjectID']
        except:
            self.debug("hmm, a Browse action and no ObjectID argument? An XBox maybe?")
            try:
                ObjectID = kwargs['ContainerID']
            except:
                ObjectID = 0
        BrowseFlag = kwargs['BrowseFlag']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        parent_container = None
        requested_id = None

        item = None
        total = 0
        items = []


        if BrowseFlag == 'BrowseDirectChildren':
            parent_container = str(ObjectID)
        else:
            requested_id = str(ObjectID)

        self.info("upnp_Browse request %r %r %r %r", ObjectID, BrowseFlag, StartingIndex, RequestedCount)

        didl = DIDLElement(upnp_client=kwargs.get('X_UPnPClient', ''),
                           requested_id=requested_id,
                           parent_container=parent_container,
                           transcoding=self.transcoding)

        def got_error(r):
            return r

        def process_result(result, total=None, found_item=None):
            if result == None:
                result = []
            if BrowseFlag == 'BrowseDirectChildren':
                l = []

                def process_items(result, tm):
                    if result == None:
                        result = []
                    for i in result:
                        if i[0] == True:
                            didl.addItem(i[1])

                    return build_response(tm)

                for i in result:
                    d = defer.maybeDeferred(i.get_item)
                    l.append(d)

                if found_item != None:
                    def got_child_count(count):
                        dl = defer.DeferredList(l)
                        dl.addCallback(process_items, count)
                        return dl

                    d = defer.maybeDeferred(found_item.get_child_count)
                    d.addCallback(got_child_count)

                    return d
                elif total == None:
                    total = item.get_child_count()

                dl = defer.DeferredList(l)
                dl.addCallback(process_items, total)
                return dl
            else:
                didl.addItem(result)
                total = 1

            return build_response(total)

        def build_response(tm):
          r = {'Result': didl.toString(),
               'TotalMatches': tm,
               'NumberReturned': didl.numItems()}

          if hasattr(item, 'update_id'):
            r['UpdateID'] = item.update_id
          elif hasattr(self.backend, 'update_id'):
            r['UpdateID'] = self.backend.update_id  # FIXME
          else:
            r['UpdateID'] = 0

          return r

        def proceed(result):
            if BrowseFlag == 'BrowseDirectChildren':
                d = defer.maybeDeferred(result.get_children, StartingIndex, StartingIndex + RequestedCount)
            else:
                d = defer.maybeDeferred(result.get_item)

            d.addCallback(process_result, found_item=result)
            d.addErrback(got_error)
            return d

        root_id = ObjectID

        wmc_mapping = getattr(self.backend, "wmc_mapping", None)
        if kwargs.get('X_UPnPClient', '') == 'XBox' and \
                wmc_mapping is not None and wmc_mapping.has_key(ObjectID):
            """ fake a Windows Media Connect Server
            """
            root_id = wmc_mapping[ObjectID]
            if callable(root_id):
                item = root_id()
                if item is not None:
                    if isinstance(item, list):
                        total = len(item)
                        if int(RequestedCount) == 0:
                            items = item[StartingIndex:]
                        else:
                            items = item[StartingIndex:StartingIndex + RequestedCount]
                        return process_result(items, total=total)
                    else:
                        if isinstance(item, defer.Deferred):
                            item.addCallback(proceed)
                            return item
                        else:
                            return proceed(item)

            item = self.backend.get_by_id(root_id)
            if item is None:
                return process_result([], total=0)

            if isinstance(item, defer.Deferred):
                item.addCallback(proceed)
                return item
            else:
                return proceed(item)

        item = self.backend.get_by_id(root_id)
        if item is None:
            return failure.Failure(errorCode(701))

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
Exemple #38
0
    def upnp_XBrowse(self, *args, **kwargs):
        try:
            ObjectID = kwargs['ObjectID']
        except:
            self.debug(
                "hmm, a Browse action and no ObjectID argument? An XBox maybe?"
            )
            try:
                ObjectID = kwargs['ContainerID']
            except:
                ObjectID = 0
        BrowseFlag = kwargs['BrowseFlag']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        parent_container = None
        requested_id = None

        if BrowseFlag == 'BrowseDirectChildren':
            parent_container = str(ObjectID)
        else:
            requested_id = str(ObjectID)

        self.info("upnp_Browse request %r %r %r %r", ObjectID, BrowseFlag,
                  StartingIndex, RequestedCount)

        didl = DIDLLite.DIDLElement(upnp_client=kwargs.get('X_UPnPClient', ''),
                                    requested_id=requested_id,
                                    parent_container=parent_container)

        def build_response(tm):
            num_ret = didl.numItems()
            #if int(kwargs['RequestedCount']) != 0 and num_ret != int(kwargs['RequestedCount']):
            #    num_ret = 0
            #if RequestedCount == 0 and tm-StartingIndex != num_ret:
            #    num_ret = 0
            r = {
                'Result': didl.toString(),
                'TotalMatches': tm,
                'NumberReturned': num_ret
            }

            self.info("upnp_Browse response %r %r", num_ret, tm)

            if hasattr(item, 'update_id'):
                r['UpdateID'] = item.update_id
            elif hasattr(self, 'update_id'):
                r['UpdateID'] = self.update_id  # FIXME
            else:
                r['UpdateID'] = 0

            return r

        total = 0
        items = []

        wmc_mapping = getattr(self, "wmc_mapping", None)
        if (kwargs.get('X_UPnPClient', '') == 'XBox' and wmc_mapping != None
                and ObjectID in wmc_mapping):
            """ fake a Windows Media Connect Server
            """
            root_id = wmc_mapping[ObjectID]
            if isinstance(root_id, collections.Callable):
                item = root_id()
                if item is not None:
                    if isinstance(item, list):
                        total = len(item)
                        if int(RequestedCount) == 0:
                            items = item[StartingIndex:]
                        else:
                            items = item[StartingIndex:StartingIndex +
                                         RequestedCount]
                    else:
                        d = defer.maybeDeferred(item.get_children,
                                                StartingIndex,
                                                StartingIndex + RequestedCount)
                        d.addCallback(process_result)
                        d.addErrback(got_error)
                        return d

            for i in items:
                didl.addItem(i.get_item())

            return build_response(total)

        root_id = ObjectID

        item = self.get_by_id(root_id)
        if item is None:
            return failure.Failure(errorCode(701))

        def got_error(r):
            return r

        def process_result(result, found_item):
            if result is None:
                result = []
            if BrowseFlag == 'BrowseDirectChildren':
                l = []

                def process_items(result, tm):
                    if result == None:
                        result = []
                    for i in result:
                        if i[0] == True:
                            didl.addItem(i[1])

                    return build_response(tm)

                for i in result:
                    d = defer.maybeDeferred(i.get_item)
                    l.append(d)

                def got_child_count(count):
                    dl = defer.DeferredList(l)
                    dl.addCallback(process_items, count)
                    return dl

                d = defer.maybeDeferred(found_item.get_child_count)
                d.addCallback(got_child_count)

                return d

            else:
                didl.addItem(result)
                total = 1

            return build_response(total)

        def proceed(result):
            if BrowseFlag == 'BrowseDirectChildren':
                d = defer.maybeDeferred(result.get_children, StartingIndex,
                                        StartingIndex + RequestedCount)
            else:
                d = defer.maybeDeferred(result.get_item)

            d.addCallback(process_result, result)
            d.addErrback(got_error)
            return d

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
Exemple #39
0
 def gotError(error, url):
     self.warning("error requesting %s", url)
     self.info(error)
     return failure.Failure(errorCode(718))
 def handle_error(r):
     return failure.Failure(errorCode(714))
Exemple #41
0
	def upnp_Search(self, *args, **kwargs):
		self.init_cover_root()
		Log.d("%s" % (kwargs,))
		ContainerID = kwargs['ContainerID']
		StartingIndex = int(kwargs['StartingIndex'])
		RequestedCount = int(kwargs['RequestedCount'])
		SearchCriteria = kwargs['SearchCriteria']

		total = 0
		root_id = 0
		item = None
		items = []
		parent_container = None
		SearchCriteria = SearchCriteria.split(" ")
		if "derivedfrom" in SearchCriteria:
			if SearchCriteria[0] == "upnp:class":
				Log.d("Searching by class! %s" % (SearchCriteria,))
				if SearchCriteria[2].find(DIDLLite.AudioItem.upnp_class) >= 0:
					parent_container = str(self._audio_all_id)
				elif SearchCriteria[2].find(DIDLLite.VideoItem.upnp_class) >= 0:
					parent_container = str(self._video_all_id)
				Log.d(parent_container)
		if not parent_container:
			parent_container = str(ContainerID)
		didl = DIDLLite.DIDLElement(upnp_client=kwargs.get('X_UPnPClient', ''),
			parent_container=parent_container,
			transcoding=self.server.content_directory_server.transcoding)

		def build_response(tm):
			r = {'Result': didl.toString(), 'TotalMatches': tm,
				 'NumberReturned': didl.numItems()}

			if hasattr(item, 'update_id'):
				r['UpdateID'] = item.update_id
			elif hasattr(self, 'update_id'):
				r['UpdateID'] = self.update_id # FIXME
			else:
				r['UpdateID'] = 0

			return r

		def got_error(r):
			return r

		def process_result(result, total=None, found_item=None):
			if result == None:
				result = []

			l = []

			def process_items(result, tm):
				if result == None:
					result = []
				for i in result:
					if i[0] == True:
						didl.addItem(i[1])

				return build_response(tm)

			for i in result:
				d = defer.maybeDeferred(i.get_item)
				l.append(d)

			if found_item != None:
				def got_child_count(count):
					dl = defer.DeferredList(l)
					dl.addCallback(process_items, count)
					return dl

				d = defer.maybeDeferred(found_item.get_child_count)
				d.addCallback(got_child_count)

				return d
			elif total == None:
				total = item.get_child_count()

			dl = defer.DeferredList(l)
			dl.addCallback(process_items, total)
			return dl

		def proceed(result):
			if kwargs.get('X_UPnPClient', '') == 'XBox' and hasattr(result, 'get_artist_all_tracks'):
				d = defer.maybeDeferred(result.get_artist_all_tracks, StartingIndex, StartingIndex + RequestedCount)
			else:
				d = defer.maybeDeferred(result.get_children, StartingIndex, StartingIndex + RequestedCount)
			d.addCallback(process_result, found_item=result)
			d.addErrback(got_error)
			return d

		try:
			root_id = parent_container
		except:
			pass

		wmc_mapping = getattr(self, "wmc_mapping", None)
		if kwargs.get('X_UPnPClient', '') == 'XBox':
			if wmc_mapping and wmc_mapping.has_key(parent_container):
				""" fake a Windows Media Connect Server
				"""
				root_id = wmc_mapping[parent_container]
				if callable(root_id):
					item = root_id()
					if item is not None:
						if isinstance(item, list):
							total = len(item)
							if int(RequestedCount) == 0:
								items = item[StartingIndex:]
							else:
								items = item[StartingIndex:StartingIndex + RequestedCount]
							return process_result(items, total=total)
						else:
							if isinstance(item, defer.Deferred):
								item.addCallback(proceed)
								return item
							else:
								return proceed(item)

				item = self.get_by_id(root_id)
				if item == None:
					return process_result([], total=0)

				if isinstance(item, defer.Deferred):
					item.addCallback(proceed)
					return item
				else:
					return proceed(item)


		item = self.get_by_id(root_id)
		Log.w(item)
		if item == None:
			Log.w(701)
			return failure.Failure(errorCode(701))

		if isinstance(item, defer.Deferred):
			item.addCallback(proceed)
			return item
		else:
			return proceed(item)
 def gotError(error, url):
     self.warning("error requesting", url)
     self.info(error)
     os.unlink(tmp_path)
     return failure.Failure(errorCode(718))
Exemple #43
0
 def handle_success(deleted):
     print('deleted', deleted, kwargs['ObjectID'])
     if not deleted:
         return failure.Failure(errorCode(715))
     return {}
    def upnp_Search(self, *args, **kwargs):
        ContainerID = kwargs['ContainerID']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        SearchCriteria = kwargs['SearchCriteria']

        total = 0
        root_id = 0
        item = None
        items = []

        parent_container = str(ContainerID)

        didl = DIDLElement(upnp_client=kwargs.get('X_UPnPClient', ''),
                           parent_container=parent_container,
                           transcoding=self.transcoding)

        def build_response(tm):
            r = {
                'Result': didl.toString(),
                'TotalMatches': tm,
                'NumberReturned': didl.numItems()
            }

            if hasattr(item, 'update_id'):
                r['UpdateID'] = item.update_id
            elif hasattr(self.backend, 'update_id'):
                r['UpdateID'] = self.backend.update_id  # FIXME
            else:
                r['UpdateID'] = 0

            return r

        def got_error(r):
            return r

        def process_result(result, total=None, found_item=None):
            if result == None:
                result = []

            l = []

            def process_items(result, tm):
                if result == None:
                    result = []
                for i in result:
                    if i[0] == True:
                        didl.addItem(i[1])

                return build_response(tm)

            for i in result:
                d = defer.maybeDeferred(i.get_item)
                l.append(d)

            if found_item != None:

                def got_child_count(count):
                    dl = defer.DeferredList(l)
                    dl.addCallback(process_items, count)
                    return dl

                d = defer.maybeDeferred(found_item.get_child_count)
                d.addCallback(got_child_count)

                return d
            elif total == None:
                total = item.get_child_count()

            dl = defer.DeferredList(l)
            dl.addCallback(process_items, total)
            return dl

        def proceed(result):
            if (kwargs.get('X_UPnPClient', '') == 'XBox'
                    and hasattr(result, 'get_artist_all_tracks')):
                d = defer.maybeDeferred(result.get_artist_all_tracks,
                                        StartingIndex,
                                        StartingIndex + RequestedCount)
            else:
                d = defer.maybeDeferred(result.get_children, StartingIndex,
                                        StartingIndex + RequestedCount)
            d.addCallback(process_result, found_item=result)
            d.addErrback(got_error)
            return d

        try:
            root_id = ContainerID
        except:
            pass

        wmc_mapping = getattr(self.backend, "wmc_mapping", None)
        if kwargs.get('X_UPnPClient', '') == 'XBox':
            if (wmc_mapping != None and wmc_mapping.has_key(ContainerID)):
                """ fake a Windows Media Connect Server
                """
                root_id = wmc_mapping[ContainerID]
                if callable(root_id):
                    item = root_id()
                    if item is not None:
                        if isinstance(item, list):
                            total = len(item)
                            if int(RequestedCount) == 0:
                                items = item[StartingIndex:]
                            else:
                                items = item[StartingIndex:StartingIndex +
                                             RequestedCount]
                            return process_result(items, total=total)
                        else:
                            if isinstance(item, defer.Deferred):
                                item.addCallback(proceed)
                                return item
                            else:
                                return proceed(item)

                item = self.backend.get_by_id(root_id)
                if item == None:
                    return process_result([], total=0)

                if isinstance(item, defer.Deferred):
                    item.addCallback(proceed)
                    return item
                else:
                    return proceed(item)

        item = self.backend.get_by_id(root_id)
        if item == None:
            return failure.Failure(errorCode(701))

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
Exemple #45
0
 def handle_error(error):
     return failure.Failure(errorCode(701))
Exemple #46
0
    def upnp_Search(self, *args, **kwargs):
        self.init_cover_root()
        Log.d("%s" % (kwargs, ))
        ContainerID = kwargs['ContainerID']
        Filter = kwargs['Filter']
        StartingIndex = int(kwargs['StartingIndex'])
        RequestedCount = int(kwargs['RequestedCount'])
        SortCriteria = kwargs['SortCriteria']
        SearchCriteria = kwargs['SearchCriteria']

        total = 0
        root_id = 0
        item = None
        items = []
        parent_container = None
        SearchCriteria = SearchCriteria.split(" ")
        if "derivedfrom" in SearchCriteria:
            if SearchCriteria[0] == "upnp:class":
                Log.d("Searching by class! %s" % (SearchCriteria, ))
                if SearchCriteria[2].find(DIDLLite.AudioItem.upnp_class) >= 0:
                    parent_container = str(self._audio_all_id)
                elif SearchCriteria[2].find(
                        DIDLLite.VideoItem.upnp_class) >= 0:
                    parent_container = str(self._video_all_id)
                Log.d(parent_container)
        if not parent_container:
            parent_container = str(ContainerID)
        didl = DIDLLite.DIDLElement(
            upnp_client=kwargs.get('X_UPnPClient', ''),
            parent_container=parent_container,
            transcoding=self.server.content_directory_server.transcoding)

        def build_response(tm):
            r = {
                'Result': didl.toString(),
                'TotalMatches': tm,
                'NumberReturned': didl.numItems()
            }

            if hasattr(item, 'update_id'):
                r['UpdateID'] = item.update_id
            elif hasattr(self, 'update_id'):
                r['UpdateID'] = self.update_id  # FIXME
            else:
                r['UpdateID'] = 0

            return r

        def got_error(r):
            return r

        def process_result(result, total=None, found_item=None):
            if result == None:
                result = []

            l = []

            def process_items(result, tm):
                if result == None:
                    result = []
                for i in result:
                    if i[0] == True:
                        didl.addItem(i[1])

                return build_response(tm)

            for i in result:
                d = defer.maybeDeferred(i.get_item)
                l.append(d)

            if found_item != None:

                def got_child_count(count):
                    dl = defer.DeferredList(l)
                    dl.addCallback(process_items, count)
                    return dl

                d = defer.maybeDeferred(found_item.get_child_count)
                d.addCallback(got_child_count)

                return d
            elif total == None:
                total = item.get_child_count()

            dl = defer.DeferredList(l)
            dl.addCallback(process_items, total)
            return dl

        def proceed(result):
            if kwargs.get('X_UPnPClient', '') == 'XBox' and hasattr(
                    result, 'get_artist_all_tracks'):
                d = defer.maybeDeferred(result.get_artist_all_tracks,
                                        StartingIndex,
                                        StartingIndex + RequestedCount)
            else:
                d = defer.maybeDeferred(result.get_children, StartingIndex,
                                        StartingIndex + RequestedCount)
            d.addCallback(process_result, found_item=result)
            d.addErrback(got_error)
            return d

        try:
            root_id = parent_container
        except:
            pass

        wmc_mapping = getattr(self, "wmc_mapping", None)
        if kwargs.get('X_UPnPClient', '') == 'XBox':
            if wmc_mapping and wmc_mapping.has_key(parent_container):
                """ fake a Windows Media Connect Server
				"""
                root_id = wmc_mapping[parent_container]
                if callable(root_id):
                    item = root_id()
                    if item is not None:
                        if isinstance(item, list):
                            total = len(item)
                            if int(RequestedCount) == 0:
                                items = item[StartingIndex:]
                            else:
                                items = item[StartingIndex:StartingIndex +
                                             RequestedCount]
                            return process_result(items, total=total)
                        else:
                            if isinstance(item, defer.Deferred):
                                item.addCallback(proceed)
                                return item
                            else:
                                return proceed(item)

                item = self.get_by_id(root_id)
                if item == None:
                    return process_result([], total=0)

                if isinstance(item, defer.Deferred):
                    item.addCallback(proceed)
                    return item
                else:
                    return proceed(item)

        item = self.get_by_id(root_id)
        Log.w(item)
        if item == None:
            Log.w(701)
            return failure.Failure(errorCode(701))

        if isinstance(item, defer.Deferred):
            item.addCallback(proceed)
            return item
        else:
            return proceed(item)
    def upnp_CreateObject(self, *args, **kwargs):
        if kwargs['ContainerID'] == 'DLNA.ORG_AnyContainer':
            """ for the moment """
            return failure.Failure(errorCode(712))
        else:
            ContainerID = kwargs['ContainerID']
        Elements = kwargs['Elements']

        parent_item = self.get_by_id(ContainerID)
        if parent_item == None:
            return failure.Failure(errorCode(710))
        if parent_item.item.restricted:
            return failure.Failure(errorCode(713))

        if len(Elements) == 0:
            return failure.Failure(errorCode(712))

        elt = DIDLElement.fromString(Elements)
        if elt.numItems() != 1:
            return failure.Failure(errorCode(712))

        item = elt.getItems()[0]
        if(item.id != '' or
           int(item.parentID) != ContainerID or
           item.restricted == True or
           item.title == ''):
            return failure.Failure(errorCode(712))

        if('..' in item.title or
           '~' in item.title or
           os.sep in item.title):
            return failure.Failure(errorCode(712))

        if item.upnp_class == 'object.container.storageFolder':
            if len(item.res) != 0:
                return failure.Failure(errorCode(712))
            path = os.path.join(parent_item.get_path(),item.title)
            id = self.create('directory',path,parent_item)
            try:
                os.mkdir(path)
            except:
                self.remove(id)
                return failure.Failure(errorCode(712))

            if self.inotify is not None:
                mask = IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_CHANGED
                self.inotify.watch(path, mask=mask, auto_add=False, callbacks=(self.notify,id))

            new_item = self.get_by_id(id)
            didl = DIDLElement()
            didl.addItem(new_item.item)
            return {'ObjectID': id, 'Result': didl.toString()}

        if item.upnp_class.startswith('object.item.'):
            #path = os.path.join(parent_item.get_path(),item.title)
            id = self.create('item',None,parent_item)

            new_item = self.get_by_id(id)
            for res in new_item.item.res:
                res.importUri = new_item.url+'?import'
                res.data = None
            didl = DIDLElement()
            didl.addItem(new_item.item)
            return {'ObjectID': id, 'Result': didl.toString()}

        return failure.Failure(errorCode(712))
	def playcontainer_browse(self, uri):
		"""
		dlna-playcontainer://uuid%3Afe814e3e-5214-4c24-847b-383fb599ff01?sid=urn%3Aupnp-org%3AserviceId%3AContentDirectory&cid=1441&fid=1444&fii=0&sc=&md=0
		"""
		from urllib import unquote
		from cgi import parse_qs
		from coherence.extern.et import ET
		from coherence.upnp.core.utils import parse_xml

		def handle_reply(r, uri, action, kw):
			try:
				next_track = ()
				elt = DIDLLite.DIDLElement.fromString(r['Result'])
				item = elt.getItems()[0]
				local_protocol_infos = self.server.connection_manager_server.get_variable('SinkProtocolInfo').value.split(',')
				res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
				if len(res) == 0:
					res = item.res.get_matching(local_protocol_infos)
				if len(res) > 0:
					res = res[0]
					remote_protocol, remote_network, remote_content_format, _ = res.protocolInfo.split(':')
					didl = DIDLLite.DIDLElement()
					didl.addItem(item)
					next_track = (res.data, didl.toString(), remote_content_format)
				""" a list with these elements:

					the current track index
					- will change during playback of the container items
					the initial complete playcontainer-uri
					a list of all the items in the playcontainer
					the action methods to do the Browse call on the device
					the kwargs for the Browse call
					- kwargs['StartingIndex'] will be modified during further Browse requests
				"""
				self.playcontainer = [int(kw['StartingIndex']), uri, elt.getItems()[:], action, kw]

				def browse_more(starting_index, number_returned, total_matches):
					self.info("browse_more", starting_index, number_returned, total_matches)
					try:

						def handle_error(r):
							pass

						def handle_reply(r, starting_index):
							elt = DIDLLite.DIDLElement.fromString(r['Result'])
							self.playcontainer[2] += elt.getItems()[:]
							browse_more(starting_index, int(r['NumberReturned']), int(r['TotalMatches']))

						if((number_returned != 5 or
							number_returned < (total_matches - starting_index)) and
							(total_matches - number_returned) != starting_index):
							self.info("seems we have been returned only a part of the result")
							self.info("requested %d, starting at %d" % (5, starting_index))
							self.info("got %d out of %d" % (number_returned, total_matches))
							self.info("requesting more starting now at %d" % (starting_index + number_returned))
							self.playcontainer[4]['StartingIndex'] = str(starting_index + number_returned)
							d = self.playcontainer[3].call(**self.playcontainer[4])
							d.addCallback(handle_reply, starting_index + number_returned)
							d.addErrback(handle_error)
					except:
						import traceback
						traceback.print_exc()

				browse_more(int(kw['StartingIndex']), int(r['NumberReturned']), int(r['TotalMatches']))

				if len(next_track) == 3:
					return next_track
			except:
				import traceback
				traceback.print_exc()

			return failure.Failure(errorCode(714))

		def handle_error(r):
			return failure.Failure(errorCode(714))

		try:
			udn, args = uri[21:].split('?')
			udn = unquote(udn)
			args = parse_qs(args)

			type = args['sid'][0].split(':')[-1]

			try:
				sc = args['sc'][0]
			except:
				sc = ''

			device = self.server.coherence.get_device_with_id(udn)
			service = device.get_service_by_type(type)
			action = service.get_action('Browse')

			kw = {'ObjectID':args['cid'][0],
					'BrowseFlag':'BrowseDirectChildren',
					'StartingIndex':args['fii'][0],
					'RequestedCount':str(5),
					'Filter':'*',
					'SortCriteria':sc}

			d = action.call(**kw)
			d.addCallback(handle_reply, uri, action, kw)
			d.addErrback(handle_error)
			return d
		except:
			return failure.Failure(errorCode(714))
		def handle_error(r):
			return failure.Failure(errorCode(714))