def subscribe(self, name, callback_function): """ Subscribe to all announcements of a named service. Whenever an announcement arrives the given callback function will be called. @type name: str @param name: The name of the service that is being subscribed to. @type callback_function: function @param callback_function: The callback function that will be called whenever a service announcement for the 'name' service arrives. This function must accept three parameters: The first parameter is the name of the provider, the second is the address of the provider, and the third is the service announced. The types of these parameters are (str, str, PresenceService). @raise PresenceException: If this function is called on an disconnected Presence instance, if the daemon does not respond, if the daemon responds with an error message, or if a socket error occurs. """ if self.__sock == None: raise PresenceException("Attempting to send command to daemon while disconnected.") try: # Send the request to the daemon. tokens = [] tokens.append(struct.pack("!B", PresenceDefines.REGISTER_CALLBACK)) service_name = ServiceName(name) tokens.append(service_name.pack()) self.__sock.send("".join(tokens)) except ValidationError, e: raise PresenceException("Invalid service name given.")
class PresenceService(object): SERVICE_NAME_SIZE = 32 SERVICE_DATA_SIZE = 200 """A Service that may be announced via the Presence daemon.""" def __init__(self, name = 'unnamed', port = 0, data = ''): """Constructor. Creates a presence service object that can be registered with the Presence daemon. @type name: string @param name: The name of the service. This must be between 1 and 32 characters. @type port: int @param port: The port that the service is listening on. This must be a number between 0 and 65535. @type data: string @param data: The (optional) service data. Currently this can at most be 184 bytes. @raise PresenceException: Raised if the input parameters are invalid. """ super(PresenceService, self).__init__() self._name = ServiceName(name) self._port = UInt16(port) self._data = ServiceData(data) def name(): #@NoSelf def fget(self): return self._name.name def fset(self, value): self._name.name = value return locals() name = property(**name()) def port(): #@NoSelf def fget(self): return self._port.value def fset(self, value): self._port.value = value return locals() port = property(**port()) def data(): #@NoSelf def fget(self): return self._data.data def fset(self, value): self._data.data = value return locals() data = property(**data()) def pack(self): """Packs the service into a string for transfer through a socket.""" return ''.join([self._name.pack(), self._port.pack(), self._data.pack()]) def unpack(self, string_repr): try: idx = self._name.unpack(string_repr) idx += self._port.unpack(string_repr[idx:]) idx += self._data.unpack(string_repr[idx:]) return idx except (UnpackingError, ValidationError), excep: raise UnpackingError('Error unpacking service description. Message was="%s"'%excep.args[0])
def unsubscribe(self, name, callback_function): """ Remove a callback function from the callback list of the named service. @type name: str @param name: The name pf ther service that the subscribtion is removed from. @type callback_function: function @param callback_function: The callback function that was attached to the subscribtion. @raise PresenceException: If this function is called on an disconnected Presence instance, if the daemon does not respond, and if the daemon responds with an error message. This exception is also raised if the subscribtion does not exist and when a socket error occurs. """ if self.__sock == None: raise PresenceException("Attempting to send command to daemon while disconnected.") # Remove the callback from __callbacks. if self.__callbacks.has_key(name): if callback_function in self.__callbacks[name]: self.__callbacks[name].remove(callback_function) else: raise PresenceException("This function is not registered to receive callbacks.") else: raise PresenceException("Unknown service name. No callback handler exists.") # If no more callback handlers exists for the given service we unsubscribe at # the daemon now. if len(self.__callbacks[name]) == 0: self.__callbacks.pop(name) try: # Send the request to the daemon. tokens = [] tokens.append(struct.pack("!B", PresenceDefines.REMOVE_CALLBACK)) service_name = ServiceName(name) tokens.append(service_name.pack()) self.__sock.send("".join(tokens)) except ValidationError, e: raise PresenceException("Invalid service name given.") except Exception, e: # Error sending request to daemon. Close the connection. logging.getLogger("presence").info("Error sending command to daemon. Exception was:", exc_info=True) self.__close_connection() raise PresenceException("Error sending request. Connection has been closed.", e)
def remove_service(self, name): """ Remove a service announcement from the Presence daemon. This means that the named service will no longer be announced. @type name: str @param name: The name of the service that is to be removed. @raise PresenceException: If this function is called on an disconnected Presence instance, if the daemon does not respond, if the daemon responds with an error message, or if a socket error occurs. """ if self.__sock == None: raise PresenceException("Attempting to send command to daemon while disconnected.") # Send the request to the daemon. try: tokens = [] tokens.append(struct.pack("!B", PresenceDefines.REMOVE_SERVICE)) service_name = ServiceName(name) tokens.append(service_name.pack()) self.__sock.send("".join(tokens)) except ValidationError, e: raise PresenceException("Invalid service name given.")
def __init__(self, name = 'unnamed', port = 0, data = ''): """Constructor. Creates a presence service object that can be registered with the Presence daemon. @type name: string @param name: The name of the service. This must be between 1 and 32 characters. @type port: int @param port: The port that the service is listening on. This must be a number between 0 and 65535. @type data: string @param data: The (optional) service data. Currently this can at most be 184 bytes. @raise PresenceException: Raised if the input parameters are invalid. """ super(PresenceService, self).__init__() self._name = ServiceName(name) self._port = UInt16(port) self._data = ServiceData(data)