]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/modpython.py
Minor typo in previous commit where returning 0 when it should have been 1 from opser...
[irc/evilnet/x3.git] / src / modpython.py
index cab4a4382bd793139056c34ebafb97cde8de9a09..1f7c83c97606e2004651ab08fa4a69e68803eb5c 100644 (file)
 # - provide helper functions for scripts to do common things like msg a person or a channel,
 #   reply, etc.
 
-import svc
+import _svc
+import plugins
 
 import math
 
+import sys
 
-class modules:
-    """Class to handle loading/unloading of modules"""
-    loaded_modules = []
-
-    def load(self, name):
-        mod_name = "plugins.%s"%name
-        if(sys.modules[mod_name]):
-            need_reload = true
-        #TODO: try to catch compile errors etc.
-        if(!need_reload):
-            __import__(mod_name)
-        module = sys.modules[mod_name]
-        if(need_reload):
-            reload(module) # to ensure its read fresh
-        self.loaded_modules[mod_name] = module
 
 class irc:
     """Used to interact with the world of IRC from module scripts"""
@@ -47,72 +34,160 @@ class irc:
         self.target = target   #the channel message was in (if public)
 
     def send_target_privmsg(self, source, target, message):
-        svc.send_target_privmsg(source, target,  "%s "%(message))
+        _svc.send_target_privmsg(source, target,  "%s "%(message))
 
     def reply(self, message):
         """ Send a private reply to the user using convenience values"""
-        self.send_target_privmsg(self.service, self.caller, message)
+        #print "DEBUG: sending a message from %s to %s: %s"%(self.service, self.caller, message)
+        if(len(self.target)):
+            self.send_target_privmsg(self.service, self.target, "%s: %s"%(self.caller, message))
+        else:
+            self.send_target_privmsg(self.service, self.caller, message)
+
+class handler:
+    """ Main hub of python system. Handle callbacks from c. """
+
+    def __init__(self):
+        #print "DEBUG: constructor for handler initing"
+        self.plugins = plugins_(self)
+        if(not self.plugins):
+            print "DEBUG: unable to make self.plugins!?!"
+        self.newplugins = plugins.load()
+
+    def init(self, irc): # not to be confused with __init__!
+        """ This gets called once all the objects are up and running. Otherwise,
+        were not done initing this own instance to be able to start calling it """
+        #print "DEBUG: in handler.init()"
+        self.plugins.init()
+        return 0
+
+    def join(self, irc, channel, nick):
+        #user = _svc.get_user(nick)
+        #print "DEBUG: handler.join()"
+        return self.plugins.callhandler("join", irc, [channel, nick], [channel, nick])
+
+    def server_link(self, server):
+        for plugin in self.newplugins:
+            if plugin.server_link(server):
+                return 1
+        return 0
 
+    def new_user(self, user):
+        for plugin in self.newplugins:
+            if plugin.new_user(user):
+                return 1
+        return 0
 
-    def command_set(self, command_caller, command_target, command_service):
-        """ Setup defaults for convenience"""
-        global caller, target, service
-        caller = command_caller
-        target = command_target
-        service = command_service
-        return 0;
+    def nick_change(self, user, oldnick):
+        for plugin in self.newplugins:
+            plugin.nick_change(user, oldnick)
 
-    def command_clear(self):
-        """ Clear convenience defaults"""
-        global caller, target, service
-        caller = None
-        target = None
-        service = None
-        return 0;
+    def del_user(self, user, killer, why):
+        for plugin in self.newplugins:
+            plugin.del_user(user, killer, why)
 
+    def topic(self, who, chan, old_topic):
+        for plugin in self.newplugins:
+            if plugin.topic(who, chan, old_topic):
+                return 1
+        return 0
 
-class handler:
-    """ Handle callbacks """
+    def cmd_run(self, irc, cmd):
+        #print "DEBUG: handler.cmd_run: %s"%cmd
+        eval(cmd)
+        return 0
 
-    def init(): # not to be confused with __init__!
-        print "DEBUG: This is x3init in python"
+    def addhook(self, event, method, filter=[None], data=None):
+        self.plugins.addhook(event, method, filter, data)
         return 0
 
