]> jfr.im git - erebus.git/blobdiff - erebus.py
urls - reformat headers
[erebus.git] / erebus.py
index 42a2f416cefef07c20fdcfc3935431a63934ec9a..5ebb39ea548edb67ce3ba50cff0390e5d5580a85 100644 (file)
--- a/erebus.py
+++ b/erebus.py
@@ -6,7 +6,7 @@
 
 from __future__ import print_function
 
-import os, sys, select, MySQLdb, MySQLdb.cursors, time, random, gc
+import os, sys, select, MySQLdb, MySQLdb.cursors, time, traceback, random, gc
 import bot, config, ctlmod
 
 class Erebus(object): #singleton to pass around
@@ -18,6 +18,7 @@ class Erebus(object): #singleton to pass around
        numhandlers = {}
        msghandlers = {}
        chanhandlers = {}
+       exceptionhandlers = [] # list of (Exception_class, handler_function) tuples
        users = {}
        chans = {}
 
@@ -213,6 +214,12 @@ class Erebus(object): #singleton to pass around
                        self.po.register(fileno, select.POLLIN)
                elif self.potype == "select":
                        self.fdlist.append(fileno)
+       def delfd(self, fileno):
+               del self.fds[fileno]
+               if self.potype == "poll":
+                       self.po.unregister(fileno)
+               elif self.potype == "select":
+                       self.fdlist.remove(fileno)
 
        def bot(self, name): #get Bot() by name (nick)
                return self.bots[name.lower()]
@@ -221,17 +228,17 @@ class Erebus(object): #singleton to pass around
        def randbot(self): #get Bot() randomly
                return self.bots[random.choice(list(self.bots.keys()))]
 
-       def user(self, _nick, justjoined=False, create=True):
+       def user(self, _nick, send_who=False, create=True):
                nick = _nick.lower()
+
+               if send_who and (nick not in self.users or not self.users[nick].isauthed()):
+                       self.randbot().conn.send("WHO %s n%%ant,1" % (nick))
+
                if nick in self.users:
                        return self.users[nick]
                elif create:
                        user = self.User(_nick)
                        self.users[nick] = user
-
-                       if justjoined:
-                               self.randbot().conn.send("WHO %s n%%ant,1" % (nick))
-
                        return user
                else:
                        return None
@@ -315,6 +322,15 @@ class Erebus(object): #singleton to pass around
        def getchanhook(self, chan):
                return self.chanhandlers[chan]
 
+       def hookexception(self, exc, handler):
+               self.exceptionhandlers.append((exc, handler))
+       def unhookexception(self, exc, handler):
+               self.exceptionhandlers.remove((exc, handler))
+       def hasexceptionhook(self, exc):
+               return any((True for x,h in self.exceptionhandlers if isinstance(exc, x)))
+       def getexceptionhook(self, exc):
+               return (h for x,h in self.exceptionhandlers if isinstance(exc, x))
+
 
 def dbsetup():
        main.db = None
@@ -353,8 +369,23 @@ def setup():
 def loop():
        poready = main.poll()
        for fileno in poready:
-               for line in main.fd(fileno).getdata():
-                       main.fd(fileno).parse(line)
+               try:
+                       data = main.fd(fileno).getdata()
+               except:
+                       main.log('*', '!', 'Super-mega-emergency: getdata raised exception for socket %d' % (fileno))
+                       traceback.print_exc()
+                       data = None
+               if data is None:
+                       main.fd(fileno).close()
+               else:
+                       for line in data:
+                               if cfg.getboolean('debug', 'io'):
+                                       main.log(str(main.fd(fileno)), 'I', line)
+                               try:
+                                       main.fd(fileno).parse(line)
+                               except:
+                                       main.log('*', '!', 'Super-mega-emergency: parse raised exception for socket %d data %r' % (fileno, line))
+                                       traceback.print_exc()
        if main.mustquit is not None:
                main.log('*', '!', 'Core exiting due to: %s' % (main.mustquit))
                raise main.mustquit