Coding standards and documentation improvements in client_nb.py
This commit is contained in:
		
							parent
							
								
									5139e7c8d0
								
							
						
					
					
						commit
						40d802284e
					
				
					 1 changed files with 58 additions and 41 deletions
				
			
		|  | @ -16,10 +16,13 @@ | ||||||
| 
 | 
 | ||||||
| # $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $ | # $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $ | ||||||
| 
 | 
 | ||||||
|  | ''' | ||||||
|  | Client class establishs connection to XMPP Server and handles authentication | ||||||
|  | ''' | ||||||
| import socket | import socket | ||||||
| 
 | 
 | ||||||
| import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh | import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh | ||||||
| from client import * | from client import PlugIn | ||||||
| 
 | 
 | ||||||
| from protocol import NS_TLS | from protocol import NS_TLS | ||||||
| 
 | 
 | ||||||
|  | @ -37,10 +40,11 @@ class NonBlockingClient: | ||||||
| 	def __init__(self, domain, idlequeue, caller=None): | 	def __init__(self, domain, idlequeue, caller=None): | ||||||
| 		''' | 		''' | ||||||
| 		Caches connection data: | 		Caches connection data: | ||||||
|  | 
 | ||||||
| 		:param domain: domain - for to: attribute (from account info) | 		:param domain: domain - for to: attribute (from account info) | ||||||
| 		:param idlequeue: processing idlequeue | 		:param idlequeue: processing idlequeue | ||||||
| 		:param caller: calling object - it has to implement methods _event_dispatcher | 		:param caller: calling object - it has to implement methods  | ||||||
| 			which is called from dispatcher instance | 			_event_dispatcher which is called from dispatcher instance | ||||||
| 		''' | 		''' | ||||||
| 		self.Namespace = protocol.NS_CLIENT | 		self.Namespace = protocol.NS_CLIENT | ||||||
| 		self.defaultNamespace = self.Namespace | 		self.defaultNamespace = self.Namespace | ||||||
|  | @ -51,7 +55,8 @@ class NonBlockingClient: | ||||||
| 		self.Server = domain | 		self.Server = domain | ||||||
| 		self.xmpp_hostname = None # FQDN hostname to connect to | 		self.xmpp_hostname = None # FQDN hostname to connect to | ||||||
| 
 | 
 | ||||||
| 		# caller is who initiated this client, it is ineeded to register the EventDispatcher | 		# caller is who initiated this client, it is in needed to register | ||||||
|  | 		# the EventDispatcher | ||||||
| 		self._caller = caller | 		self._caller = caller | ||||||
| 		self._owner = self | 		self._owner = self | ||||||
| 		self._registered_name = None | 		self._registered_name = None | ||||||
|  | @ -68,10 +73,9 @@ class NonBlockingClient: | ||||||
| 
 | 
 | ||||||
| 	def disconnect(self, message=''): | 	def disconnect(self, message=''): | ||||||
| 		''' | 		''' | ||||||
| 		Called on disconnection - disconnect callback is picked based on state of the | 		Called on disconnection - disconnect callback is picked based on state | ||||||
| 		client. | 		of the client. | ||||||
| 		''' | 		''' | ||||||
| 
 |  | ||||||
| 		# to avoid recursive calls | 		# to avoid recursive calls | ||||||
| 		if self.disconnecting: return | 		if self.disconnecting: return | ||||||
| 
 | 
 | ||||||
|  | @ -102,8 +106,8 @@ class NonBlockingClient: | ||||||
| 
 | 
 | ||||||
