changeset 125:efdc038e757a

fixed participant.changeNickname(), renamed IRC.server() to IRC.open_connection(), created IRC.get_connection() and IRC.has_connection(), removed irclib.SimpleIRCClient (we don't need it) Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Wed, 13 Jan 2010 22:28:09 +0100
parents 99f3dee1fad7
children eb65b875be0a
files bridge.py irclib.py participant.py
diffstat 3 files changed, 85 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- a/bridge.py
+++ b/bridge.py
@@ -76,7 +76,7 @@ class Bridge:
 		# Join IRC room
 		try:
 			self.irc_connections_limit = -1
-			self.irc_connection = self.bot.irc.server(self.irc_server, self.irc_port, self.bot.nickname)
+			self.irc_connection = self.bot.irc.open_connection(self.irc_server, self.irc_port, self.bot.nickname)
 			self.irc_connection.connect(nick_callback=self._irc_nick_callback)
 		except:
 			self.bot.error('[Error] joining IRC room failed')
--- a/irclib.py
+++ b/irclib.py
@@ -116,8 +116,8 @@ class IRC:
     Here is an example:
 
         irc = irclib.IRC()
-        server = irc.server()
-        server.connect(\"irc.some.where\", 6667, \"my_nickname\")
+        server = irc.open_connection(\"irc.some.where\", 6667, \"my_nickname\")
+        server.connect()
         server.privmsg(\"a_nickname\", \"Hi there!\")
         irc.process_forever()
 
@@ -166,7 +166,18 @@ class IRC:
 
         self.add_global_handler("ping", _ping_ponger, -42)
 
-    def server(self, server, port, nickname):
+    def get_connection(self, server, port, nickname):
+        for c in self.connections:
+            if c.server == server and c.port == port and c.real_nickname == nickname:
+                return c
+        return None
+
+    def has_connection(self, server, port, nickname):
+        if self.get_connection(server, port, nickname):
+            return True
+        return False
+
+    def open_connection(self, server, port, nickname):
         """Creates or returns an existing ServerConnection object for nickname at server:port.
 
             server -- Server name.
@@ -175,9 +186,9 @@ class IRC:
 
             nickname -- The nickname."""
 
-        for c in self.connections:
-            if c.server == server and c.port == port and c.real_nickname == nickname:
-                return c
+        c = self.get_connection(server, port, nickname)
+        if c:
+            return c
         c = ServerConnection(self, server, port, nickname)
         self.connections.append(c)
         return c
@@ -1114,105 +1125,6 @@ class DCCConnection(Connection):
             # Ouch!
             self.disconnect("Connection reset by peer.")
 
-class SimpleIRCClient:
-    """A simple single-server IRC client class.
-
-    This is an example of an object-oriented wrapper of the IRC
-    framework.  A real IRC client can be made by subclassing this
-    class and adding appropriate methods.
-
-    The method on_join will be called when a "join" event is created
-    (which is done when the server sends a JOIN messsage/command),
-    on_privmsg will be called for "privmsg" events, and so on.  The
-    handler methods get two arguments: the connection object (same as
-    self.connection) and the event object.
-
-    Instance attributes that can be used by sub classes:
-
-        ircobj -- The IRC instance.
-
-        connection -- The ServerConnection instance.
-
-        dcc_connections -- A list of DCCConnection instances.
-    """
-    def __init__(self):
-        self.ircobj = IRC()
-        self.connection = self.ircobj.server()
-        self.dcc_connections = []
-        self.ircobj.add_global_handler("all_events", self._dispatcher, -10)
-        self.ircobj.add_global_handler("dcc_disconnect", self._dcc_disconnect, -10)
-
-    def _dispatcher(self, c, e):
-        """[Internal]"""
-        m = "on_" + e.eventtype()
-        if hasattr(self, m):
-            getattr(self, m)(c, e)
-
-    def _dcc_disconnect(self, c, e):
-        self.dcc_connections.remove(c)
-
-    def connect(self, server, port, nickname, password=None, username=None,
-                ircname=None, localaddress="", localport=0, ssl=False, ipv6=False):
-        """Connect/reconnect to a server.
-
-        Arguments:
-
-            server -- Server name.
-
-            port -- Port number.
-
-            nickname -- The nickname.
-
-            password -- Password (if any).
-
-            username -- The username.
-
-            ircname -- The IRC name.
-
-            localaddress -- Bind the connection to a specific local IP address.
-
-            localport -- Bind the connection to a specific local port.
-
-            ssl -- Enable support for ssl.
-
-            ipv6 -- Enable support for ipv6.
-
-        This function can be called to reconnect a closed connection.
-        """
-        self.connection.connect(server, port, nickname,
-                                password, username, ircname,
-                                localaddress, localport, ssl, ipv6)
-
-    def dcc_connect(self, address, port, dcctype="chat"):
-        """Connect to a DCC peer.
-
-        Arguments:
-
-            address -- IP address of the peer.
-
-            port -- Port to connect to.
-
-        Returns a DCCConnection instance.
-        """
-        dcc = self.ircobj.dcc(dcctype)
-        self.dcc_connections.append(dcc)
-        dcc.connect(address, port)
-        return dcc
-
-    def dcc_listen(self, dcctype="chat"):
-        """Listen for connections from a DCC peer.
-
-        Returns a DCCConnection instance.
-        """
-        dcc = self.ircobj.dcc(dcctype)
-        self.dcc_connections.append(dcc)
-        dcc.listen()
-        return dcc
-
-    def start(self):
-        """Start the IRC client."""
-        self.ircobj.process_forever()
-
 
 class Event:
     """Class representing an IRC event."""
--- a/participant.py
+++ b/participant.py
@@ -109,7 +109,7 @@ class Participant:
 		if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection):
 			return
 		sleep(1) # try to prevent "reconnecting too fast" shit
-		self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.duplicate_nickname)
+		self.irc_connection = self.bridge.bot.irc.open_connection(self.bridge.irc_server, self.bridge.irc_port, self.duplicate_nickname)
 		self.irc_connection.connect(nick_callback=self._irc_nick_callback)
 	
 	
@@ -195,18 +195,23 @@ class Participant:
 				self.irc_connection = 'unwanted nick change'
 			
 			else:
-				self.nickname = newnick
-				self.duplicate_nickname = newnick
-				if isinstance(self.irc_connection, ServerConnection):
-					if self.irc_connection.used_by == 1:
-						self.irc_connection.nick(newnick, callback=self._irc_nick_callback)
+				try:
+					p = self.bridge.getParticipant(newnick)
+				except self.bridge.NoSuchParticipantException:
+					self.nickname = newnick
+					self.duplicate_nickname = newnick
+					has_connection = self.bridge.bot.irc.has_connection(self.bridge.irc_server, self.bridge.irc_port, self.duplicate_nickname)
+					if isinstance(self.irc_connection, ServerConnection):
+						if not has_connection and self.irc_connection.used_by == 1:
+							self.irc_connection.nick(newnick, callback=self._irc_nick_callback)
+						else:
+							self._close_irc_connection('Changed nickname')
+							self.createDuplicateOnIRC()
 					else:
-						self._close_irc_connection('Changed nickname')
+						if self.irc_connection == 'both':
+							self.bridge.addParticipant('irc', oldnick)
 						self.createDuplicateOnIRC()
-				else:
-					if self.irc_connection == 'both':
-						self.bridge.addParticipant('irc', oldnick)
-					self.createDuplicateOnIRC()
+					return
 		
 		elif self.protocol == 'irc':
 			if on_protocol == 'irc':
@@ -214,27 +219,58 @@ class Participant:
 				self.xmpp_c = 'unwanted nick change'
 			
 			else:
-				self.nickname = newnick
-				self.duplicate_nickname = newnick
-				if isinstance(self.xmpp_c, xmpp.client.Client):
-					for b in self.bridge.bot.bridges:
-						if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server:
-							self.muc.leave(message='Changed nickname to "'+self.nickname+'"')
-							self.xmpp_c = None
-							self.bridge.bot.close_xmpp_connection(oldnick)
-							self.createDuplicateOnXMPP()
-							return
-					
-					if not self.bridge.bot.xmpp_connections.has_key(newnick):
-						if self.bridge.bot.xmpp_connections.has_key(oldnick):
-							self.bridge.bot.xmpp_connections.pop(oldnick)
-						self.bridge.bot.xmpp_connections[newnick] = self.xmpp_c
-					
-					self.muc.change_nick(newnick, status='From IRC', callback=self._xmpp_join_callback)
+				try:
+					p = self.bridge.getParticipant(newnick)
+				except self.bridge.NoSuchParticipantException:
+					self.nickname = newnick
+					self.duplicate_nickname = newnick
+					if isinstance(self.xmpp_c, xmpp.client.Client):
+						for b in self.bridge.bot.bridges:
+							if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server:
+								self.muc.leave(message='Changed nickname to "'+self.nickname+'"')
+								self.xmpp_c = None
+								self.bridge.bot.close_xmpp_connection(oldnick)
+								self.createDuplicateOnXMPP()
+								return
+						
+						if not self.bridge.bot.xmpp_connections.has_key(newnick):
+							if self.bridge.bot.xmpp_connections.has_key(oldnick):
+								self.bridge.bot.xmpp_connections.pop(oldnick)
+							self.bridge.bot.xmpp_connections[newnick] = self.xmpp_c
+						
+						self.muc.change_nick(newnick, status='From IRC', callback=self._xmpp_join_callback)
+					else:
+						if self.xmpp_c == 'both':
+							self.bridge.addParticipant('xmpp', oldnick)
+						self.createDuplicateOnXMPP()
+					return
+		
+		self.nickname = newnick
+		self.duplicate_nickname = newnick
+		if p.nickname == newnick:
+			if p.protocol == self.protocol:
+				# should never happen
+				raise Exception('WTF ?')
+			else:
+				self.set_both_sides()
+		elif p.duplicate_nickname == newnick:
+			if p.protocol != self.protocol:
+				# should never happen
+				raise Exception('WTF ?')
+			else:
+				if self.protocol == 'xmpp':
+					self.irc_connection = p.irc_connection
+					p.irc_connection = None
 				else:
-					if self.xmpp_c == 'both':
-						self.bridge.addParticipant('xmpp', oldnick)
-					self.createDuplicateOnXMPP()
+					self.xmpp_c = p.xmpp_c
+					self.muc = p.muc
+					p.xmpp_c = None
+					p.muc = None
+				p.duplicate_nickname = p._get_new_duplicate_nickname()
+				p.createDuplicateOnXMPP()
+		else:
+			# should never happen
+			raise Exception('WTF ?')
 	
 	
 	def sayOnIRC(self, message):