1
2
3
4
5 """ allow data to be pickled to disk .. creating the persisted object
6 restores data
7
8 usage:
9 !plug-cfg -> shows list of all config
10 !plug-cfg key value -> sets value to key
11 !plug-cfg key -> shows list of key
12 !plug-cfg key add value -> adds value to list
13 !plug-cfg key remove value -> removes value from list
14 !plug-cfg key clear -> clears entire list
15 !plug-cfgsave -> force save configuration to disk
16
17 todo:
18 - plugin api (more work needed?)
19
20 """
21
22 __copyright__ = 'this file is in the public domain'
23 __author__ = 'Bas van Oostveen'
24
25 from gozerbot.generic import rlog, calledfrom
26 from gozerbot.persist import Persist
27 from gozerbot.commands import cmnds, Command
28 from gozerbot.examples import examples
29 from gozerbot.datadir import datadir
30 import sys, os, types, time
31
33
34 - def __init__(self, value, desc, perm, example, name, exposed):
35 assert isinstance(name, str), "Option.self.name must be a string"
36 self.value = value
37 self.desc = desc
38 self.perm = perm
39 self.example = example
40 self.name = name.lower()
41 self.exposed = exposed
42
44
45 if not hasattr(self, name):
46 setattr(self, name, val)
47 return True
48 else:
49
50 if val != None and type(getattr(self, name)) != type(val):
51 setattr(self, name, val)
52 return True
53 return False
54
55 - def check(self, key, plugname, value, desc, perm, example, name, exposed):
56 upd = False
57
58 if self.__casattr__("value", value): upd = True
59 if self.__casattr__("example", example): upd = True
60 if self.__casattr__("name", name): upd = True
61 if self.__casattr__("perm", perm): upd = True
62 if self.__casattr__("exposed", exposed): upd = True
63 if self.name == None:
64 self.name = "%s-cfg-%s" % (plugname, str(key))
65 upd = True
66 return upd
67
69 return self.value < other
70
72 return self.value <= other
73
75 return self.value == other
76
78 return self.value != other
79
81 return self.value >= other
82
84 return self.value >= other
85
87
88 """ emulates the normal Persist.data (key, value) dict """
89
92
94 return len(self.__persistData)
95
97 return self.__cfg.data[key].value
98
100 if not self.__cfg.data.has_key(key) or not \
101 isinstance(self.__cfg.data[key], Option):
102 name = "%s-cfg-%s" % (self.__cfg.plugname, str(key))
103 self.__cfg.define(value, "", 'OPER', "", name, exposed=False)
104 self.__cfg.set(key, value)
105
107 raise Exception("Direct deletion not supported, use \
108 persistConfig.undefine()")
109
112
115
117 return self.__cfg.data.has_key(item)
118
120
122
123 """ persist plugin configuration and create default handlers """
124
126 self.__basename__ = self.__class__.__name__
127 self.plugname = calledfrom(sys._getframe())
128 Persist.__init__(self, os.path.join(datadir, "%s-config" % \
129 self.plugname), {})
130 self.__callbacks = {}
131 cmndname = "%s-cfg" % self.plugname
132 rlog(-3, 'persistconfig', 'added command %s (%s)' % (cmndname, \
133 self.plugname))
134 cmnds[cmndname] = Command(self.cmnd_cfg, 'OPER', self.plugname, \
135 threaded=True)
136 examples.add(cmndname, "plugin configuration", cmndname)
137 cmndnamesave = cmndname + "save"
138 cmnds[cmndnamesave] = Command(self.cmnd_cfgsave, 'OPER', \
139 self.plugname, threaded=True)
140 examples.add(cmndnamesave, "save plugin configuration", cmndnamesave)
141
154
156 if self.__callbacks.has_key((key, event)):
157 cb, extra_data = self.__callbacks[(key, event)]
158 if callable(cb):
159 cb(key, value, event, extra_data)
160 else:
161 rlog(5, 'persistconfig', 'invalid callback for %s %s' % (key, \
162 event))
163 del self.__callbacks[(key, event)]
164
165
166
168 s = []
169 for key, option in sorted(self.data.items()):
170 if not isinstance(option, Option):
171 rlog(5, 'persistconfig', 'Option %s is not a valid option' % \
172 key)
173 continue
174 if not option.exposed:
175 continue
176 v = option.value
177 if type(v) in [str, unicode]:
178 v = '"'+v+'"'
179 v = str(v)
180 s.append("%s=%s" % (key, v))
181 ievent.reply("options: " + ' .. '.join(s))
182
184 self.save()
185 ievent.reply("config saved")
186
188 if type(option.value) == types.ListType:
189 if args[0].startswith("[") and args[-1].endswith("]"):
190 values = []
191 for v in ' '.join(args)[1:-1].replace(", ", ",").split(","):
192 if v[0]=='"' and v[-1]=='"':
193
194 v = v.replace('"', '')
195 elif v[0]=="'" and v[-1]=="'":
196
197 v = v.replace("'", "")
198 elif '.' in v:
199
200 try:
201 v = float(v)
202 except ValueError:
203 ievent.reply("invalid long literal: %s" % v)
204 return
205 else:
206
207 try:
208 v = int(v)
209 except ValueError:
210 ievent.reply("invalid int literal: %s" % v)
211 return
212 values.append(v)
213 self.set(key, values)
214 ievent.reply("%s set %s" % (key, values))
215 return
216 command = args[0]
217 value = ' '.join(args[1:])
218 if command == "clear":
219 self.clear(key)
220 ievent.reply("list empty")
221 elif command == "add":
222 self.append(key, value)
223 ievent.reply("%s added %s" % (key, value))
224 elif command == "remove" or command == "del":
225 try:
226 self.remove(key, value)
227 ievent.reply("%s removed" % str(value))
228 except ValueError:
229 ievent.reply("%s is not in list" % str(value))
230 else:
231 ievent.reply("invalid command")
232 return
233 else:
234 value = ' '.join(args)
235 try:
236 value = type(option.value)(value)
237 except:
238 pass
239 if type(value) == type(option.value):
240 self.set(key, value)
241 ievent.reply("%s set" % key)
242 elif type(value) == types.LongType and \
243 type(option.value) == types.IntType:
244
245 self.set(key, value)
246 ievent.reply("%s set" % key)
247 else:
248 ievent.reply("value %s (%s) is not of the same type as %s \
249 (%s)" % (value, type(value), option.value, type(option.value)))
250
252 if not ievent.args:
253 self.show_cfg(bot, ievent)
254 return
255 argc = len(ievent.args)
256 key = ievent.args[0]
257 try:
258 option = self.data[key]
259 except KeyError:
260 ievent.reply("%s option %s not found" % (self.plugname, key))
261 return
262 if not isinstance(option, Option):
263 rlog(5, 'persistconfig', 'Option %s is not a valid option' % key)
264 return
265 if not option.exposed:
266 return
267 if argc == 1:
268 ievent.reply(str(option.value))
269 return
270 self.cmnd_cfg_edit(bot, ievent, ievent.args[1:], key, option)
271
273 def func(bot, ievent):
274 try:
275 option = self.data[key]
276 except KeyError:
277 ievent.reply("%s not found" % key)
278
279 if not isinstance(option, Option):
280 rlog(5, 'persistconfig', 'Option %s is not a valid option' % \
281 key)
282 return
283 if ievent.args:
284 value = ' '.join(ievent.args)
285 try:
286 value = type(option.value)(value)
287 except:
288 pass
289 self.cmnd_cfg_edit(bot, ievent, ievent.args, key, option)
290 else:
291 ievent.reply(str(option.value))
292 return func
293
294
295
296 - def define(self, key, value=None, desc="plugin option", perm='OPER', \
297 example="", name=None, exposed=True):
298 if name:
299 name = name.lower()
300 if not self.data.has_key(key):
301 if name == None:
302 name = "%s-cfg-%s" % (self.plugname, str(key))
303 option = Option(value, desc, perm, example, name, exposed)
304 self.data[key] = option
305 self.save()
306 else:
307 option = self.data[key]
308
309
310
311
312 if not isinstance(option, Option):
313