From e9a855007b2310f53a36d607aac1dc5fe3be3c4a Mon Sep 17 00:00:00 2001
From: Dimitur Kirov <dkirov@gmail.com>
Date: Tue, 19 Sep 2006 12:46:09 +0000
Subject: [PATCH] better xmmpppy plugin integration. fixed xml error with
 iChats

---
 src/common/xmpp/dispatcher_nb.py       |   4 +-
 src/common/xmpp/simplexml.py           |   2 +-
 src/common/zeroconf/client_zeroconf.py | 134 +++++++++++++++----------
 3 files changed, 86 insertions(+), 54 deletions(-)

diff --git a/src/common/xmpp/dispatcher_nb.py b/src/common/xmpp/dispatcher_nb.py
index 7d57fdc191..ca13af1843 100644
--- a/src/common/xmpp/dispatcher_nb.py
+++ b/src/common/xmpp/dispatcher_nb.py
@@ -400,7 +400,7 @@ class Dispatcher(PlugIn):
 		''' Serialise stanza and put it on the wire. Assign an unique ID to it before send.
 			Returns assigned ID.'''
 		if type(stanza) in [type(''), type(u'')]: 
-			return self._owner.send_stanza(stanza)
+			return self._owner.Connection.send(stanza)
 		if not isinstance(stanza, Protocol): 
 			_ID=None
 		elif not stanza.getID():
@@ -423,7 +423,7 @@ class Dispatcher(PlugIn):
 			stanza=route
 		stanza.setNamespace(self._owner.Namespace)
 		stanza.setParent(self._metastream)
-		self._owner.send_stanza(stanza)
+		self._owner.Connection.send(stanza)
 		return _ID
 	
 	def disconnect(self):
diff --git a/src/common/xmpp/simplexml.py b/src/common/xmpp/simplexml.py
index 0057b472f5..76c70651f8 100644
--- a/src/common/xmpp/simplexml.py
+++ b/src/common/xmpp/simplexml.py
@@ -362,7 +362,7 @@ class NodeBuilder:
 		if self.last_is_data:
 			if self.data_buffer:
 				self.data_buffer.append(data)
-		else:
+		elif self._ptr:
 			self.data_buffer = [data]
 			self.last_is_data = 1
 	
diff --git a/src/common/zeroconf/client_zeroconf.py b/src/common/zeroconf/client_zeroconf.py
index 452d16324e..d3f534232a 100644
--- a/src/common/zeroconf/client_zeroconf.py
+++ b/src/common/zeroconf/client_zeroconf.py
@@ -1,4 +1,4 @@
-##      common/zeroconf/client_zeroconf.py
+##      common/zeroconf/client_zeroconf.py
 ##
 ## Copyright (C) 2006 Stefan Bethge <stefan@lanpartei.de>
 ## 				2006 Dimitur Kirov <dkirov@gmail.com>
@@ -14,7 +14,7 @@
 ##
 from common import gajim
 from common.xmpp.idlequeue import IdleObject
-from common.xmpp import dispatcher_nb, debug
+from common.xmpp import dispatcher_nb
 from common.xmpp.client import *
 from common.xmpp.simplexml import ustr
 from dialogs import BindPortError
@@ -58,12 +58,12 @@ class ZeroconfListener(IdleObject):
 	
 	def pollend(self):
 		''' called when we stop listening on (host, port) '''
-		self.disconnect2()
+		self.disconnect()
 	
 	def pollin(self):
 		''' accept a new incomming connection and notify queue'''
 		sock = self.accept_conn()
-		P2PConnection('', sock[0], sock[1][0], sock[1][1], self.caller)
+		P2PClient(sock[0], sock[1][0], sock[1][1], self.caller)
 	
 	def disconnect(self):
 		''' free all resources, we are not listening anymore '''
@@ -83,10 +83,59 @@ class ZeroconfListener(IdleObject):
 		return _sock
 
 
