]> jfr.im git - irc/evilnet/x3.git/blob - src/modpython.py
Couple of srvx updates.
[irc/evilnet/x3.git] / src / modpython.py
1 #!/usr/bin/python
2
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
14 import _svc
15 import plugins
16
17 import math
18
19 import sys
20
21
22 class irc:
23 """Used to interact with the world of IRC from module scripts"""
24
25 # some defaults to make shorthand easy
26 caller = ''
27 target = ''
28 service = ''
29
30 def __init__(self, service = None, caller = None, target = None):
31 """ Constructor """
32 self.caller = caller #the person who sent the command/message
33 self.service = service #the service who saw the message
34 self.target = target #the channel message was in (if public)
35
36 def send_target_privmsg(self, source, target, message):
37 _svc.send_target_privmsg(source, target, "%s "%(message))
38
39 def reply(self, message):
40 """ Send a private reply to the user using convenience values"""
41 #print "DEBUG: sending a message from %s to %s: %s"%(self.service, self.caller, message)
42 if(len(self.target)):
43 self.send_target_privmsg(self.service, self.target, "%s: %s"%(self.caller, message))
44 else:
45 self.send_target_privmsg(self.service, self.caller, message)
46
47 class handler:
48 """ Main hub of python system. Handle callbacks from c. """
49
50 def __init__(self):
51 #print "DEBUG: constructor for handler initing"
52 self.plugins = plugins_(self)
53 if(not self.plugins):
54 print "DEBUG: unable to make self.plugins!?!"
55 self.newplugins = plugins.load()
56
57 def init(self, irc): # not to be confused with __init__!
58 """ This gets called once all the objects are up and running. Otherwise,
59 were not done initing this own instance to be able to start calling it """
60 #print "DEBUG: in handler.init()"
61 self.plugins.init()
62 return 0
63
64 def join(self, irc, channel, nick):
65 #user = _svc.get_user(nick)
66 #print "DEBUG: handler.join()"
67 return self.plugins.callhandler("join", irc, [channel, nick], [channel, nick])
68
69 def server_link(self, server):
70 for plugin in self.newplugins:
71 if plugin.server_link(server):
72 return 1
73 return 0
74
75 def new_user(self, user):
76 for plugin in self.newplugins:
77 if plugin.new_user(user):
78 return 1
79 return 0
80
81 def nick_change(self, user, oldnick):
82 for plugin in self.newplugins:
83 plugin.nick_change(user, oldnick)
84
85 def del_user(self, user, killer, why):
86 for plugin in self.newplugins:
87 plugin.del_user(user, killer, why)
88
89 def topic(self, who, chan, old_topic):
90 for plugin in self.newplugins:
91 if plugin.topic(who, chan, old_topic):
92 return 1
93 return 0
94
95 def cmd_run(self, irc, cmd):
96 #print "DEBUG: handler.cmd_run: %s"%cmd
97 eval(cmd)
98 return 0
99
100 def addhook(self, event, method, filter=[None], data=None):
101 self.plugins.addhook(event, method, filter, data)
102 return 0
103
104 def addcommand(self, plugin, command, method):
105 self.addhook("command", method, [plugin, command])
106
107 def cmd_command(self, irc, plugin, cmd, args):
108 #print "DEBUG: handel.cmd_command; %s %s; args= %s"%(plugin, cmd, args)
109 return self.plugins.callhandler("command", irc, [plugin, cmd], [args])
110
111 def load(self, irc, plugin):
112 return self.plugins.load(plugin)
113
114 class plugins_:
115 """Class to handle loading/unloading of plugins"""
116 loaded_plugins = {}
117 hooks = []
118
119 class hook:
120 """ This is a request from a plugin to be called on an event """
121 event = "" # Event to be called on (eg "join")
122 method = None # Method to call
123 filter = None # Arguments to filter
124 data = "" # plugin-supplied data for plugin use
125
126 def __init__(self, event, method, filter, data):
127 self.event = event
128 self.method = method
129 self.filter = filter
130 self.data = data
131
132 def event_is(self, event, evdata):
133 if(self.event == event):
134 for i in range(len(self.filter)):
135 if( self.filter[i] != None
136 and self.filter[i] != evdata[i]): # should be case insensitive? or how to compare?
137 #print "DEBUG: rejecting event, %s is not %s"%(self.filter[i], evdata[i])
138 return False
139 return True
140 else:
141 return False
142
143 def trigger(self, irc, args):
144 #print "DEBUG: Triggering %s event. with '%s' arguments."%(self.event, args)
145 self.method(irc, *args)
146
147 def __init__(self, handler):
148 """ Constructor """
149 #print "DEBUG: constructor for plugins initing"
150 self.handler = handler
151
152 def init(self):
153 #print "DEBUG: in plugins.init()"
154 self.load("annoy")
155 self.load("hangman")
156
157 def addhook(self, event, method, filter=[None], data=None):
158 #print "DEBUG: Adding hook for %s."%event
159 self.hooks.append(self.hook(event, method, filter, data))
160
161 def findhooksforevent(self, event, data):
162 ret = []
163 #print "DEBUG: findhooksforevent() looking..."
164 for hook in self.hooks:
165 #print "DEBUG: looking at a %s hook..."%hook.event
166 if(hook.event_is(event, data)):
167 ret.append(hook)
168 return ret
169
170 def callhandler(self, event, irc, filter, args):
171 for hook in self.findhooksforevent(event, filter):
172 if(hook.trigger(irc, args)):
173 return 1
174 return 0
175
176 def load(self, name):
177 """ Loads a plugin by name """
178 mod_name = "plugins.%s"%name
179 need_reload = False
180 if(sys.modules.has_key(mod_name)):
181 need_reload = True
182 #TODO: try to catch compile errors etc.
183
184 if(need_reload == False):
185 __import__(mod_name)
186 module = sys.modules[mod_name]
187 if(need_reload == True):
188 reload(module) # to ensure its read fresh
189 Class = module.Class
190 pluginObj = Class(self.handler, irc())
191 self.loaded_plugins[mod_name] = pluginObj
192 return True
193