]> jfr.im git - irc/evilnet/x3.git/blame - src/modpython.py
mod-python: refactor modeList conversion into separate function
[irc/evilnet/x3.git] / src / modpython.py
CommitLineData
caf97651 1#!/usr/bin/python
2
a2c8c575 3
4# TODO notes:
5#
6# - impliment handle_* functions for everything x3 has register fetaures for
7# - impliment script load/unload for user scripts.
8# - load a script via this script.
9# - script calls functions from here to set its functions up for calling on various actions
10# - provide helper functions for subscripts to save settings attached to users/chanels
11# - provide helper functions for scripts to do common things like msg a person or a channel,
12# reply, etc.
13
50d61a79 14import _svc
a2c8c575 15
d4e0f0c4 16import math
17
4c216694 18import sys
cbfd323c 19
cbfd323c 20
21class irc:
22 """Used to interact with the world of IRC from module scripts"""
23
24 # some defaults to make shorthand easy
25 caller = ''
26 target = ''
27 service = ''
28
29 def __init__(self, service = None, caller = None, target = None):
30 """ Constructor """
31 self.caller = caller #the person who sent the command/message
32 self.service = service #the service who saw the message
33 self.target = target #the channel message was in (if public)
34
35 def send_target_privmsg(self, source, target, message):
50d61a79 36 _svc.send_target_privmsg(source, target, "%s "%(message))
cbfd323c 37
38 def reply(self, message):
39 """ Send a private reply to the user using convenience values"""
0c33848c 40 #print "DEBUG: sending a message from %s to %s: %s"%(self.service, self.caller, message)
07559983 41 if(len(self.target)):
4c216694 42 self.send_target_privmsg(self.service, self.target, "%s: %s"%(self.caller, message))
43 else:
44 self.send_target_privmsg(self.service, self.caller, message)
cbfd323c 45
cbfd323c 46class handler:
4c216694 47 """ Main hub of python system. Handle callbacks from c. """
07559983 48
49 def __init__(self):
0c33848c 50 #print "DEBUG: constructor for handler initing"
07559983 51 self.plugins = plugins(self)
52 if(not self.plugins):
53 print "DEBUG: unable to make self.plugins!?!"
cbfd323c 54
4c216694 55 def init(self, irc): # not to be confused with __init__!
07559983 56 """ This gets called once all the objects are up and running. Otherwise,
57 were not done initing this own instance to be able to start calling it """
0c33848c 58 #print "DEBUG: in handler.init()"
07559983 59 self.plugins.init()
cbfd323c 60 return 0
61
e0f76584 62 def join(self, irc, channel, nick):
50d61a79 63 #user = _svc.get_user(nick)
0c33848c 64 #print "DEBUG: handler.join()"
0ab7b4bc 65 return self.plugins.callhandler("join", irc, [channel, nick], [channel, nick])
66
67 def server_link(self, irc, name, desc):
68 return self.plugins.callhandler("server_link", irc, [name, desc], [name, desc])
69
70 def new_user(self, irc, nick, ident, hostname, info):
71 # we may filter on all the user fields, but we only pass the nick because
72 # the plugin can get the rest itself
73 return self.plugins.callhandler("new_user", irc, [nick, ident, hostname, info], [nick])
74
75 def nick_change(self, irc, nick, old_nick):
76 return self.plugins.callhandler("nick_change", irc, [nick, old_nick], [nick, old_nick])
cbfd323c 77
4c216694 78 def cmd_run(self, irc, cmd):
0c33848c 79 #print "DEBUG: handler.cmd_run: %s"%cmd
07559983 80 eval(cmd)
81 return 0
4c216694 82
07559983 83 def addhook(self, event, method, filter=[None], data=None):
84 self.plugins.addhook(event, method, filter, data)
85 return 0
4c216694 86
07559983 87 def addcommand(self, plugin, command, method):
88 self.addhook("command", method, [plugin, command])
89
90 def cmd_command(self, irc, plugin, cmd, args):
0c33848c 91 #print "DEBUG: handel.cmd_command; %s %s; args= %s"%(plugin, cmd, args)
0ab7b4bc 92 return self.plugins.callhandler("command", irc, [plugin, cmd], [args])
07559983 93
0c33848c 94 def load(self, irc, plugin):
95 return self.plugins.load(plugin)
96
07559983 97class plugins:
98 """Class to handle loading/unloading of plugins"""
99 loaded_plugins = {}
100 hooks = []
101
102 class hook:
103 """ This is a request from a plugin to be called on an event """
104 event = "" # Event to be called on (eg "join")
105 method = None # Method to call
106 filter = None # Arguments to filter
107 data = "" # plugin-supplied data for plugin use
108
109 def __init__(self, event, method, filter, data):
110 self.event = event
111 self.method = method
112 self.filter = filter
113 self.data = data
114
115 def event_is(self, event, evdata):
116 if(self.event == event):
117 for i in range(len(self.filter)):
118 if( self.filter[i] != None
119 and self.filter[i] != evdata[i]): # should be case insensitive? or how to compare?
0c33848c 120 #print "DEBUG: rejecting event, %s is not %s"%(self.filter[i], evdata[i])
07559983 121 return False
122 return True
123 else:
124 return False
125
126 def trigger(self, irc, args):
0c33848c 127 #print "DEBUG: Triggering %s event. with '%s' arguments."%(self.event, args)
07559983 128 self.method(irc, *args)
129
130 def __init__(self, handler):
131 """ Constructor """
0c33848c 132 #print "DEBUG: constructor for plugins initing"
07559983 133 self.handler = handler
134
135 def init(self):
0c33848c 136 #print "DEBUG: in plugins.init()"
4c216694 137 self.load("annoy")
0c33848c 138 self.load("hangman")
4c216694 139
07559983 140 def addhook(self, event, method, filter=[None], data=None):
0c33848c 141 #print "DEBUG: Adding hook for %s."%event
07559983 142 self.hooks.append(self.hook(event, method, filter, data))
143
144 def findhooksforevent(self, event, data):
145 ret = []
0c33848c 146 #print "DEBUG: findhooksforevent() looking..."
07559983 147 for hook in self.hooks:
0c33848c 148 #print "DEBUG: looking at a %s hook..."%hook.event
07559983 149 if(hook.event_is(event, data)):
150 ret.append(hook)
151 return ret
152
153 def callhandler(self, event, irc, filter, args):
154 for hook in self.findhooksforevent(event, filter):
0ab7b4bc 155 if(hook.trigger(irc, args)):
156 return 1
157 return 0
07559983 158
4c216694 159 def load(self, name):
07559983 160 """ Loads a plugin by name """
4c216694 161 mod_name = "plugins.%s"%name
162 need_reload = False
163 if(sys.modules.has_key(mod_name)):
164 need_reload = true
165 #TODO: try to catch compile errors etc.
166
167 if(need_reload == False):
168 __import__(mod_name)
169 module = sys.modules[mod_name]
170 if(need_reload == True):
171 reload(module) # to ensure its read fresh
172 Class = module.Class
07559983 173 pluginObj = Class(self.handler, irc())
174 self.loaded_plugins[mod_name] = pluginObj
0c33848c 175 return True
4c216694 176