| 		log.debug('Client disconnected..') | 		log.debug('Client disconnected..') | ||||||
| 		if connected == '': | 		if connected == '': | ||||||
| 			# if we're disconnecting before connection to XMPP sever is opened, we don't | 			# if we're disconnecting before connection to XMPP sever is opened, | ||||||
| 			# call disconnect handlers but on_connect_failure callback | 			# we don't call disconnect handlers but on_connect_failure callback | ||||||
| 			if self.proxy: | 			if self.proxy: | ||||||
| 				# with proxy, we have different failure callback | 				# with proxy, we have different failure callback | ||||||
| 				log.debug('calling on_proxy_failure cb') | 				log.debug('calling on_proxy_failure cb') | ||||||
|  | @ -114,9 +118,10 @@ class NonBlockingClient: | ||||||
| 		else: | 		else: | ||||||
| 			# we are connected to XMPP server | 			# we are connected to XMPP server | ||||||
| 			if not stream_started: | 			if not stream_started: | ||||||
| 				# if error occur before XML stream was opened, e.g. no response on init | 				# if error occur before XML stream was opened, e.g. no response on  | ||||||
| 				# request, we call the on_connect_failure callback because proper | 				# init request, we call the on_connect_failure callback because | ||||||
| 				# connection is not estabilished yet and it's not a proxy issue | 				# proper connection is not estabilished yet and it's not a proxy | ||||||
|  | 				# issue | ||||||
| 				log.debug('calling on_connect_failure cb') | 				log.debug('calling on_connect_failure cb') | ||||||
| 				self.on_connect_failure() | 				self.on_connect_failure() | ||||||
| 			else: | 			else: | ||||||
|  | @ -126,26 +131,26 @@ class NonBlockingClient: | ||||||
| 					i() | 					i() | ||||||
| 		self.disconnecting = False | 		self.disconnecting = False | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	def connect(self, on_connect, on_connect_failure, hostname=None, port=5222, | 	def connect(self, on_connect, on_connect_failure, hostname=None, port=5222, | ||||||
| 	on_proxy_failure=None, proxy=None, secure_tuple=(None, None, None)): | 	on_proxy_failure=None, proxy=None, secure_tuple=(None, None, None)): | ||||||
| 		'''  | 		'''  | ||||||
| 		Open XMPP connection (open XML streams in both directions). | 		Open XMPP connection (open XML streams in both directions). | ||||||
|  | 
 | ||||||
| 		:param on_connect: called after stream is successfully opened | 		:param on_connect: called after stream is successfully opened | ||||||
| 		:param on_connect_failure: called when error occures during connection | 		:param on_connect_failure: called when error occures during connection | ||||||
| 		:param hostname: hostname of XMPP server from SRV request   | 		:param hostname: hostname of XMPP server from SRV request   | ||||||
| 		:param port: port number of XMPP server | 		:param port: port number of XMPP server | ||||||
| 		:param on_proxy_failure: called if error occurres during TCP connection to | 		:param on_proxy_failure: called if error occurres during TCP connection to | ||||||
| 			proxy server or during proxy connecting process | 			proxy server or during proxy connecting process | ||||||
| 		:param proxy: dictionary with proxy data. It should contain at least values | 		:param proxy: dictionary with proxy data. It should contain at least | ||||||
| 		for keys 'host' and 'port' - connection details for proxy server and | 			values for keys 'host' and 'port' - connection details for proxy serve | ||||||
| 		optionally keys 'user' and 'pass' as proxy credentials | 			and optionally keys 'user' and 'pass' as proxy credentials | ||||||
| 		:param secure_tuple: tuple of (desired connection type, cacerts and mycerts) | 		:param secure_tuple: tuple of (desired connection type, cacerts, mycerts) | ||||||
| 			connection type can be 'ssl' - TLS estabilished after TCP connection, | 			connection type can be 'ssl' - TLS estabilished after TCP connection, | ||||||
| 			'tls' - TLS estabilished after negotiation with starttls, or 'plain'. | 			'tls' - TLS estabilished after negotiation with starttls, or 'plain'. | ||||||
| 			cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more details | 			cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more | ||||||
|  | 			details | ||||||
| 		''' | 		''' | ||||||
| 
 |  | ||||||
| 		self.on_connect = on_connect | 		self.on_connect = on_connect | ||||||
| 		self.on_connect_failure=on_connect_failure | 		self.on_connect_failure=on_connect_failure | ||||||
| 		self.on_proxy_failure = on_proxy_failure | 		self.on_proxy_failure = on_proxy_failure | ||||||
|  | @ -173,9 +178,9 @@ class NonBlockingClient: | ||||||
| 			# (DNS request will be done for proxy or BOSH CM hostname) | 			# (DNS request will be done for proxy or BOSH CM hostname) | ||||||
| 			tcp_host, tcp_port, proxy_user, proxy_pass = \ | 			tcp_host, tcp_port, proxy_user, proxy_pass = \ | ||||||
| 				transports_nb.get_proxy_data_from_dict(proxy) | 				transports_nb.get_proxy_data_from_dict(proxy) | ||||||
| 
 |  | ||||||