+
+class P2PClient(IdleObject):
+	def __init__(self, _sock, host, port, caller):
+		self._owner = self
+		self.Namespace = 'jabber:client'
+		self.defaultNamespace = self.Namespace
+		self._component=0
+		self._caller = caller
+		self.Server = host
+		self.DBG = 'client'
+		debug = ['always', 'nodebuilder']
+		self._DEBUG = Debug.Debug(debug)
+		self.DEBUG = self._DEBUG.Show
+		self.debug_flags = self._DEBUG.debug_flags
+		self.debug_flags.append(self.DBG)
+		self.Connection = P2PConnection('', _sock, host, port, caller)
+		self.Connection.PlugIn(self)
+		dispatcher_nb.Dispatcher().PlugIn(self)
+		
+		self.RegisterHandler('message', self._messageCB)
+	
+	def disconnected(self):
+		if self.__dict__.has_key('Dispatcher'):
+			self.Dispatcher.PlugOut()
+		if self.__dict__.has_key('P2PConnection'):
+			self.P2PConnection.PlugOut()
+		
+	def _on_receive_document_attrs(self, data):
+		if data:
+			self.Dispatcher.ProcessNonBlocking(data)
+		if not hasattr(self, 'Dispatcher') or \
+			self.Dispatcher.Stream._document_attrs is None:
+			return
+		self.onreceive(None)
+		if self.Dispatcher.Stream._document_attrs.has_key('version') and \
+			self.Dispatcher.Stream._document_attrs['version'] == '1.0':
+				#~ self.onreceive(self._on_receive_stream_features)
+				#XXX continue with TLS
+				return
+		self.onreceive(None)
+		return True
+		
+		
+	def _messageCB(self, conn, data):
+		self._caller._messageCB(self.Server, conn, data)
+		
+		
 class P2PConnection(IdleObject, PlugIn):
 	''' class for sending file to socket over socks5 '''
 	def __init__(self, sock_hash, _sock, host = None, port = None, caller = None):
+		IdleObject.__init__(self)
 		PlugIn.__init__(self)
+		self.DBG_LINE='socket'
 		self.sendqueue = []
 		self.sendbuff = None
 		self._sock = _sock
@@ -100,30 +149,27 @@ class P2PConnection(IdleObject, PlugIn):
 		self.readable = False
 		# waiting for first bytes
 		# start waiting for data
-		self.Namespace = 'jabber:client'
-		self.defaultNamespace = self.Namespace
-		self._component=0
-		self._caller = caller
-		self.Server = host
-		self.Connection = self
+		
+		
+		
+		#~ self.Connection = self
 		self._registered_name = None
-		self.DBG = 'client'
-		debug = ['always', 'nodebuilder']
-		self._DEBUG = Debug.Debug(debug)
-		self.DEBUG = self._DEBUG.Show
-		self.debug_flags = self._DEBUG.debug_flags
-		self.debug_flags.append(self.DBG)
-		self._owner = self
-		self._exported_methods=[self.send_stanza, self.disconnect2, self.pollend]	
+		
+		self._exported_methods=[self.send, self.disconnect, self.onreceive]	
 		self.on_receive = None
+		
+		
+	def plugin(self, owner):
+		self.onreceive(owner._on_receive_document_attrs)
 		gajim.idlequeue.plug_idle(self, False, True)
-		self.onreceive(self._on_receive_document_attrs)
-		dispatcher_nb.Dispatcher().PlugIn(self)
-		self.RegisterHandler('message', self._messageCB)
+		return True
 	
-		
-	def _messageCB(self, conn, data):
-		self._caller._messageCB(self.Server, conn, data)
+	def plugout(self):
+		''' Disconnect from the remote server and unregister self.disconnected method from
+			the owner's dispatcher. '''
+		self.disconnect()
+		self._owner.Connection = None
+		self._owner = None
 	
 	def onreceive(self, recv_handler):
 		if not recv_handler:
@@ -137,22 +183,9 @@ class P2PConnection(IdleObject, PlugIn):
 		if not recv_handler(None) and _tmp == self.on_receive:
 			self.on_receive = recv_handler
 	
