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_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))
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 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 != 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 == 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)
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) mimecontainers = self.backend.get_x_containers() if (len(mimecontainers)): if "object.item.imageItem" in SearchCriteria: item = self.backend.get_by_id(mimecontainers['imageItem']) elif "object.item.audioItem" in SearchCriteria: item = self.backend.get_by_id(mimecontainers['audioItem']) elif "object.item.videoItem" in SearchCriteria: item = self.backend.get_by_id(mimecontainers['videoItem']) if item == None: return failure.Failure(errorCode(708)) if isinstance(item,defer.Deferred): item.addCallback(proceed) return item else: return proceed(item)