*quietly adds a file that should have been in the tree since 9839a*
[halbot.git] / basic_commands.py
blobad5a9c3c0029ca546b367261d12577343cea5562
1 from __future__ import generators
2 import re
4 from irclib import irc_lower
6 import perms, whois
7 import globals
8 from globals import commands, private
9 from safety import safe_call
10 from common import get_timestamp, resize
12 waiting_commands = {}
14 def got_command(who, where, command, args=""):
15 from connection import hal
16 if not command in commands:
17 command = 'raise error'
18 args = "I don't understand that."
19 waiting = waiting_commands.get(who, [])
20 if not waiting:
21 (required_perms, do_it, wants_perms) = resize(commands[command], 3)
22 if where == private and required_perms <= perms.owner:
23 if wants_perms:
24 safe_call(do_it, (who, where, args, perms.owner))
25 else:
26 safe_call(do_it, (who, where, args))
27 elif not wants_perms and required_perms <= perms.voice \
28 and where in hal.channels:
29 if irc_lower(who) in whois.voice_or_better(where):
30 safe_call(do_it, (who, where, args))
31 else:
32 return
33 else:
34 waiting_commands[who] = [(where, command, args)]
35 hal.connection.whois((who,))
36 else:
37 waiting.append((where, command, args))
39 def do_commands(who, info):
40 for where, command, args in waiting_commands[who]:
41 actual_perms = perms.get_perms(who, where, info)
42 if command not in commands:
43 command = 'raise error'
44 args = "I don't understand that."
45 (required_perms, do_it, wants_perms) = resize(commands[command], 3)
46 if required_perms <= actual_perms:
47 if not wants_perms:
48 safe_call(do_it, (who, where, args))
49 else:
50 safe_call(do_it, (who, where, args, actual_perms))
51 elif required_perms > perms.voice <= actual_perms:
52 reply(who, where, "I'm sorry, %s, I'm afraid I can't do that." % who,
53 all = True)
54 waiting_commands[who] = []
55 whois.callback = do_commands
57 def reply(who, where, what, all=False):
58 from connection import hal
59 if where == private:
60 hal.connection.privmsg(who, what)
61 elif all:
62 hal.connection.privmsg(where, what)
63 else:
64 hal.connection.privmsg(where, "%s: %s" % (who, what))
66 commands['raise error'] = (perms.voice, reply)
68 def ping(who, where, args):
69 "$ping: Asks Hal to reply to you, so that you can tell you're both connected."
70 reply(who, where, "Pong!")
71 commands['ping'] = (perms.voice, ping)
73 class TestException(Exception): pass
75 def error(who, where, args):
76 "$error: Raises a test error."
77 raise TestException, str(args)
78 commands['error'] = (perms.ircop, error)
80 def join(who, where, args):
81 "Asks Hal to join the channel you're in. Always implicit, via /join."
82 from connection import hal
83 hal.connection.join(where)
84 commands['do join'] = (perms.op, join)
86 def shutdown(who, where, args):
87 "$shutdown: Shuts Hal down."
88 from connection import hal
89 hal.connection.quit("Daisy, daaaisy...")
90 raise SystemExit
91 commands['shutdown'] = (perms.ircop, shutdown)
93 def get_time(who, where, args):
94 "$time: Asks Hal what time it is, according to him."
95 reply(who, where, "Current time is: " + get_timestamp())
96 commands['time'] = (perms.voice, get_time)
98 weak_mask_re = re.compile(".+!.+@.+")
99 def ignore(who, where, args):
100 "$ignore <nick>!<user>@<host>: Makes Hal ignore someone."
101 if args.lower().strip() == "list":
102 banlist = ", ".join([user for user in globals.my_users if globals.my_users[user] == perms.ban])
103 reply(who, where, "Currently ignoring: %s" % banlist)
104 return
105 if not weak_mask_re.search(args):
106 reply(who, where, "Please give a full nick!user@host mask.")
107 return
108 globals.my_users[args] = perms.ban
109 reply(who, where, "Done.")
110 commands['ignore'] = (perms.ircop, ignore)
112 def unignore(who, where, args):
113 "$unignore <nick>!<user>@<host>: Makes Hal stop ignoring someone."
114 if args in globals.my_users and globals.my_users[args] == perms.ban:
115 globals.my_users[args] = perms.none
116 reply(who, where, "Done.")
117 else:
118 reply(who, where, "I wasn't ignoring them.")
119 commands['unignore'] = (perms.ircop, unignore)
121 def tell_commands(who, where, args, user_perms):
122 "$commands: Shows you all the stuff you can do."
123 command_list = [command for command in commands
124 if " " not in command
125 if commands[command][0] <= user_perms]
126 command_list.sort()
127 commands_str = ", ".join(command_list)
128 reply(who, where,
129 "Available commands at your permission level: " + commands_str)
130 commands['commands'] = (perms.voice, tell_commands, "I want perms.")
132 def get_help(who, where, args):
133 "$help <command>: Gets help on a command. Use $commands to get a list of available commands. Confused? Try: $help basic"
134 args = args.lower()
135 if not args:
136 args = "help"
137 elif args in ("basic", "usage", "basic usage", "hal"):
138 reply(who, where, "If you're used to troggie, I may seem a bit odd, because I don't behave the same way. The easiest way to think of it is that in every channel, there's a separate copy of me, so what happens in one doesn't affect the others. The same is true if you PM me, it's your own personal Hal.")
139 return
140 elif args == "poker":
141 reply(who, where, "I announce Triplejack prize tournaments as they begin staging (5 minutes before they start). See $help subscribe for information on subscribing to them and $help poke-msg if you need me to /msg you instead of saying your name in channel. Available groups: poker, pp, fandango, laptop, finals, pokernight.")
142 return
143 elif " " in args:
144 reply(who, where, "One command at a time, please.")
145 return
146 elif args[0] == "$":
147 args = args[1:]
148 if args not in commands:
149 reply(who, where, "I don't have that command.")
150 return
151 (required_perms, command) = resize(commands[args],2)
152 if required_perms <= perms.voice:
153 permstr = ""
154 else:
155 permstr = " (Requires %s.)" % required_perms
156 docstr = getattr(command, '__doc__', None)
157 if not docstr:
158 docstr = "No help available for this command."
159 reply(who, where, docstr + permstr)
160 commands['help'] = (perms.voice, get_help)
162 def troggie(func):
163 def continue_if_no_troggie(who, where, *args, **kwargs):
164 from connection import hal
165 if where in hal.channels:
166 chan = hal.channels[where]
167 if "troggie" not in chan.userdict:
168 func(who, where, *args, **kwargs)
169 # Pass the docstring through.
170 continue_if_no_troggie.__doc__ = func.__doc__
171 return continue_if_no_troggie