| 		 | 		 | ||||||
| 			if proxy['type'] == 'bosh': | 			if proxy['type'] == 'bosh': | ||||||
|  | 				# Setup BOSH transport | ||||||
| 				self.socket = bosh.NonBlockingBOSH( | 				self.socket = bosh.NonBlockingBOSH( | ||||||
| 					on_disconnect = self.disconnect, | 					on_disconnect = self.disconnect, | ||||||
| 					raise_event = self.raise_event, | 					raise_event = self.raise_event, | ||||||
|  | @ -187,14 +192,16 @@ class NonBlockingClient: | ||||||
| 					domain = self.Server, | 					domain = self.Server, | ||||||
| 					bosh_dict = proxy) | 					bosh_dict = proxy) | ||||||
| 				self.protocol_type = 'BOSH' | 				self.protocol_type = 'BOSH' | ||||||
| 				self.wait_for_restart_response = proxy['bosh_wait_for_restart_response'] | 				self.wait_for_restart_response = \ | ||||||
| 
 | 					proxy['bosh_wait_for_restart_response'] | ||||||
| 			else: | 			else: | ||||||
|  | 				# http proxy | ||||||
| 				proxy_dict['type'] = proxy['type'] | 				proxy_dict['type'] = proxy['type'] | ||||||
| 				proxy_dict['xmpp_server'] = (self.xmpp_hostname, self.Port) | 				proxy_dict['xmpp_server'] = (self.xmpp_hostname, self.Port) | ||||||
| 				proxy_dict['credentials'] = (proxy_user, proxy_pass) | 				proxy_dict['credentials'] = (proxy_user, proxy_pass) | ||||||
| 
 | 
 | ||||||
| 		if not proxy or proxy['type'] != 'bosh': | 		if not proxy or proxy['type'] != 'bosh': | ||||||
|  | 			# Setup ordinary TCP transport | ||||||
| 			self.socket = transports_nb.NonBlockingTCP( | 			self.socket = transports_nb.NonBlockingTCP( | ||||||
| 				on_disconnect = self.disconnect, | 				on_disconnect = self.disconnect, | ||||||
| 				raise_event = self.raise_event, | 				raise_event = self.raise_event, | ||||||
|  | @ -203,6 +210,7 @@ class NonBlockingClient: | ||||||
| 				certs = certs, | 				certs = certs, | ||||||
| 				proxy_dict = proxy_dict) | 				proxy_dict = proxy_dict) | ||||||
| 
 | 
 | ||||||
|  | 		# plug transport into client as self.Connection | ||||||
| 		self.socket.PlugIn(self) | 		self.socket.PlugIn(self) | ||||||
| 
 | 
 | ||||||
| 		self._resolve_hostname( | 		self._resolve_hostname( | ||||||
|  | @ -222,7 +230,7 @@ class NonBlockingClient: | ||||||
| 			on_success() | 			on_success() | ||||||
| 
 | 
 | ||||||
| 	def _try_next_ip(self, err_message=None): | 	def _try_next_ip(self, err_message=None): | ||||||
| 		'''iterates over IP addresses from getaddrinfo''' | 		'''Iterates over IP addresses tries to connect to it''' | ||||||
| 		if err_message: | 		if err_message: | ||||||
| 			log.debug('While looping over DNS A records: %s' % err_message) | 			log.debug('While looping over DNS A records: %s' % err_message) | ||||||
| 		if self.ip_addresses == []: | 		if self.ip_addresses == []: | ||||||
|  | @ -236,10 +244,9 @@ class NonBlockingClient: | ||||||
| 				on_connect=lambda: self._xmpp_connect(socket_type='plain'), | 				on_connect=lambda: self._xmpp_connect(socket_type='plain'), | ||||||
| 				on_connect_failure=self._try_next_ip) | 				on_connect_failure=self._try_next_ip) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	def incoming_stream_version(self): | 	def incoming_stream_version(self): | ||||||
| 		''' gets version of xml stream''' | 		''' gets version of xml stream''' | ||||||
| 		if self.Dispatcher.Stream._document_attrs.has_key('version'): | 		if 'version' in self.Dispatcher.Stream._document_attrs: | ||||||
| 			return self.Dispatcher.Stream._document_attrs['version'] | 			return self.Dispatcher.Stream._document_attrs['version'] | ||||||
| 		else: | 		else: | ||||||
| 			return None | 			return None | ||||||
|  | @ -255,19 +262,23 @@ class NonBlockingClient: | ||||||
| 		self.connected = socket_type | 		self.connected = socket_type | ||||||
| 		self._xmpp_connect_machine() | 		self._xmpp_connect_machine() | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	def _xmpp_connect_machine(self, mode=None, data=None): | 	def _xmpp_connect_machine(self, mode=None, data=None): | ||||||
| 		''' | 		''' | ||||||
| 		Finite automaton taking care of stream opening and features tag | 		Finite automaton taking care of stream opening and features tag | ||||||
| 		handling. Calls _on_stream_start when stream is started, and disconnect() | 		handling. Calls _on_stream_start when stream is started, and disconnect() | ||||||
| 		on failure. | 		on failure. | ||||||
| 		''' | 		''' | ||||||
| 		log.info('-------------xmpp_connect_machine() >> mode: %s, data: %s...' % (mode,str(data)[:20] )) | 		log.info('-------------xmpp_connect_machine() >> mode: %s, data: %s...' % | ||||||
|  | 			(mode, str(data)[:20])) | ||||||
| 
 | 
 | ||||||