-    def join(self, channel, nick)
-        user = svc.get_user(nick)
-        irc.send_target_privmsg("x3", channel, "test %s "%(service))
+    def addcommand(self, plugin, command, method):
+        self.addhook("command", method, [plugin, command])
+
+    def cmd_command(self, irc, plugin, cmd, args):
+        #print "DEBUG: handel.cmd_command; %s %s; args= %s"%(plugin, cmd, args)
+        return self.plugins.callhandler("command", irc, [plugin, cmd], [args])
+
+    def load(self, irc, plugin):
+        return self.plugins.load(plugin)
+
+class plugins_:
+    """Class to handle loading/unloading of plugins"""
+    loaded_plugins = {}
+    hooks = []
+
+    class hook:
+        """ This is a request from a plugin to be called on an event """
+        event = ""     # Event to be called on (eg "join")
+        method = None  # Method to call
+        filter = None  # Arguments to filter
+        data = ""      # plugin-supplied data for plugin use
         
-#+print "This is mod-python.py"
-#+
-#+caller = ''
-#+target = ''
-#+service = ''
-#+
-#+def handle_init():
-#+    print "This is x3init in python"
-#+    return 0
-#+
-#+
-#+def handle_join(channel, nick):
-#+    global caller, target, service
-#+    print "This is handle_join() in python"
-#+    user = svc.get_user(nick)
-#+    svc.send_target_privmsg("x3", channel, "test %s "%(service))
-#+    svc.send_target_privmsg("x3", channel, "   %s joined %s: %s"%(nick, channel, user))
-#+    svc.send_target_privmsg("x3", channel, "Welcome to %s %s (*%s)! Your IP is %s. You are now in %d channels!"%(channel, user['nick'], user['account'], user['ip'], len(user['channels']) ))
-#+    chan = svc.get_channel(channel)
-#+    svc.send_target_privmsg("x3", channel, "Channel details: %s"%chan)
-#+    return 0
-#+
-#+def run(command):
-#+    eval(command)
-#+    return 0
-#+
-#+def reply(message):
-#+    global caller, target, service
-#+    print "DEBUG: %s / %s / %s : %s" %(caller, target, service, message);
-#+    if(len(target) > 0):
-#+        svc.send_target_privmsg(service, target, "%s: %s"%(caller, message));
-#+    else:
-#+        svc.send_target_notice(service, caller, message);
-#+    return 0
+        def __init__(self, event, method, filter, data):
+            self.event = event
+            self.method = method
+            self.filter = filter
+            self.data = data
+
+        def event_is(self, event, evdata):
+            if(self.event == event):
+                for i in range(len(self.filter)):
+                    if( self.filter[i] != None 
+                      and self.filter[i] != evdata[i]): # should be case insensitive? or how to compare?
+                        #print "DEBUG: rejecting event, %s is not %s"%(self.filter[i], evdata[i])
+                        return False
+                return True
+            else:
+                return False
+
+        def trigger(self, irc, args):
+            #print "DEBUG: Triggering %s event. with '%s' arguments."%(self.event, args)
+            self.method(irc, *args)
+
+    def __init__(self, handler):
+        """ Constructor """
+        #print "DEBUG: constructor for plugins initing"
+        self.handler = handler
+
+    def init(self):
+        #print "DEBUG: in plugins.init()"
+        self.load("annoy")
+        self.load("hangman")
+
+    def addhook(self, event, method, filter=[None], data=None):
+        #print "DEBUG: Adding hook for %s."%event
+        self.hooks.append(self.hook(event, method, filter, data))
+
+    def findhooksforevent(self, event, data):
+        ret = []
+        #print "DEBUG: findhooksforevent() looking..."
+        for hook in self.hooks:
+            #print "DEBUG: looking at a %s hook..."%hook.event
+            if(hook.event_is(event, data)):
+                ret.append(hook)
+        return ret
+
+    def callhandler(self, event, irc, filter, args):
+        for hook in self.findhooksforevent(event, filter):
+            if(hook.trigger(irc, args)):
+                return 1
+        return 0
+
+    def load(self, name):
+        """ Loads a plugin by name """
+        mod_name = "plugins.%s"%name
+        need_reload = False
+        if(sys.modules.has_key(mod_name)):
+            need_reload = True
+        #TODO: try to catch compile errors etc.
+
+        if(need_reload == False):
+            __import__(mod_name)
+        module = sys.modules[mod_name]
+        if(need_reload == True):
+            reload(module) # to ensure its read fresh
+        Class = module.Class
+        pluginObj = Class(self.handler, irc())
+        self.loaded_plugins[mod_name] = pluginObj
+        return True
+