changeset 86:bfa32b017fc9

First hack at an error notification system Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Sun, 06 Sep 2009 15:34:49 +0200
parents dfa030c141f1
children 500d47b1d8cd
files bot.py bridge.py irclib.py participant.py start_bots_from_xml_config.py
diffstat 5 files changed, 28 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/bot.py
+++ b/bot.py
@@ -37,7 +37,7 @@ import traceback
 
 class bot(Thread):
 	
-	def __init__(self, jid, password, nickname, error_fd=sys.stderr, debug=False):
+	def __init__(self, jid, password, nickname, admins_jid=[], error_fd=sys.stderr, debug=False):
 		Thread.__init__(self)
 		self.commands = ['!xmpp_participants', '!irc_participants']
 		self.bare_jid = xmpp.protocol.JID(jid=jid)
@@ -46,6 +46,7 @@ class bot(Thread):
 		self.password = password
 		self.error_fd = error_fd
 		self.debug = debug
+		self.admins_jid = admins_jid
 		self.bridges = []
 		self.xmpp_connections = {}
 		self.irc = irclib.IRC()
@@ -63,8 +64,10 @@ class bot(Thread):
 		self.xmpp_thread.start()
 	
 	
-	def error(self, s, debug=False):
+	def error(self, s, debug=False, send_to_admins=False):
 		"""Output an error message."""
+		if send_to_admins == True:
+			self._send_message_to_admins(s)
 		if not debug or debug and self.debug:
 			try:
 				self.error_fd.write(auto_encode(s)+"\n")
@@ -102,8 +105,9 @@ class bot(Thread):
 				self.error('=> Debug: invalid stanza', debug=True)
 				unlock = True
 			except:
-				self.error('[Error] Unkonwn exception on XMPP thread:')
-				traceback.print_exc()
+				error = '[Error] Unkonwn exception on XMPP thread:\n'
+				error += traceback.format_exc()
+				self.error(error, send_to_admins=True)
 				unlock = True
 			if unlock == True:
 				c.lock.release()
@@ -505,6 +509,15 @@ class bot(Thread):
 		self.error('=> Debug: event not handled', debug=True)
 	
 	
+	def _send_message_to_admins(self, message):
+		"""[Internal] Send XMPP Message to bot admin(s)"""
+		for admin_jid in self.admins_jid:
+			try:
+				self.xmpp_c.send(xmpp.protocol.Message(to=admin_jid, body=message, typ='chat'))
+			except:
+				pass
+	
+	
 	def new_bridge(self, xmpp_room, irc_room, irc_server, mode, say_level, irc_port=6667):
 		"""Create a bridge between xmpp_room and irc_room at irc_server."""
 		b = bridge(self, xmpp_room, irc_room, irc_server, mode, say_level, irc_port=irc_port)
--- a/bridge.py
+++ b/bridge.py
@@ -101,7 +101,7 @@ class bridge:
 					raise Exception('[Error] unknown error for "'+self.bot.nickname+'" on bridge "'+str(self)+'", limit seems to be '+str(arguments[0]))
 			except:
 				traceback.print_exc()
-			self.bot.error('[Error] failed to connect to the IRC chan of bridge "'+str(self)+'", removing bridge')
+			self.bot.error('[Error] failed to connect to the IRC chan of bridge "'+str(self)+'", removing bridge', send_to_admins=True)
 			self.bot.removeBridge(self)
 	
 	
@@ -121,7 +121,7 @@ class bridge:
 					raise error
 				except:
 					traceback.print_exc()
-			self.bot.error('[Error] failed to connect to the XMPP room of bridge "'+str(self)+'", removing bridge')
+			self.bot.error('[Error] failed to connect to the XMPP room of bridge "'+str(self)+'", removing bridge', send_to_admins=True)
 			self.bot.removeBridge(self)
 	
 	
@@ -237,11 +237,10 @@ class bridge:
 			del p
 			self.lock.release()
 			if left_protocol == 'xmpp':
-				i = len(self.get_participants_nicknames_list(protocols=['xmpp']))
-				if self.irc_connections_limit != -1 and self.irc_connections_limit > i:
+				xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp'])
+				if self.irc_connections_limit != -1 and self.irc_connections_limit > len(xmpp_participants_nicknames):
 					self.switchFromLimitedToNormalMode()
 				if self.mode != 'normal':
-					xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp'])
 					self.say('[Info] Participants on XMPP: '+'  '.join(xmpp_participants_nicknames), on_xmpp=False)
 			elif left_protocol == 'irc':
 				if self.mode == 'minimal':
--- a/irclib.py
+++ b/irclib.py
@@ -198,8 +198,7 @@ class IRC:
                         try:
                             c.process_data()
                         except:
-                            self.bot.error('[Error] Unkonwn exception on IRC thread:')
-                            traceback.print_exc()
+                            self.bot.error('[Error] Unkonwn exception on IRC thread:\n'+traceback.format_exc(), send_to_admins=True)
                     c.lock.release()
 
     def process_timeout(self):
--- a/participant.py
+++ b/participant.py
@@ -63,7 +63,7 @@ class participant:
 					self.bridge.bot.close_xmpp_connection(self.nickname)
 					self.xmpp_c = None
 				except xmpp.muc.RoomIsFull:
-					self.bridge.bot.error('[Warning] XMPP MUC of bridge "'+str(self.bridge)+'" is full', debug=True)
+					self.bridge.bot.error('[Warning] XMPP MUC of bridge "'+str(self.bridge)+'" is full', send_to_admins=True)
 					self.bridge.say('[Warning] XMPP room is full')
 					self.bridge.bot.close_xmpp_connection(self.nickname)
 					self.xmpp_c = None
--- a/start_bots_from_xml_config.py
+++ b/start_bots_from_xml_config.py
@@ -49,7 +49,11 @@ try:
 		if bot_el.hasAttribute('debug'):
 			if bot_el.getAttribute('debug') == 'true':
 				debug = True
-		bot_ = bot(bot_el.getAttribute('jid'), bot_el.getAttribute('password'), bot_el.getAttribute('nickname'), debug=debug)
+		admins_jid = []
+		for admin_el in bot_el.getElementsByTagName('admin'):
+			if admin_el.hasAttribute('jid'):
+				admins_jid.append(admin_el.getAttribute('jid'))
+		bot_ = bot(bot_el.getAttribute('jid'), bot_el.getAttribute('password'), bot_el.getAttribute('nickname'), admins_jid=admins_jid, debug=debug)
 		bots.append(bot_)
 		for bridge_el in bot_el.getElementsByTagName('bridge'):
 			xmpp_room = bridge_el.getElementsByTagName('xmpp-room')[0]