| 		def on_next_receive(mode): | 		def on_next_receive(mode): | ||||||
|  | 			''' | ||||||
|  | 			Sets desired on_receive callback on transport based on the state of | ||||||
|  | 			connect_machine. | ||||||
|  | 			''' | ||||||
| 			log.info('setting %s on next receive' % mode) | 			log.info('setting %s on next receive' % mode) | ||||||
| 			if mode is None: | 			if mode is None: | ||||||
| 				self.onreceive(None) | 				self.onreceive(None) # switch to Dispatcher.ProcessNonBlocking | ||||||
| 			else: | 			else: | ||||||
| 				self.onreceive(lambda _data:self._xmpp_connect_machine(mode, _data)) | 				self.onreceive(lambda _data:self._xmpp_connect_machine(mode, _data)) | ||||||
| 
 | 
 | ||||||
|  | @ -286,7 +297,7 @@ class NonBlockingClient: | ||||||
| 			if data: | 			if data: | ||||||
| 				self.Dispatcher.ProcessNonBlocking(data) | 				self.Dispatcher.ProcessNonBlocking(data) | ||||||
| 			if not hasattr(self, 'Dispatcher') or \ | 			if not hasattr(self, 'Dispatcher') or \ | ||||||
| 				self.Dispatcher.Stream._document_attrs is None: | 			self.Dispatcher.Stream._document_attrs is None: | ||||||
| 				self._xmpp_connect_machine( | 				self._xmpp_connect_machine( | ||||||
| 					mode='FAILURE', | 					mode='FAILURE', | ||||||
| 					data='Error on stream open') | 					data='Error on stream open') | ||||||
|  | @ -320,7 +331,7 @@ class NonBlockingClient: | ||||||
| 	def _on_stream_start(self): | 	def _on_stream_start(self): | ||||||
| 		''' | 		''' | ||||||
| 		Called after XMPP stream is opened. | 		Called after XMPP stream is opened. | ||||||
| 		TLS negotiation may follow after esabilishing a stream. | 		TLS negotiation may follow when stream is established. | ||||||
| 		''' | 		''' | ||||||
| 		self.stream_started = True | 		self.stream_started = True | ||||||
| 		self.onreceive(None) | 		self.onreceive(None) | ||||||
|  | @ -358,7 +369,7 @@ class NonBlockingClient: | ||||||
| 			self.send('<starttls xmlns="%s"/>' % NS_TLS) | 			self.send('<starttls xmlns="%s"/>' % NS_TLS) | ||||||
| 		else: | 		else: | ||||||
| 			# we got <proceed> or <failure> | 			# we got <proceed> or <failure> | ||||||
| 			if tag.getNamespace() <> NS_TLS: | 			if tag.getNamespace() != NS_TLS: | ||||||
| 				self.disconnect('Unknown namespace: %s' % tag.getNamespace()) | 				self.disconnect('Unknown namespace: %s' % tag.getNamespace()) | ||||||
| 				return | 				return | ||||||
| 			tagname = tag.getName() | 			tagname = tag.getName() | ||||||
|  | @ -379,15 +390,17 @@ class NonBlockingClient: | ||||||
| 
 | 
 | ||||||
| 	def raise_event(self, event_type, data): | 	def raise_event(self, event_type, data): | ||||||
| 		''' | 		''' | ||||||
| 		raises event to connection instance - DATA_SENT and DATA_RECIVED events are | 		Raises event to connection instance. DATA_SENT and DATA_RECIVED events | ||||||
| 		used in XML console to show XMPP traffic | 		are used in XML console to show XMPP traffic | ||||||
| 		''' | 		''' | ||||||
| 		log.info('raising event from transport: :::::%s::::\n_____________\n%s\n_____________\n' % (event_type,data)) | 		log.info('raising event from transport: :::::%s::::\n_____________\n%s\n_____________\n' % (event_type,data)) | ||||||
| 		if hasattr(self, 'Dispatcher'): | 		if hasattr(self, 'Dispatcher'): | ||||||
| 			self.Dispatcher.Event('', event_type, data) | 			self.Dispatcher.Event('', event_type, data) | ||||||
| 
 | 
 | ||||||
