Merge lp:~isoschiz/endroid/cmd-and-help-changes into lp:endroid
- cmd-and-help-changes
- Merge into trunk
Proposed by
Martin Morrison
Status: | Merged |
---|---|
Approved by: | Martin Morrison |
Approved revision: | 35 |
Merged at revision: | 25 |
Proposed branch: | lp:~isoschiz/endroid/cmd-and-help-changes |
Merge into: | lp:endroid |
Diff against target: |
691 lines (+249/-139) 19 files modified
debian/changelog (+7/-0) debian/control (+1/-1) debian/endroid.install (+0/-17) debian/rules (+3/-1) etc/endroid.conf (+2/-0) etc/init/endroid.conf (+1/-1) setup.py (+14/-0) src/endroid/__init__.py (+2/-0) src/endroid/cron.py (+0/-1) src/endroid/plugins/blacklist.py (+3/-5) src/endroid/plugins/chuck.py (+7/-14) src/endroid/plugins/command.py (+85/-9) src/endroid/plugins/coolit.py (+15/-0) src/endroid/plugins/correct.py (+4/-6) src/endroid/plugins/echobot.py (+1/-6) src/endroid/plugins/help.py (+59/-35) src/endroid/plugins/theyfightcrime.py (+5/-21) src/endroid/plugins/unhandled.py (+38/-20) src/endroid/wokkelhandler.py (+2/-2) |
To merge this branch: | bzr merge lp:~isoschiz/endroid/cmd-and-help-changes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Morrison | Approve | ||
Review via email: mp+122425@code.launchpad.net |
Commit message
Merge changes in to handle actually building successful packages on both lucid and later distros (along with misc other fixes).
Description of the change
To post a comment you must log in.
Revision history for this message
Martin Morrison (isoschiz) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2012-08-31 19:21:34 +0000 |
3 | +++ debian/changelog 2012-09-02 21:51:19 +0000 |
4 | @@ -1,3 +1,10 @@ |
5 | +endroid (1.1.1) lucid; urgency=low |
6 | + |
7 | + * Improved build system (to support multiple Python versions) |
8 | + * Improvements to plugin APIs - especially for command-based plugins, and help |
9 | + |
10 | + -- Martin Morrison <martin.morrison@ensoft.co.uk> Fri, 02 Sep 2012 22:00:00 +0100 |
11 | + |
12 | endroid (1.1) lucid; urgency=low |
13 | |
14 | * Enhanced Help system |
15 | |
16 | === modified file 'debian/control' (properties changed: +x to -x) |
17 | --- debian/control 2012-08-13 22:27:22 +0000 |
18 | +++ debian/control 2012-09-02 21:51:19 +0000 |
19 | @@ -2,7 +2,7 @@ |
20 | Maintainer: Jonathan Millican <jonathanrm@ensoft.co.uk> |
21 | Section: misc |
22 | Priority: optional |
23 | -Build-Depends: debhelper (>= 7) |
24 | +Build-Depends: debhelper (>= 7), python |
25 | Standards-Version: 3.8.4 |
26 | |
27 | Package: endroid |
28 | |
29 | === modified file 'debian/endroid.install' |
30 | --- debian/endroid.install 2012-08-13 22:27:22 +0000 |
31 | +++ debian/endroid.install 2012-09-02 21:51:19 +0000 |
32 | @@ -1,21 +1,4 @@ |
33 | etc/endroid.conf etc/endroid/ |
34 | etc/init/endroid.conf etc/init/ |
35 | bin/endroid usr/bin/ |
36 | -src/endroid/__init__.py usr/lib/pymodules/python2.6/endroid |
37 | -src/endroid/config.py usr/lib/pymodules/python2.6/endroid |
38 | -src/endroid/cron.py usr/lib/pymodules/python2.6/endroid |
39 | -src/endroid/database.py usr/lib/pymodules/python2.6/endroid |
40 | -src/endroid/messagehandler.py usr/lib/pymodules/python2.6/endroid |
41 | -src/endroid/pluginmanager.py usr/lib/pymodules/python2.6/endroid |
42 | -src/endroid/rosterhandler.py usr/lib/pymodules/python2.6/endroid |
43 | -src/endroid/usermanagement.py usr/lib/pymodules/python2.6/endroid |
44 | -src/endroid/wokkelhandler.py usr/lib/pymodules/python2.6/endroid |
45 | -src/endroid/plugins/__init__.py usr/lib/pymodules/python2.6/endroid/plugins |
46 | -src/endroid/plugins/command.py usr/lib/pymodules/python2.6/endroid/plugins |
47 | -src/endroid/plugins/echobot.py usr/lib/pymodules/python2.6/endroid/plugins |
48 | -src/endroid/plugins/help.py usr/lib/pymodules/python2.6/endroid/plugins |
49 | -src/endroid/plugins/patternmatcher.py usr/lib/pymodules/python2.6/endroid/plugins |
50 | -src/endroid/plugins/speak.py usr/lib/pymodules/python2.6/endroid/plugins |
51 | -src/endroid/plugins/unhandled.py usr/lib/pymodules/python2.6/endroid/plugins |
52 | -src/endroid/plugins/whosonline.py usr/lib/pymodules/python2.6/endroid/plugins |
53 | lib/wokkel-0.7.0-py2.7.egg usr/lib/endroid/dependencies |
54 | |
55 | === modified file 'debian/rules' |
56 | --- debian/rules 2012-08-13 22:27:22 +0000 |
57 | +++ debian/rules 2012-09-02 21:51:19 +0000 |
58 | @@ -1,4 +1,6 @@ |
59 | #!/usr/bin/make -f |
60 | |
61 | +WITH_PYTHON2 = $(shell test -f /usr/bin/dh_python2 && echo "--with python2") |
62 | + |
63 | %: |
64 | - dh $@ |
65 | + dh ${WITH_PYTHON2} $@ |
66 | |
67 | === modified file 'etc/endroid.conf' |
68 | --- etc/endroid.conf 2012-08-30 22:53:47 +0000 |
69 | +++ etc/endroid.conf 2012-09-02 21:51:19 +0000 |
70 | @@ -5,8 +5,10 @@ |
71 | |
72 | plugins = |
73 | endroid.plugins.blacklist |
74 | + endroid.plugins.chuck |
75 | endroid.plugins.command |
76 | endroid.plugins.compute |
77 | + endroid.plugins.coolit |
78 | endroid.plugins.correct |
79 | endroid.plugins.echobot |
80 | endroid.plugins.help |
81 | |
82 | === modified file 'etc/init/endroid.conf' |
83 | --- etc/init/endroid.conf 2012-08-13 22:27:22 +0000 |
84 | +++ etc/init/endroid.conf 2012-09-02 21:51:19 +0000 |
85 | @@ -1,7 +1,7 @@ |
86 | description "EnDroid XMPP bot" |
87 | author "Ensoft Limited" |
88 | |
89 | -exec /usr/bin/endroid /etc/endroid/endroid.conf |
90 | +exec /usr/bin/endroid -L /var/log/endroid.log /etc/endroid/endroid.conf |
91 | start on net-device-up |
92 | stop on stopping network |
93 | stop on starting shutdown |
94 | |
95 | === added file 'setup.py' |
96 | --- setup.py 1970-01-01 00:00:00 +0000 |
97 | +++ setup.py 2012-09-02 21:51:19 +0000 |
98 | @@ -0,0 +1,14 @@ |
99 | +#!/usr/bin/env python |
100 | +# |
101 | +# EnDroid setup file |
102 | +# |
103 | + |
104 | +from distutils.core import setup |
105 | + |
106 | +setup(name='endroid', |
107 | + version="1.1", |
108 | + description='EnDroid: a modular XMPP bot', |
109 | + url='http://open.ensoft.co.uk/EnDroid', |
110 | + packages=['endroid', 'endroid.plugins'], |
111 | + package_dir={'endroid': 'src/endroid'}, |
112 | + ) |
113 | |
114 | === modified file 'src/endroid/__init__.py' |
115 | --- src/endroid/__init__.py 2012-09-01 23:15:55 +0000 |
116 | +++ src/endroid/__init__.py 2012-09-02 21:51:19 +0000 |
117 | @@ -25,6 +25,8 @@ |
118 | from endroid.pluginmanager import PluginManager |
119 | from endroid.cron import Cron |
120 | |
121 | +__version__ = (1, 1) |
122 | + |
123 | class Endroid(object): |
124 | def __init__(self, conffile, logtraffic=False): |
125 | self.application = service.Application("EnDroid") |
126 | |
127 | === modified file 'src/endroid/cron.py' |
128 | --- src/endroid/cron.py 2012-08-08 23:58:18 +0000 |
129 | +++ src/endroid/cron.py 2012-09-02 21:51:19 +0000 |
130 | @@ -71,7 +71,6 @@ |
131 | |
132 | |
133 | def _do_crons(self): |
134 | - print "Running Crons" |
135 | # curtime = datetime.now(timezone('GMT')) |
136 | delays = self.db.fetch('cron_delay', ['timestamp', 'fun_name', 'params', 'rowid']) |
137 | set_times = self.db.fetch('cron_datetime', ['datetime', 'fun_name', 'params', 'locality', 'rowid']) |
138 | |
139 | === modified file 'src/endroid/plugins/blacklist.py' |
140 | --- src/endroid/plugins/blacklist.py 2012-08-30 22:53:47 +0000 |
141 | +++ src/endroid/plugins/blacklist.py 2012-09-02 21:51:19 +0000 |
142 | @@ -9,8 +9,6 @@ |
143 | from endroid.cron import Cron |
144 | from endroid.config import as_list |
145 | |
146 | -import logging |
147 | - |
148 | # DB constants |
149 | DB_NAME = "Blacklist" |
150 | DB_TABLE = "Blacklist" |
151 | @@ -25,10 +23,10 @@ |
152 | list is silently dropped, without allowing any handlers to be called for |
153 | them. |
154 | """ |
155 | - name = "blacklist" |
156 | + help = "Maintain a blacklist of JIDs who get ignored by EnDroid." |
157 | hidden = True |
158 | |
159 | - def enInit(self): |
160 | + def endroid_init(self): |
161 | """ |
162 | Initialise the plugin, and recover the blacklist from the DB. |
163 | """ |
164 | @@ -76,7 +74,7 @@ |
165 | if cmd == "add" and user not in self._blacklist: |
166 | self.blacklist(user) |
167 | elif cmd == "remove" and user in self._blacklist: |
168 | - self.blacklist(user) |
169 | + self.unblacklist(user) |
170 | elif cmd == "list": |
171 | msg.reply("Blacklist: " + ", ".join(self._blacklist)) |
172 | else: |
173 | |
174 | === modified file 'src/endroid/plugins/chuck.py' |
175 | --- src/endroid/plugins/chuck.py 2012-09-01 23:15:55 +0000 |
176 | +++ src/endroid/plugins/chuck.py 2012-09-02 21:51:19 +0000 |
177 | @@ -6,25 +6,18 @@ |
178 | import re |
179 | from HTMLParser import HTMLParser |
180 | from twisted.web.client import getPage |
181 | -from endroid.pluginmanager import Plugin |
182 | +from endroid.plugins.command import CommandPlugin |
183 | |
184 | FACTRE = re.compile(r'<div id="wia_factBox">(.*?)</p>', re.S) |
185 | |
186 | -class Chuck(Plugin): |
187 | - name = "chucknorris" |
188 | - dependencies = ('endroid.plugins.command',) |
189 | +class ChuckNorris(CommandPlugin): |
190 | help = "Get a random Chuck Norris fact." |
191 | |
192 | - def endroid_init(self): |
193 | - com, = self.get_dependencies() |
194 | - com.register_both(self.chuck, 'chuck', |
195 | - synonyms=('norris', 'chucknorris')) |
196 | - |
197 | - def chuck(self, msg, arg): |
198 | - def fact(data): |
199 | - h = HTMLParser() |
200 | + def cmd_chuck(self, msg, arg): |
201 | + def extract_fact(data): |
202 | fact = re.sub(r"<.*?>", "", FACTRE.search(data).group(1)).strip() |
203 | - msg.reply("Fact: {0}".format(h.unescape(fact.strip()))) |
204 | + msg.reply("Fact: {0}".format(HTMLParser().unescape(fact.strip()))) |
205 | |
206 | - getPage("http://www.whatisawesome.com/chuck").addCallbacks(fact, |
207 | + getPage("http://www.whatisawesome.com/chuck").addCallbacks(extract_fact, |
208 | msg.unhandled) |
209 | + cmd_chuck.synonyms = ('norris', 'chucknorris') |
210 | |
211 | === modified file 'src/endroid/plugins/command.py' |
212 | --- src/endroid/plugins/command.py 2012-09-01 23:15:55 +0000 |
213 | +++ src/endroid/plugins/command.py 2012-09-02 21:51:19 +0000 |
214 | @@ -7,7 +7,11 @@ |
215 | import logging |
216 | |
217 | from collections import namedtuple |
218 | -from endroid.pluginmanager import Plugin |
219 | +from endroid.pluginmanager import Plugin, PluginMeta |
220 | + |
221 | +__all__ = ( |
222 | + 'CommandPlugin', |
223 | + ) |
224 | |
225 | # A single registration |
226 | # - callback is the registered callback function |
227 | @@ -22,6 +26,51 @@ |
228 | # - subcommands is a dict of subcommand (simple str) to Handlers object |
229 | Handlers = namedtuple('Handlers', ('handlers', 'subcommands')) |
230 | |
231 | +class CommandPluginMeta(PluginMeta): |
232 | + """ |
233 | + Metaclass to support simple command-driven plugins. This should not be used |
234 | + directly, but rather by subclassing from CommandPlugin rather than Plugin. |
235 | + """ |
236 | + def __new__(meta, name, bases, dct): |
237 | + cmds = dict((c, f) for c, f in dct.items() if c.startswith("cmd_")) |
238 | + init = dct.get('endroid_init', lambda _: None) |
239 | + def endroid_init(self): |
240 | + com = self.get('endroid.plugins.command') |
241 | + for cmd, fn in cmds.items(): |
242 | + if getattr(fn, "chat_only", False): |
243 | + reg_fn = com.register_chat |
244 | + elif getattr(fn, "muc_only", False): |
245 | + reg_fn = com.register_muc |
246 | + else: |
247 | + reg_fn = com.register_both |
248 | + reg_fn(getattr(self, cmd), cmd.split("_")[1:], |
249 | + helphint=getattr(fn, "helphint", ""), |
250 | + hidden=getattr(fn, "hidden", False), |
251 | + synonyms=getattr(fn, "synonyms", ())) |
252 | + init(self) |
253 | + dct['endroid_init'] = endroid_init |
254 | + dct['dependencies'] = tuple(dct.get('dependencies', ()) + |
255 | + ('endroid.plugins.command',)) |
256 | + return PluginMeta.__new__(meta, name, bases, dct) |
257 | + |
258 | +class CommandPlugin(Plugin): |
259 | + """ |
260 | + Parent class for simple command-driven plugins. Such plugins don't need to |
261 | + explicitly register their commands. Instead, they can just define methods |
262 | + prefixed with "cmd_" and they will automatically be registered. Any |
263 | + additional underscores in the method name will be converted to spaces in |
264 | + the registration (so cmd_foo_bar is registered as ('foo', 'bar')). |
265 | + |
266 | + In addition, certain options can be passed by adding fields to the methods: |
267 | + - hidden: don't show the command in help if set to True. |
268 | + - synonyms: an iterable of alternative keyword sequences to register the |
269 | + method against. All synonyms are hidden. |
270 | + - helphint: a hint to print after the keywords in help output. |
271 | + - muc_only or chat_only: register for only chat or muc messages (default is |
272 | + both). |
273 | + """ |
274 | + __metaclass__ = CommandPluginMeta |
275 | + |
276 | class Command(Plugin): |
277 | """ |
278 | Helper plugin to handle command registrations by other plugins. This is |
279 | @@ -29,13 +78,20 @@ |
280 | and it is expected most plugins will depend on this. |
281 | """ |
282 | name = "commands" |
283 | + hidden = True # This plugin is built in to the help module |
284 | |
285 | - def enInit(self): |
286 | + def endroid_init(self): |
287 | self._muc_handlers = Handlers([], {}) |
288 | self._chat_handlers = Handlers([], {}) |
289 | self.register_muc_callback(self.command_muc) |
290 | self.register_chat_callback(self.command_chat) |
291 | |
292 | + self._topics = { |
293 | + '': self.help_main, |
294 | + 'chat': self.help_chat, |
295 | + 'muc': self.help_muc, |
296 | + } |
297 | + |
298 | # ------------------------------------------------------------------------- |
299 | # Help methods |
300 | |
301 | @@ -47,21 +103,42 @@ |
302 | """ |
303 | for reg in handlers.handlers: |
304 | if not reg.hidden: |
305 | - output.append("%s %s" % (reg.command, reg.helphint)) |
306 | + output.append(" %s %s" % (reg.command, reg.helphint)) |
307 | for _, hdlrs in sorted(handlers.subcommands.items()): |
308 | self.help_add_regs(output, hdlrs) |
309 | |
310 | - def help(self): |
311 | - out = ["Command Module Help:", ""] |
312 | + def help(self, topic): |
313 | + topics = topic.strip().split(' ', 1) |
314 | + topic, extra = topics[0], "".join(topics[1:]) |
315 | + if topic in self._topics: |
316 | + return self._topics[topic](extra) |
317 | + |
318 | + def help_main(self, topic): |
319 | + assert not topic |
320 | + out = ["Commands known to me:"] |
321 | + chat = self.help_chat(topic) |
322 | + if chat: |
323 | + out.extend(["", chat]) |
324 | + muc = self.help_muc(topic) |
325 | + if muc: |
326 | + out.extend(["", muc]) |
327 | + return "\n".join(out) |
328 | + |
329 | + def help_chat(self, topic): |
330 | parts = [] |
331 | self.help_add_regs(parts, self._chat_handlers) |
332 | if parts: |
333 | - out.extend(["\nCommands in Chat:"] + parts) |
334 | + return "\n".join(["Commands in Chat:"] + parts) |
335 | + else: |
336 | + return "No command registered in chat." |
337 | + |
338 | + def help_muc(self, topic): |
339 | parts = [] |
340 | self.help_add_regs(parts, self._muc_handlers) |
341 | if parts: |
342 | - out.extend(["\nCommands in MUC:"] + parts) |
343 | - return "\n".join(out) |
344 | + return "\n".join(["Commands in MUC:"] + parts) |
345 | + else: |
346 | + return "No commands registed in MUC." |
347 | |
348 | # ------------------------------------------------------------------------- |
349 | # Command handling methods |
350 | @@ -139,4 +216,3 @@ |
351 | """Register a handler for both MUC and chat messages.""" |
352 | self.register_muc(callback, command, helphint, hidden, synonyms) |
353 | self.register_chat(callback, command, helphint, hidden, synonyms) |
354 | - |
355 | |
356 | === added file 'src/endroid/plugins/coolit.py' |
357 | --- src/endroid/plugins/coolit.py 1970-01-01 00:00:00 +0000 |
358 | +++ src/endroid/plugins/coolit.py 2012-09-02 21:51:19 +0000 |
359 | @@ -0,0 +1,15 @@ |
360 | +# ----------------------------------------------------------------------------- |
361 | +# EnDroid - Cool it Plugin |
362 | +# Copyright 2012, Ensoft Ltd |
363 | +# ----------------------------------------------------------------------------- |
364 | + |
365 | +from endroid.plugins.command import CommandPlugin |
366 | + |
367 | +class CoolIt(CommandPlugin): |
368 | + help = "I'm a robot. I'm not a refrigerator." |
369 | + hidden = True |
370 | + |
371 | + def cmd_coolit(self, msg, args): |
372 | + msg.reply(self.help) |
373 | + cmd_coolit.hidden = True |
374 | + cmd_coolit.synonyms = ('cool it',) |
375 | |
376 | === modified file 'src/endroid/plugins/correct.py' |
377 | --- src/endroid/plugins/correct.py 2012-08-13 17:25:40 +0000 |
378 | +++ src/endroid/plugins/correct.py 2012-09-02 21:51:19 +0000 |
379 | @@ -17,15 +17,13 @@ |
380 | last message heard from the sender using that regex. |
381 | """ |
382 | name = "correct" |
383 | + help = "Correct typos using s/<regex>/<replace>/[gi]" |
384 | |
385 | - def enInit(self): |
386 | + def endroid_init(self): |
387 | self.lastmsg = {} |
388 | self.register_chat_callback(self.heard) |
389 | self.register_muc_callback(self.heard) |
390 | |
391 | - def help(self): |
392 | - return "Correct typos using s/<regex>/<replace>/[gi]" |
393 | - |
394 | def heard(self, msg): |
395 | """ |
396 | Monitors all received messages to track the last message from each |
397 | @@ -46,8 +44,8 @@ |
398 | matches in the match object (given in 'match'). Replies are sent via |
399 | the given 'msg' (so either to the room or original sender). |
400 | |
401 | - The regular expression support full Python regex syntax; the |
402 | - replacement group support backreferences using \1 or \g<1> syntax; two |
403 | + The regular expressions support full Python regex syntax; the |
404 | + replacement group supports backreferences using \1 or \g<1> syntax; two |
405 | flags are supported: i for case-insensitive, and g for global |
406 | replacements. |
407 | """ |
408 | |
409 | === modified file 'src/endroid/plugins/echobot.py' |
410 | --- src/endroid/plugins/echobot.py 2012-08-02 12:34:17 +0000 |
411 | +++ src/endroid/plugins/echobot.py 2012-09-02 21:51:19 +0000 |
412 | @@ -7,14 +7,9 @@ |
413 | from endroid.pluginmanager import Plugin |
414 | |
415 | class EchoBot(Plugin): |
416 | - name = "echo" |
417 | - |
418 | - def enInit(self): |
419 | + def endroid_plugin(self): |
420 | self.register_chat_callback(self.do_echo) |
421 | self.register_muc_callback(self.do_echo) |
422 | |
423 | def do_echo(self, msg): |
424 | msg.reply(msg.body) |
425 | - |
426 | -def get_plugin(): |
427 | - return EchoBot() |
428 | |
429 | === modified file 'src/endroid/plugins/help.py' |
430 | --- src/endroid/plugins/help.py 2012-09-01 23:15:55 +0000 |
431 | +++ src/endroid/plugins/help.py 2012-09-02 21:51:19 +0000 |
432 | @@ -7,14 +7,19 @@ |
433 | |
434 | class Help(Plugin): |
435 | name = "help" |
436 | - |
437 | - def dependencies(self): |
438 | - return ('endroid.plugins.command',) |
439 | - |
440 | - def enInit(self): |
441 | - com = self.get('endroid.plugins.command') |
442 | + dependencies = ('endroid.plugins.command',) |
443 | + help = "DON'T PANIC!" |
444 | + |
445 | + def endroid_init(self): |
446 | + com, = self.get_dependencies() |
447 | com.register_both(self.show_help, 'help') |
448 | |
449 | + self._topics = { |
450 | + '': self.show_help_main, |
451 | + 'plugins': self.show_help_plugins, |
452 | + 'commands': self.show_help_commands, |
453 | + } |
454 | + |
455 | self.load_plugin_list() |
456 | |
457 | def load_plugin_list(self): |
458 | @@ -23,39 +28,58 @@ |
459 | plugin = self.get(fullname) |
460 | name = getattr(plugin, "name", fullname) |
461 | self.plugins[name] = (fullname, plugin) |
462 | - |
463 | + |
464 | def show_help(self, msg, args): |
465 | + topics = args.split(' ', 1) |
466 | + if topics[0] in self._topics: |
467 | + self._topics[topics[0]](msg, "".join(topics[1:])) |
468 | + else: |
469 | + name, topic = topics[0], "".join(topics[1:]) |
470 | + self.show_help_plugin(msg, name, topic) |
471 | + |
472 | + def show_help_main(self, msg, topic): |
473 | + assert not topic |
474 | out = [] |
475 | - if not args.strip(): |
476 | - out.append("Help Module. Plugins Loaded:") |
477 | + out.append("EnDroid at your service! Help topics:") |
478 | + out.append(" plugins - list loaded plugins") |
479 | + out.append(" commands - list supported commands") |
480 | + out.append(" <pluginname> - help provided by the given plugin") |
481 | + msg.reply_to_sender("\n".join(out)) |
482 | + |
483 | + def show_help_plugins(self, msg, topic): |
484 | + if topic.strip(): |
485 | + # specific plugin? |
486 | + topics = topic.split(" ", 1) |
487 | + name, topic = topics[0], "".join(topics[1:]) |
488 | + self.show_help_plugin(msg, name, topic) |
489 | + else: |
490 | + out = [] |
491 | + out.append("Currently loaded plugins:") |
492 | for name, (_, plug) in sorted(self.plugins.items()): |
493 | if not getattr(plug, "hidden", False): |
494 | - out.append(name) |
495 | + out.append(" {0}".format(name)) |
496 | + msg.reply_to_sender("\n".join(out)) |
497 | + |
498 | + def show_help_commands(self, msg, topic): |
499 | + self.show_help_plugin(msg, "commands", topic) |
500 | + |
501 | + def show_help_plugin(self, msg, name, topic): |
502 | + out = [] |
503 | + fullname, plugin = self.plugins.get(name, (name, None)) |
504 | + if self.pluginLoaded(fullname): |
505 | + if plugin.hasattr("help"): |
506 | + try: |
507 | + out.append(plugin.help(topic)) |
508 | + except TypeError: |
509 | + if topic: |
510 | + out.append("(Plugin doesn't support topic help)") |
511 | + if callable(plugin.help): |
512 | + out.append(plugin.help()) |
513 | + else: |
514 | + out.append(str(plugin.help)) |
515 | + else: |
516 | + out.append("Plugin {0} has no help provided".format(name)) |
517 | else: |
518 | - splitsies = args.split(' ', 1) |
519 | - if len(splitsies) > 1: |
520 | - name, topic = splitsies |
521 | - else: |
522 | - name, topic = splitsies[0], "" |
523 | - |
524 | - fullname, plugin = self.plugins.get(name, (name, None)) |
525 | - if self.pluginLoaded(fullname): |
526 | - if plugin.hasattr("help"): |
527 | - try: |
528 | - out.append(plugin.help(topic)) |
529 | - except TypeError: |
530 | - if topic: |
531 | - out.append("(Plugin doesn't support topic help)") |
532 | - if callable(plugin.help): |
533 | - out.append(plugin.help()) |
534 | - else: |
535 | - out.append(str(plugin.help)) |
536 | - else: |
537 | - out.append("Plugin {0} has no help provided".format(name)) |
538 | - else: |
539 | - out.append("Plugin {0} is not loaded".format(name)) |
540 | + out.append("Plugin {0} is not loaded".format(name)) |
541 | |
542 | msg.reply_to_sender('\n'.join(out)) |
543 | - |
544 | - def help(self): |
545 | - return "DON'T PANIC!" |
546 | |
547 | === modified file 'src/endroid/plugins/theyfightcrime.py' |
548 | --- src/endroid/plugins/theyfightcrime.py 2012-08-31 12:10:51 +0000 |
549 | +++ src/endroid/plugins/theyfightcrime.py 2012-09-02 21:51:19 +0000 |
550 | @@ -10,10 +10,8 @@ |
551 | # Note: that plugin doesn't seem to have an explicit license, but rbot's |
552 | # license can be seen at http://ruby-rbot.org/rbot-trac/browser/COPYING.rbot |
553 | |
554 | -import logging |
555 | import random |
556 | - |
557 | -from endroid.pluginmanager import Plugin |
558 | +from endroid.plugins.command import CommandPlugin |
559 | |
560 | MALE_OPTIONS = ( |
561 | ('a superhumanly strong', 'an underprivileged', 'a globe-trotting', |
562 | @@ -154,28 +152,17 @@ |
563 | |
564 | ) |
565 | |
566 | -class TheyFightCrime(Plugin): |
567 | +class TheyFightCrime(CommandPlugin): |
568 | """ |
569 | Generates random movie titles and plots. |
570 | """ |
571 | - name = "theyfightcrime" |
572 | - |
573 | - def enInit(self): |
574 | - com = self.get('endroid.plugins.command') |
575 | - com.register_both(self.plot, ('movie', 'plot')) |
576 | - com.register_both(self.title, ('movie', 'title')) |
577 | - |
578 | - def dependencies(self): |
579 | - return ('endroid.plugins.command',) |
580 | - |
581 | - def help(self): |
582 | - return "Generate a random movie scenario." |
583 | + help = "Generate a random movie scenario." |
584 | |
585 | @staticmethod |
586 | def get_random_things(things): |
587 | return " ".join(map(random.choice, things)) |
588 | |
589 | - def plot(self, msg, arg): |
590 | + def cmd_movie_plot(self, msg, arg): |
591 | """ |
592 | Generate a plot for a movie. |
593 | """ |
594 | @@ -183,11 +170,8 @@ |
595 | (self.get_random_things(MALE_OPTIONS), |
596 | self.get_random_things(FEMALE_OPTIONS))) |
597 | |
598 | - def title(self, msg, arg): |
599 | + def cmd_movie_title(self, msg, arg): |
600 | """ |
601 | Generate a new movie title. |
602 | """ |
603 | msg.reply("Title: %s" % self.get_random_things(TITLE_OPTIONS)) |
604 | - |
605 | -def get_plugin(): |
606 | - return TheyFightCrime() |
607 | |
608 | === modified file 'src/endroid/plugins/unhandled.py' |
609 | --- src/endroid/plugins/unhandled.py 2012-08-12 14:31:22 +0000 |
610 | +++ src/endroid/plugins/unhandled.py 2012-09-02 21:51:19 +0000 |
611 | @@ -1,27 +1,45 @@ |
612 | +# ----------------------------------------------------------------------------- |
613 | +# EnDroid - Plugin to respond to unhandled messages |
614 | +# Copyright 2012, Ensoft Ltd |
615 | +# ----------------------------------------------------------------------------- |
616 | + |
617 | from datetime import date |
618 | import random |
619 | from endroid.pluginmanager import Plugin |
620 | |
621 | class UnHandled(Plugin): |
622 | name = "unhandled" |
623 | - messages = ["404 Error: message not found",\ |
624 | - "Command not found, perhaps it can be found in the bottom of a locked filing cabinet stuck in a disused lavatory with a sign on the door saying Beware of the Leopard?",\ |
625 | - "Command not found. Don't Panic!",\ |
626 | - "I'm afraid I lost my Babel fish, please translate command into EnDroid.",\ |
627 | - "As you will no doubt be aware, the plans for development of the outlying regions of the Galaxy require the building of a hyperspatial express route through my code for that command.",\ |
628 | - "I seem to be having this tremendous difficulty with my lifestyle. As soon as I reach some kind of definite policy about what is my kind of music and my kind of restaurant and my kind of overdraft, people start blowing up my kind of planet, throwing me out of their kind of spaceships, and entering unrecognized commands!",\ |
629 | - "I'm afraid I won't execute that command without an order, signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters."] |
630 | - |
631 | - def __init__(self): |
632 | + help = "I'm a personality prototype. You can tell, can't you...?" |
633 | + |
634 | + messages = [ |
635 | + "404 Error: message not found", |
636 | + "Command not found, perhaps it can be found in the bottom of a locked " |
637 | + "filing cabinet stuck in a disused lavatory with a sign on the door " |
638 | + "saying Beware of the Leopard?", |
639 | + "Command not found. Don't Panic!", |
640 | + "I'm afraid I lost my Babel fish, please translate command into " |
641 | + "EnDroid.", |
642 | + "As you will no doubt be aware, the plans for development of the " |
643 | + "outlying regions of the Galaxy require the building of a " |
644 | + "hyperspatial express route through my code for that command.", |
645 | + "I seem to be having this tremendous difficulty with my lifestyle. As " |
646 | + "soon as I reach some kind of definite policy about what is my kind " |
647 | + "of music and my kind of restaurant and my kind of overdraft, people " |
648 | + "start blowing up my kind of planet, throwing me out of their kind of " |
649 | + "spaceships, and entering unrecognized commands!", |
650 | + "I'm afraid I won't execute that command without an order, signed in " |
651 | + "triplicate, sent in, sent back, queried, lost, found, subjected to " |
652 | + "public enquiry, lost again, and finally buried in soft peat for " |
653 | + "three months and recycled as firelighters.", |
654 | + ] |
655 | + |
656 | + def endroid_init(self): |
657 | + self.register_unhandled_chat_callback(self.unhandled) |
658 | + self.register_unhandled_muc_callback(self.unhandled) |
659 | + |
660 | + def unhandled(self, msg): |
661 | + messages = self.messages |
662 | if date.weekday(date.today()) == 3: |
663 | - UnHandled.messages.append("This must be a Thursday, I could never get the hang of Thursdays") |
664 | - |
665 | - def enInit(self): |
666 | - self.register_unhandled_chat_callback(self.unHandled) |
667 | - self.register_unhandled_muc_callback(self.unHandled) |
668 | - |
669 | - def unHandled(self, msg): |
670 | - msg.reply(random.choice(UnHandled.messages)) |
671 | - |
672 | - def help(self): |
673 | - return "I'm a personality prototype. You can tell, can't you...?" |
674 | + messages = messages[:] + ["This must be a Thursday, I could never " |
675 | + "get the hang of Thursdays"] |
676 | + msg.reply(random.choice(messages)) |
677 | |
678 | === modified file 'src/endroid/wokkelhandler.py' |
679 | --- src/endroid/wokkelhandler.py 2012-09-01 23:15:55 +0000 |
680 | +++ src/endroid/wokkelhandler.py 2012-09-02 21:51:19 +0000 |
681 | @@ -97,8 +97,8 @@ |
682 | MUCClient.unavailableReceived(self, presence) |
683 | if presence.mucStatuses: |
684 | if presence.mucStatuses.pop().name == "KICKED": |
685 | - # In this case, we we want presence.sender.userhostJID (room JID, rather than |
686 | - # JID of kicker) |
687 | + # In this case, we we want presence.sender.userhostJID (room |
688 | + # JID, rather than JID of kicker) |
689 | self.usermanagement.left_room(presence.sender.userhostJID()) |
690 | else: |
691 | # Note that this person is unavailable |