comparison bridge.py @ 103:23416c27b592

New command system Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Sat, 21 Nov 2009 16:26:09 +0100
parents b3eba9489329
children d8acff763731
comparison
equal deleted inserted replaced
102:b3eba9489329 103:23416c27b592
35 _info = 1 35 _info = 1
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 _modes = ['normal', 'limited', 'minimal'] 41 _modes = ['normal', 'limited', 'minimal']
41 42
42 43
43 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):
44 """Create a new bridge.""" 45 """Create a new bridge."""
45 self.bot = owner_bot 46 self.bot = owner_bot
46 self.irc_server = irc_server 47 self.irc_server = irc_server
47 self.irc_port = irc_port 48 self.irc_port = irc_port
48 self.irc_room = irc_room.lower() 49 self.irc_room = irc_room.lower()
50 self.xmpp_room_jid = xmpp_room_jid
49 if hasattr(self.__class__, '_'+say_level): 51 if hasattr(self.__class__, '_'+say_level):
50 self.say_level = getattr(self.__class__, '_'+say_level) 52 self.say_level = getattr(self.__class__, '_'+say_level)
51 else: 53 else:
52 raise Exception('[Error] "'+say_level+'" is not a correct value for a bridge\'s "say_level" attribute') 54 raise Exception('[Error] "'+say_level+'" is not a correct value for a bridge\'s "say_level" attribute')
53 self.participants = [] 55 self.participants = []
55 raise Exception('[Error] "'+mode+'" is not a correct value for a bridge\'s "mode" attribute') 57 raise Exception('[Error] "'+mode+'" is not a correct value for a bridge\'s "mode" attribute')
56 self.mode = mode 58 self.mode = mode
57 59
58 self.lock = threading.RLock() 60 self.lock = threading.RLock()
59 61
62 self.init2()
63
64
65 def init2(self):
60 # Join XMPP room 66 # Join XMPP room
61 try: 67 try:
62 self.xmpp_room = xmpp.muc(xmpp_room_jid) 68 self.xmpp_room = xmpp.muc(self.xmpp_room_jid)
63 self.xmpp_room.join(self.bot.xmpp_c, self.bot.nickname, callback=self._xmpp_join_callback) 69 self.xmpp_room.join(self.bot.xmpp_c, self.bot.nickname, callback=self._xmpp_join_callback)
64 except: 70 except:
65 self.bot.error('[Error] joining XMPP room failed') 71 self.bot.error('[Error] joining XMPP room failed')
66 raise 72 raise
67 73
68 # Join IRC room 74 # Join IRC room
69 try: 75 try:
70 self.irc_connections_limit = -1 76 self.irc_connections_limit = -1
71 self.irc_connection = self.bot.irc.server(irc_server, irc_port, self.bot.nickname) 77 self.irc_connection = self.bot.irc.server(self.irc_server, self.irc_port, self.bot.nickname)
72 self.irc_connection.connect(nick_callback=self._irc_nick_callback) 78 self.irc_connection.connect(nick_callback=self._irc_nick_callback)
73 except: 79 except:
74 self.bot.error('[Error] joining IRC room failed') 80 self.bot.error('[Error] joining IRC room failed')
75 raise 81 raise
76 82
77 self.bot.error('[Notice] bridge "'+str(self)+'" is running in '+self.mode+' mode and a say_level of "'+say_level+'"') 83 self.bot.error('[Notice] bridge "'+str(self)+'" is running in '+self.mode+' mode and a say_level of "'+self._say_levels[self.say_level]+'"')
78 84
79 85
80 def _irc_nick_callback(self, error, arguments=[]): 86 def _irc_nick_callback(self, error, arguments=[]):
81 if error == None: 87 if error == None:
82 if self.mode == None: 88 if self.mode == None:
123 traceback.print_exc() 129 traceback.print_exc()
124 self.bot.error('[Error] failed to connect to the XMPP room of bridge "'+str(self)+'", removing bridge', send_to_admins=True) 130 self.bot.error('[Error] failed to connect to the XMPP room of bridge "'+str(self)+'", removing bridge', send_to_admins=True)
125 self.bot.removeBridge(self) 131 self.bot.removeBridge(self)
126 132
127 133
128 def addParticipant(self, from_protocol, nickname): 134 def addParticipant(self, from_protocol, nickname, real_jid=None):
129 """Add a participant to the bridge.""" 135 """Add a participant to the bridge."""
130 if (from_protocol == 'irc' and nickname == self.irc_connection.get_nickname()) or (from_protocol == 'xmpp' and nickname == self.xmpp_room.nickname): 136 if (from_protocol == 'irc' and nickname == self.irc_connection.get_nickname()) or (from_protocol == 'xmpp' and nickname == self.xmpp_room.nickname):
131 self.bot.error('===> Debug: not adding self ('+self.bot.nickname+') to bridge "'+str(self)+'"', debug=True) 137 self.bot.error('===> Debug: not adding self ('+self.bot.nickname+') to bridge "'+str(self)+'"', debug=True)
132 return 138 return
133 try: 139 try:
150 except NoSuchParticipantException: 156 except NoSuchParticipantException:
151 pass 157 pass
152 self.lock.acquire() 158 self.lock.acquire()
153 self.bot.error('===> Debug: adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) 159 self.bot.error('===> Debug: adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True)
154 try: 160 try:
155 p = participant(self, from_protocol, nickname) 161 p = participant(self, from_protocol, nickname, real_jid=real_jid)
156 except IOError: 162 except IOError:
157 self.bot.error('===> Debug: IOError while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'", reconnectiong ...', debug=True) 163 self.bot.error('===> Debug: IOError while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'", reconnectiong ...', debug=True)
158 p.xmpp_c.reconnectAndReauth() 164 p.xmpp_c.reconnectAndReauth()
159 except: 165 except:
160 self.bot.error('===> Debug: unknown error while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) 166 self.bot.error('===> Debug: unknown error while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True)
268 274
269 else: 275 else:
270 self.bot.error('=> Debug: Bad decision tree, p.protocol='+p.protocol+' left_protocol='+left_protocol+'\np.xmpp_c='+str(p.xmpp_c)+'\np.irc_connection='+str(p.irc_connection), debug=True) 276 self.bot.error('=> Debug: Bad decision tree, p.protocol='+p.protocol+' left_protocol='+left_protocol+'\np.xmpp_c='+str(p.xmpp_c)+'\np.irc_connection='+str(p.irc_connection), debug=True)
271 277
272 278
279 def restart(self):
280 """Restart the bridge"""
281
282 # Stop the bridge
283 self.stop(message='Restarting bridge')
284
285 # Recreate the bridge
286 self.init2()
287
288
273 def say(self, message, on_irc=True, on_xmpp=True): 289 def say(self, message, on_irc=True, on_xmpp=True):
274 """Make the bot say something.""" 290 """Make the bot say something."""
275 if message[0] != '[': 291 if message[0] != '[':
276 raise Exception('[Internal Error] message does not start with "["') 292 raise Exception('[Internal Error] message does not start with "["')
277 if self.say_level == self.__class__._nothing: 293 if self.say_level == self.__class__._nothing:
284 return 300 return
285 if on_xmpp == True: 301 if on_xmpp == True:
286 self.xmpp_room.say(message) 302 self.xmpp_room.say(message)
287 if on_irc == True: 303 if on_irc == True:
288 self.irc_connection.privmsg(self.irc_room, message) 304 self.irc_connection.privmsg(self.irc_room, message)
305
306
307 def stop(self, message='Stopping bridge'):
308 """Stop the bridge"""
309
310 # Close IRC connection if not used by an other bridge, just leave the room otherwise
311 self.irc_connection.used_by -= 1
312 if self.irc_connection.used_by < 1:
313 self.irc_connection.close(message)
314 else:
315 self.irc_connection.part(self.irc_room, message=message)
316
317 # Leave the MUC
318 self.xmpp_room.leave(message=message)
319 self.xmpp_room.__del__()
320 del self.xmpp_room
321
322 # Delete participants objects
323 for p in self.participants:
324 p.leave(message)
325 del p
326 self.participants = []
289 327
290 328
291 def switchFromLimitedToNormalMode(self): 329 def switchFromLimitedToNormalMode(self):
292 if self.mode != 'normal-limited': 330 if self.mode != 'normal-limited':
293 return 331 return
316 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) 354 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp'])
317 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) 355 self.say('[Info] Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False)
318 356
319 357
320 def __str__(self): 358 def __str__(self):
321 return self.irc_room+'@'+self.irc_server+' <-> '+self.xmpp_room.room_jid 359 return self.irc_room+'@'+self.irc_server+' <-> '+self.xmpp_room_jid
322 360
323 361
324 def __del__(self): 362 def __del__(self):
325 # Delete participants objects 363 self.stop(message='Removing bridge')
326 for p in self.participants:
327 p.leave('Removing bridge')
328 del p
329 del self.participants
330
331 # Close IRC connection if not used by an other bridge, just leave the room otherwise
332 self.irc_connection.used_by -= 1
333 if self.irc_connection.used_by < 1:
334 self.irc_connection.close('Removing bridge')
335 else:
336 self.irc_connection.part(self.irc_room, message='Removing bridge')
337
338 # Leave XMPP room
339 self.xmpp_room.leave('Removing bridge')