Mercurial > xib
comparison bridge.py @ 118:b29fd5696a78
new mode bypass and new method bridge.changeMode
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sat, 28 Nov 2009 23:47:11 +0100 |
parents | 0ae0f8836a7a |
children | de00bbe026a7 |
comparison
equal
deleted
inserted
replaced
117:d062efcfbe9d | 118:b29fd5696a78 |
---|---|
36 _notice = 2 | 36 _notice = 2 |
37 _warning = 3 | 37 _warning = 3 |
38 _error = 4 | 38 _error = 4 |
39 _nothing = 5 | 39 _nothing = 5 |
40 _say_levels = ['all', 'info', 'notice', 'warning', 'error', 'nothing'] | 40 _say_levels = ['all', 'info', 'notice', 'warning', 'error', 'nothing'] |
41 _modes = ['normal', 'limited', 'minimal'] | 41 _modes = ['normal', 'bypass', 'limited', 'minimal'] |
42 | 42 |
43 | 43 |
44 def __init__(self, owner_bot, xmpp_room_jid, irc_room, irc_server, mode, say_level, irc_port=6667): | 44 def __init__(self, owner_bot, xmpp_room_jid, irc_room, irc_server, mode, say_level, irc_port=6667): |
45 """Create a new bridge.""" | 45 """Create a new bridge.""" |
46 self.bot = owner_bot | 46 self.bot = owner_bot |
142 p = self.getParticipant(nickname) | 142 p = self.getParticipant(nickname) |
143 if p.protocol != from_protocol: | 143 if p.protocol != from_protocol: |
144 if from_protocol == 'irc' and isinstance(p.irc_connection, ServerConnection) and p.irc_connection.really_connected == True or from_protocol == 'xmpp' and isinstance(p.xmpp_c, xmpp.client.Client) and isinstance(p.muc, xmpp.muc): | 144 if from_protocol == 'irc' and isinstance(p.irc_connection, ServerConnection) and p.irc_connection.really_connected == True or from_protocol == 'xmpp' and isinstance(p.xmpp_c, xmpp.client.Client) and isinstance(p.muc, xmpp.muc): |
145 if irc_id: | 145 if irc_id: |
146 p.irc_connection.irc_id = irc_id | 146 p.irc_connection.irc_id = irc_id |
147 return | 147 return p |
148 self.bot.error('===> Debug: "'+nickname+'" is on both sides of bridge "'+str(self)+'"', debug=True) | 148 self.bot.error('===> Debug: "'+nickname+'" is on both sides of bridge "'+str(self)+'"', debug=True) |
149 self.say('[Warning] The nickname "'+nickname+'" is used on both sides of the bridge, please avoid that if possible') | 149 self.say('[Warning] The nickname "'+nickname+'" is used on both sides of the bridge, please avoid that if possible') |
150 if isinstance(p.irc_connection, ServerConnection): | 150 if isinstance(p.irc_connection, ServerConnection): |
151 p.irc_connection.close('') | 151 p.irc_connection.close('') |
152 if p.irc_connection != 'both': | 152 if p.irc_connection != 'both': |
157 if p.xmpp_c != 'both': | 157 if p.xmpp_c != 'both': |
158 p.xmpp_c = 'both' | 158 p.xmpp_c = 'both' |
159 return p | 159 return p |
160 except NoSuchParticipantException: | 160 except NoSuchParticipantException: |
161 pass | 161 pass |
162 | |
163 if nickname == 'ChanServ' and from_protocol == 'irc': | |
164 return | |
165 | |
162 self.lock.acquire() | 166 self.lock.acquire() |
163 self.bot.error('===> Debug: adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) | 167 self.bot.error('===> Debug: adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) |
164 try: | 168 try: |
165 p = participant(self, from_protocol, nickname, real_jid=real_jid) | 169 p = participant(self, from_protocol, nickname, real_jid=real_jid) |
166 except IOError: | 170 except IOError: |
170 self.bot.error('===> Debug: unknown error while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) | 174 self.bot.error('===> Debug: unknown error while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) |
171 traceback.print_exc() | 175 traceback.print_exc() |
172 return | 176 return |
173 self.participants.append(p) | 177 self.participants.append(p) |
174 self.lock.release() | 178 self.lock.release() |
175 if self.mode != 'normal': | 179 if self.mode not in ['normal', 'bypass']: |
176 if from_protocol == 'xmpp': | 180 if from_protocol == 'xmpp': |
177 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) | 181 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) |
178 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) | 182 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) |
179 elif self.mode == 'minimal' and from_protocol == 'irc': | 183 elif self.mode == 'minimal' and from_protocol == 'irc': |
180 irc_participants_nicknames = self.get_participants_nicknames_list(protocols=['irc']) | 184 irc_participants_nicknames = self.get_participants_nicknames_list(protocols=['irc']) |
181 self.say('[Info] Participants on IRC: '+' '.join(irc_participants_nicknames), on_irc=False) | 185 self.say('[Info] Participants on IRC: '+' '.join(irc_participants_nicknames), on_irc=False) |
182 return p | 186 return p |
183 | 187 |
184 | 188 |
189 def changeMode(self, new_mode): | |
190 if new_mode == self.mode: | |
191 return 'Mode is already equal to '+self.mode | |
192 | |
193 unhandled = 'Error: unhandled mode changing from '+self.mode+' to '+new_mode | |
194 | |
195 if new_mode in ['normal', 'bypass']: | |
196 | |
197 if self.mode[-7:] == 'limited': | |
198 # From [{normal,bypass}-]limited to {normal,bypass} | |
199 pass # duplicates of XMPP users are created below | |
200 | |
201 elif self.mode == 'minimal': | |
202 # From minimal to {normal,bypass} | |
203 # create duplicates of IRC users, duplicates of XMPP users are created below | |
204 for p in self.participants: | |
205 if p.protocol == 'irc': | |
206 p.createDuplicateOnXMPP() | |
207 | |
208 else: | |
209 # Unhandled mode changing | |
210 return unhandled | |
211 | |
212 # create duplicates of XMPP users | |
213 for p in self.participants: | |
214 if p.protocol == 'xmpp': | |
215 p.createDuplicateOnIRC() | |
216 | |
217 elif new_mode[-7:] == 'limited': | |
218 | |
219 i = 0 | |
220 for p in self.participants: | |
221 if p.protocol == 'xmpp': | |
222 i += 1 | |
223 p._close_irc_connection('Bridge is switching to limited mode') | |
224 | |
225 if new_mode[-8:] == '-limited': | |
226 # to {normal,bypass}-limited | |
227 self.irc_connections_limit = i | |
228 self.bot.error('===> Bridge is switching to limited mode. Limit seems to be '+str(self.irc_connections_limit)+' on "'+self.irc_server+'".') | |
229 self.say('[Warning] Bridge is switching to limited mode, it means that it will be transparent for XMPP users but not for IRC users, this is due to the IRC servers\' per-IP-address connections\' limit number which seems to be '+str(self.irc_connections_limit)+' on "'+self.irc_server+'".') | |
230 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) | |
231 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) | |
232 return | |
233 | |
234 elif new_mode == 'minimal': | |
235 for p in self.participants: | |
236 p.leave('Bridge is switching to limited mode') | |
237 | |
238 else: | |
239 # Unhandled mode changing | |
240 return unhandled | |
241 | |
242 self.mode = new_mode | |
243 self.bot.error('===> Bridge is switching from '+self.mode+' to '+new_mode+' mode.') | |
244 self.say('[Notice] Bridge is switching from '+self.mode+' to '+new_mode+' mode.') | |
245 | |
246 | |
185 def getParticipant(self, nickname): | 247 def getParticipant(self, nickname): |
186 """Returns a participant object if there is a participant using nickname in the bridge. Raises a NoSuchParticipantException otherwise.""" | 248 """Returns a participant object if there is a participant using nickname in the bridge. Raises a NoSuchParticipantException otherwise.""" |
187 self.lock.acquire() | 249 self.lock.acquire() |
188 for participant_ in self.participants: | 250 for p in self.participants: |
189 if participant_.nickname == nickname: | 251 if nickname in [p.nickname, p.duplicate_nickname]: |
190 self.lock.release() | 252 self.lock.release() |
191 return participant_ | 253 return p |
192 self.lock.release() | 254 self.lock.release() |
193 raise NoSuchParticipantException('there is no participant using the nickname "'+nickname+'" in this bridge') | 255 raise NoSuchParticipantException('there is no participant using the nickname "'+nickname+'" in this bridge') |
194 | 256 |
195 | 257 |
196 def get_participants_nicknames_list(self, protocols=['irc', 'xmpp']): | 258 def get_participants_nicknames_list(self, protocols=['irc', 'xmpp']): |
266 del p | 328 del p |
267 self.lock.release() | 329 self.lock.release() |
268 if left_protocol == 'xmpp': | 330 if left_protocol == 'xmpp': |
269 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) | 331 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) |
270 if self.irc_connections_limit != -1 and self.irc_connections_limit > len(xmpp_participants_nicknames): | 332 if self.irc_connections_limit != -1 and self.irc_connections_limit > len(xmpp_participants_nicknames): |
271 self.switchFromLimitedToNormalMode() | 333 self.changeMode(self.mode[:-8]) |
272 if self.mode != 'normal': | 334 if self.mode not in ['normal', 'bypass']: |
273 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) | 335 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) |
274 elif left_protocol == 'irc': | 336 elif left_protocol == 'irc': |
275 if self.mode == 'minimal': | 337 if self.mode == 'minimal': |
276 irc_participants_nicknames = self.get_participants_nicknames_list(protocols=['irc']) | 338 irc_participants_nicknames = self.get_participants_nicknames_list(protocols=['irc']) |
277 self.say('[Info] Participants on IRC: '+' '.join(irc_participants_nicknames), on_irc=False) | 339 self.say('[Info] Participants on IRC: '+' '.join(irc_participants_nicknames), on_irc=False) |
334 p.leave(message) | 396 p.leave(message) |
335 del p | 397 del p |
336 self.participants = [] | 398 self.participants = [] |
337 | 399 |
338 | 400 |
339 def switchFromLimitedToNormalMode(self): | |
340 if self.mode != 'normal-limited': | |
341 return | |
342 self.bot.error('===> Bridge is switching to normal mode.') | |
343 self.say('[Notice] Bridge is switching to normal mode.') | |
344 self.mode = 'normal' | |
345 for p in self.participants: | |
346 if p.protocol == 'xmpp': | |
347 p.createDuplicateOnIRC() | |
348 | |
349 | |
350 def switchFromNormalToLimitedMode(self): | |
351 if self.mode != 'normal': | |
352 return | |
353 self.mode = 'normal-limited' | |
354 i = 0 | |
355 for p in self.participants: | |
356 if p.protocol == 'xmpp': | |
357 i += 1 | |
358 if isinstance(self.irc_connection, ServerConnection): | |
359 p.irc_connection.close('Bridge is switching to limited mode') | |
360 p.irc_connection = None | |
361 self.irc_connections_limit = i | |
362 self.bot.error('===> Bridge is switching to limited mode. Limit seems to be '+str(self.irc_connections_limit)+' on "'+self.irc_server+'".') | |
363 self.say('[Warning] Bridge is switching to limited mode, it means that it will be transparent for XMPP users but not for IRC users, this is due to the IRC servers\' per-IP-address connections\' limit number which seems to be '+str(self.irc_connections_limit)+' on "'+self.irc_server+'".') | |
364 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) | |
365 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) | |
366 | |
367 | |
368 def __str__(self): | 401 def __str__(self): |
369 return self.irc_room+'@'+self.irc_server+' <-> '+self.xmpp_room_jid | 402 return self.irc_room+'@'+self.irc_server+' <-> '+self.xmpp_room_jid |
370 | 403 |
371 | 404 |
372 def __del__(self): | 405 def __del__(self): |