| 	# follows code for authentication, resource bind, session and roster download | ############################################################################### | ||||||
| 	# | ### follows code for authentication, resource bind, session and roster download | ||||||
|  | ############################################################################### | ||||||
|  | 
 | ||||||
| 	def auth(self, user, password, resource = '', sasl = 1, on_auth = None): | 	def auth(self, user, password, resource = '', sasl = 1, on_auth = None): | ||||||
| 		''' | 		''' | ||||||
| 		Authenticate connnection and bind resource. If resource is not provided | 		Authenticate connnection and bind resource. If resource is not provided | ||||||
|  | @ -450,13 +463,12 @@ class NonBlockingClient: | ||||||
| 		else: | 		else: | ||||||
| 			self.on_auth(self, None) | 			self.on_auth(self, None) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	def initRoster(self): | 	def initRoster(self): | ||||||
| 		''' Plug in the roster. ''' | 		''' Plug in the roster. ''' | ||||||
| 		if not self.__dict__.has_key('NonBlockingRoster'): | 		if not self.__dict__.has_key('NonBlockingRoster'): | ||||||
| 			roster_nb.NonBlockingRoster().PlugIn(self) | 			roster_nb.NonBlockingRoster().PlugIn(self) | ||||||
| 
 | 
 | ||||||
| 	def getRoster(self, on_ready = None): | 	def getRoster(self, on_ready=None): | ||||||
| 		''' Return the Roster instance, previously plugging it in and | 		''' Return the Roster instance, previously plugging it in and | ||||||
| 			requesting roster from server if needed. ''' | 			requesting roster from server if needed. ''' | ||||||
| 		if self.__dict__.has_key('NonBlockingRoster'): | 		if self.__dict__.has_key('NonBlockingRoster'): | ||||||
|  | @ -466,10 +478,15 @@ class NonBlockingClient: | ||||||
| 	def sendPresence(self, jid=None, typ=None, requestRoster=0): | 	def sendPresence(self, jid=None, typ=None, requestRoster=0): | ||||||
| 		''' Send some specific presence state. | 		''' Send some specific presence state. | ||||||
| 			Can also request roster from server if according agrument is set.''' | 			Can also request roster from server if according agrument is set.''' | ||||||
| 		if requestRoster: roster_nb.NonBlockingRoster().PlugIn(self) | 		if requestRoster: | ||||||
|  | 			# FIXME: used somewhere? | ||||||
|  | 			roster_nb.NonBlockingRoster().PlugIn(self) | ||||||
| 		self.send(dispatcher_nb.Presence(to=jid, typ=typ)) | 		self.send(dispatcher_nb.Presence(to=jid, typ=typ)) | ||||||
| 
 | 
 | ||||||
| 	# following methods are moved from blocking client class from xmpppy: | ############################################################################### | ||||||
|  | ### following methods are moved from blocking client class of xmpppy | ||||||
|  | ############################################################################### | ||||||
|  | 
 | ||||||
| 	def RegisterDisconnectHandler(self,handler): | 	def RegisterDisconnectHandler(self,handler): | ||||||
| 		''' Register handler that will be called on disconnect.''' | 		''' Register handler that will be called on disconnect.''' | ||||||
| 		self.disconnect_handlers.append(handler) | 		self.disconnect_handlers.append(handler) | ||||||
|  | @ -493,8 +510,8 @@ class NonBlockingClient: | ||||||
| 	def get_peerhost(self): | 	def get_peerhost(self): | ||||||
| 		''' | 		''' | ||||||
| 		Gets the ip address of the account, from which is made connection to the | 		Gets the ip address of the account, from which is made connection to the | ||||||
| 		server , (e.g. IP and port of gajim's socket. We will create listening socket | 		server (e.g. IP and port of gajim's socket). | ||||||
| 		on the same ip | 		We will create listening socket on the same ip | ||||||
| 		''' | 		''' | ||||||
| 		# FIXME: tuple (ip, port) is expected (and checked for) but port num is | 		# FIXME: tuple (ip, port) is expected (and checked for) but port num is | ||||||
| 		# useless | 		# useless | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue