comparison participant.py @ 72:6c4b841144f6

Better handling of participants Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Wed, 02 Sep 2009 14:57:57 +0200
parents 7aa1f59800b0
children fa291fd20480
comparison
equal deleted inserted replaced
71:c5e4bf95f52a 72:6c4b841144f6
16 16
17 17
18 import muc 18 import muc
19 xmpp = muc.xmpp 19 xmpp = muc.xmpp
20 del muc 20 del muc
21 from irclib import ServerNotConnectedError 21 from irclib import ServerNotConnectedError, ServerConnection
22 from encoding import * 22 from encoding import *
23 from threading import Thread 23 from threading import Thread
24 from time import sleep 24 from time import sleep
25 25
26 26
39 else: 39 else:
40 raise Exception('[Internal Error] bad protocol') 40 raise Exception('[Internal Error] bad protocol')
41 41
42 42
43 def createDuplicateOnXMPP(self): 43 def createDuplicateOnXMPP(self):
44 if self.xmpp_c != None or self.irc_connection != None or self.bridge.mode == 'minimal' or self.nickname == 'ChanServ': 44 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection) or self.bridge.mode == 'minimal' or self.nickname == 'ChanServ':
45 return 45 return
46 self.xmpp_c = self.bridge.bot.get_xmpp_connection(self.nickname) 46 self.xmpp_c = self.bridge.bot.get_xmpp_connection(self.nickname)
47 self.muc = xmpp.muc(self.bridge.xmpp_room.room_jid) 47 self.muc = xmpp.muc(self.bridge.xmpp_room.room_jid)
48 self.muc.join(self.xmpp_c, self.nickname, status='From IRC', callback=self._xmpp_join_callback) 48 self.muc.join(self.xmpp_c, self.nickname, status='From IRC', callback=self._xmpp_join_callback)
49 49
56 try: 56 try:
57 raise error 57 raise error
58 except xmpp.muc.NicknameConflict: 58 except xmpp.muc.NicknameConflict:
59 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the XMPP MUC or reserved on the XMPP server of bridge "'+str(self.bridge)+'"', debug=True) 59 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the XMPP MUC or reserved on the XMPP server of bridge "'+str(self.bridge)+'"', debug=True)
60 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') 60 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible')
61 self.muc.leave('Nickname change') 61 self.muc.leave('Changed nickname to "'+self.nickname+'"')
62 self.bridge.bot.close_xmpp_connection(self.nickname) 62 self.bridge.bot.close_xmpp_connection(self.nickname)
63 self.xmpp_c = None 63 self.xmpp_c = None
64 64
65 65
66 def createDuplicateOnIRC(self): 66 def createDuplicateOnIRC(self):
67 if self.irc_connection != None or self.xmpp_c != None or self.bridge.mode != 'normal': 67 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection) or self.bridge.mode != 'normal':
68 return 68 return
69 sleep(1) # try to prevent "reconnecting too fast" shit 69 sleep(1) # try to prevent "reconnecting too fast" shit
70 self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.nickname) 70 self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.nickname)
71 self.irc_connection.connect(nick_callback=self._irc_nick_callback) 71 self.irc_connection.connect(nick_callback=self._irc_nick_callback)
72 72
77 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True) 77 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True)
78 else: 78 else:
79 if error == 'nicknameinuse': 79 if error == 'nicknameinuse':
80 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the IRC chan of bridge "'+str(self.bridge)+'"', debug=True) 80 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the IRC chan of bridge "'+str(self.bridge)+'"', debug=True)
81 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the IRC server, please avoid that if possible') 81 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the IRC server, please avoid that if possible')
82 if self.irc_connection != None: 82 if isinstance(self.irc_connection, ServerConnection):
83 self.irc_connection.close('') 83 self.irc_connection.close('')
84 self.irc_connection = None 84 self.irc_connection = 'nicknameinuse'
85 elif error == 'nickcollision': 85 elif error == 'nickcollision':
86 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used or reserved on the IRC server of bridge "'+str(self.bridge)+'"', debug=True) 86 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used or reserved on the IRC server of bridge "'+str(self.bridge)+'"', debug=True)
87 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is already used or reserved on the IRC server, please avoid that if possible') 87 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is already used or reserved on the IRC server, please avoid that if possible')
88 if self.irc_connection != None: 88 if isinstance(self.irc_connection, ServerConnection):
89 self.irc_connection.close('') 89 self.irc_connection.close('')
90 self.irc_connection = None 90 self.irc_connection = 'nickcollision'
91 elif error == 'erroneusnickname': 91 elif error == 'erroneusnickname':
92 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True) 92 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True)
93 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains unauthorized characters and cannot be used in the IRC channel, please avoid that if possible') 93 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains unauthorized characters and cannot be used in the IRC channel, please avoid that if possible')
94 if self.irc_connection != None: 94 if isinstance(self.irc_connection, ServerConnection):
95 self.irc_connection.close('') 95 self.irc_connection.close('')
96 self.irc_connection = None 96 self.irc_connection = 'erroneusnickname'
97 elif error == 'nicknametoolong': 97 elif error == 'nicknametoolong':
98 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "nicknametoolong" on bridge "'+str(self.bridge)+'"', debug=True) 98 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "nicknametoolong" on bridge "'+str(self.bridge)+'"', debug=True)
99 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is too long (limit seems to be '+str(arguments[0])+') and cannot be used in the IRC channel, please avoid that if possible') 99 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is too long (limit seems to be '+str(arguments[0])+') and cannot be used in the IRC channel, please avoid that if possible')
100 if self.irc_connection != None: 100 if isinstance(self.irc_connection, ServerConnection):
101 self.irc_connection.close('') 101 self.irc_connection.close('')
102 self.irc_connection = None 102 self.irc_connection = 'nicknametoolong'
103 103
104 104
105 def changeNickname(self, newnick, on_protocol): 105 def changeNickname(self, newnick, on_protocol):
106 """Change participant's nickname.""" 106 """Change participant's nickname."""
107 107
112 self.bridge.removeParticipant('irc', self.nickname, '') 112 self.bridge.removeParticipant('irc', self.nickname, '')
113 self.bridge.addParticipant('irc', newnick) 113 self.bridge.addParticipant('irc', newnick)
114 114
115 else: 115 else:
116 self.nickname = newnick 116 self.nickname = newnick
117 if self.irc_connection != None: 117 if isinstance(self.irc_connection, ServerConnection):
118 self.irc_connection.nick(newnick, callback=self._irc_nick_callback) 118 self.irc_connection.nick(newnick, callback=self._irc_nick_callback)
119 else: 119 else:
120 self.createDuplicateOnIRC() 120 self.createDuplicateOnIRC()
121 121
122 elif self.protocol == 'irc': 122 elif self.protocol == 'irc':
127 else: 127 else:
128 self.nickname = newnick 128 self.nickname = newnick
129 if self.muc != None: 129 if self.muc != None:
130 for b in self.bridge.bot.bridges: 130 for b in self.bridge.bot.bridges:
131 if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server: 131 if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server:
132 self.muc.leave(message='Nickname change') 132 self.muc.leave(message='Changed nickname to "'+self.nickname+'"')
133 self.xmpp_c = None 133 self.xmpp_c = None
134 self.bridge.bot.close_xmpp_connection(oldnick) 134 self.bridge.bot.close_xmpp_connection(oldnick)
135 self.createDuplicateOnXMPP() 135 self.createDuplicateOnXMPP()
136 return 136 return
137 137
138 if not self.bridge.bot.xmpp_connections.has_key(newnick): 138 if not self.bridge.bot.xmpp_connections.has_key(newnick):
139 self.bridge.bot.xmpp_connections.pop(oldnick) 139 if self.bridge.bot.xmpp_connections.has_key(oldnick):
140 self.bridge.bot.xmpp_connections.pop(oldnick)
140 self.bridge.bot.xmpp_connections[newnick] = self.xmpp_c 141 self.bridge.bot.xmpp_connections[newnick] = self.xmpp_c
141 142
142 self.muc.change_nick(newnick, status='From IRC', callback=self._xmpp_join_callback) 143 self.muc.change_nick(newnick, status='From IRC', callback=self._xmpp_join_callback)
143 else: 144 else:
144 self.createDuplicateOnXMPP() 145 self.createDuplicateOnXMPP()
145 146
146 147
147 def sayOnIRC(self, message): 148 def sayOnIRC(self, message):
148 try: 149 try:
149 if self.irc_connection != None: 150 if isinstance(self.irc_connection, ServerConnection):
150 try: 151 try:
151 self.irc_connection.privmsg(self.bridge.irc_room, message) 152 self.irc_connection.privmsg(self.bridge.irc_room, message)
152 except ServerNotConnectedError: 153 except ServerNotConnectedError:
153 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message) 154 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message)
154 elif self.xmpp_c == None: 155 elif not isinstance(self.xmpp_c, xmpp.client.Client):
155 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message) 156 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message)
156 except EncodingException: 157 except EncodingException:
157 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 158 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
158 159
159 160
160 def sayOnIRCTo(self, to, message): 161 def sayOnIRCTo(self, to, message):
161 if self.irc_connection != None: 162 if isinstance(self.irc_connection, ServerConnection):
162 try: 163 try:
163 self.irc_connection.privmsg(to, message) 164 self.irc_connection.privmsg(to, message)
164 except EncodingException: 165 except EncodingException:
165 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 166 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
166 elif self.xmpp_c == None: 167 elif not isinstance(self.xmpp_c, xmpp.client.Client):
167 if self.bridge.mode != 'normal': 168 if self.bridge.mode != 'normal':
168 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in '+self.bridge.mode+' mode.') 169 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in '+self.bridge.mode+' mode.')
169 else: 170 else:
170 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an IRC duplicate with your nickname.') 171 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an IRC duplicate with your nickname.')
171 172
172 173
173 def sayOnXMPP(self, message): 174 def sayOnXMPP(self, message):
174 try: 175 try:
175 if self.xmpp_c != None: 176 if isinstance(self.xmpp_c, xmpp.client.Client):
176 self.muc.say(auto_decode(message)) 177 self.muc.say(auto_decode(message))
177 elif self.irc_connection == None: 178 elif not isinstance(self.irc_connection, ServerConnection):
178 self.bridge.xmpp_room.say('<'+self.nickname+'> '+auto_decode(message)) 179 self.bridge.xmpp_room.say('<'+self.nickname+'> '+auto_decode(message))
179 except EncodingException: 180 except EncodingException:
180 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 181 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
181 182
182 183
183 def sayOnXMPPTo(self, to, message): 184 def sayOnXMPPTo(self, to, message):
184 try: 185 try:
185 if self.xmpp_c != None: 186 if isinstance(self.xmpp_c, xmpp.client.Client):
186 self.muc.sayTo(to, auto_decode(message)) 187 self.muc.sayTo(to, auto_decode(message))
187 elif self.irc_connection == None: 188 elif not isinstance(self.irc_connection, ServerConnection):
188 if self.bridge.mode != 'normal': 189 if self.bridge.mode != 'normal':
189 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in '+self.bridge.mode+' mode.') 190 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in '+self.bridge.mode+' mode.')
190 else: 191 else:
191 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an XMPP duplicate with your nickname.') 192 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an XMPP duplicate with your nickname.')
192 except EncodingException: 193 except EncodingException:
194 195
195 196
196 def leave(self, message): 197 def leave(self, message):
197 if message == None: 198 if message == None:
198 message = '' 199 message = ''
199 if self.xmpp_c != None: 200 if isinstance(self.xmpp_c, xmpp.client.Client):
200 self.muc.leave(auto_decode(message)) 201 self.muc.leave(auto_decode(message))
201 self.bridge.bot.close_xmpp_connection(self.nickname) 202 self.bridge.bot.close_xmpp_connection(self.nickname)
202 if self.irc_connection != None: 203 if isinstance(self.irc_connection, ServerConnection):
203 self.irc_connection.used_by -= 1 204 self.irc_connection.used_by -= 1
204 if self.irc_connection.used_by < 1: 205 if self.irc_connection.used_by < 1:
205 self.irc_connection.close(message) 206 self.irc_connection.close(message)
206 self.irc_connection = None 207 self.irc_connection = None
207 self.nickname = None 208 self.nickname = None