-	def _on_receive_document_attrs(self, data):
-		if data:
-			self.Dispatcher.ProcessNonBlocking(data)
-		if not hasattr(self, 'Dispatcher') or \
-			self.Dispatcher.Stream._document_attrs is None:
-			return
-		self.onreceive(None)
-		if self.Dispatcher.Stream._document_attrs.has_key('version') and \
-			self.Dispatcher.Stream._document_attrs['version'] == '1.0':
-				#~ self.onreceive(self._on_receive_stream_features)
-				#XXX continue with TLS
-				return
-		self.onreceive(None)
-		return True
 	
-	def send_stanza(self, stanza):
+	
+	def send(self, stanza):
 		'''Append stanza to the queue of messages to be send. 
 		If supplied data is unicode string, encode it to utf-8.
 		'''
@@ -161,8 +194,8 @@ class P2PConnection(IdleObject, PlugIn):
 		r = stanza
 		if isinstance(r, unicode): 
 			r = r.encode('utf-8')
-		elif not isinstance(r, str): 
-			r = ustr(r).encode('utf-8')
+		#~ elif not isinstance(r, str): 
+			#~ r = ustr(r).encode('utf-8')
 		self.sendqueue.append(r)
 		self._plug_idle()
 		
@@ -177,11 +210,10 @@ class P2PConnection(IdleObject, PlugIn):
 			return
 		gajim.idlequeue.remove_timeout(self.fd)
 		self._do_send()
-		# self.idlequeue.plug_idle(self, False, True)
 	
 	def pollend(self):
 		self.state = -1
-		self.disconnect2()
+		self.disconnect()
 	
 	def pollin(self):
 		''' Reads all pending incoming data. Calls owner's disconnected() method if appropriate.'''
@@ -206,7 +238,7 @@ class P2PConnection(IdleObject, PlugIn):
 				# 8 EOF occurred in violation of protocol
 				self.pollend()
 			if self.state >= 0:
-				self.disconnect2()
+				self.disconnect()
 			return
 		
 		if self.state < 0:
@@ -218,7 +250,7 @@ class P2PConnection(IdleObject, PlugIn):
 		else:
 			# This should never happed, so we need the debug
 			self.DEBUG('Unhandled data received: %s' % received,'got')
-			self.disconnect2()
+			self.disconnect()
 			if self.on_connect_failure:
 				self.on_connect_failure()
 		return True
@@ -235,7 +267,7 @@ class P2PConnection(IdleObject, PlugIn):
 		if not recv_handler(None) and _tmp == self.on_receive:
 			self.on_receive = recv_handler
 	
-	def disconnect2(self):
+	def disconnect(self):
 		''' Closes the socket. '''
 		gajim.idlequeue.remove_timeout(self.fd)
 		gajim.idlequeue.unplug_idle(self.fd)
@@ -248,6 +280,7 @@ class P2PConnection(IdleObject, PlugIn):
 		self.connected = False
 		self.fd = -1
 		self.state = -1
+		self._owner.disconnected()
 
 	def _do_send(self):
 		if not self.sendbuff:
@@ -263,7 +296,7 @@ class P2PConnection(IdleObject, PlugIn):
 					if self.state < 0:
 						gajim.idlequeue.unplug_idle(self.fd)
 						self._on_send()
-						self.disconnect2()
+						self.disconnect()
 						return
 					# we are not waiting for write 
 					self._plug_idle()
@@ -273,11 +306,10 @@ class P2PConnection(IdleObject, PlugIn):
 			if e[0] == socket.SSL_ERROR_WANT_WRITE:
 				return True		
 			if self.state < 0:
-				self.disconnect2()
-				return
-			if self._on_send_failure:
-				self._on_send_failure()
+				self.disconnect()
 				return
+			self._on_send_failure()
+			return
 		return True
 	
 	def _plug_idle(self):
-- 
GitLab