$poke-msg on now omits your name from the channel poke and sends the entire reminder...
[halbot.git] / basic_commands.py
blob7adfcc176023169c5916c5b6775b4e554ee78703
1 from __future__ import generators
3 from irclib import irc_lower
5 import perms, whois
6 from globals import commands, private
7 from safety import safe_call
8 from common import get_timestamp, resize
10 waiting_commands = {}
12 def got_command(who, where, command, args=""):
13 from connection import hal
14 if not command in commands:
15 command = 'raise error'
16 args = "I don't understand that."
17 waiting = waiting_commands.get(who, [])
18 if not waiting:
19 (required_perms, do_it, wants_perms) = resize(commands[command], 3)
20 if where == private and required_perms <= perms.owner:
21 if wants_perms:
22 safe_call(do_it, (who, where, args, perms.owner))
23 else:
24 safe_call(do_it, (who, where, args))
25 elif not wants_perms and required_perms <= perms.voice \
26 and where in hal.channels:
27 if irc_lower(who) in whois.voice_or_better(where):
28 safe_call(do_it, (who, where, args))
29 else:
30 return
31 else:
32 waiting_commands[who] = [(where, command, args)]
33 hal.connection.whois((who,))
34 else:
35 waiting.append((where, command, args))
37 def do_commands(who, info):
38 for where, command, args in waiting_commands[who]:
39 actual_perms = perms.get_perms(who, where, info)
40 if command not in commands:
41 command = 'raise error'
42 args = "I don't understand that."
43 (required_perms, do_it, wants_perms) = resize(commands[command], 3)
44 if required_perms <= actual_perms:
45 if not wants_perms:
46 safe_call(do_it, (who, where, args))
47 else:
48 safe_call(do_it, (who, where, args, actual_perms))
49 elif required_perms > perms.voice <= actual_perms:
50 reply(who, where, "I'm sorry, %s, I'm afraid I can't do that." % who,
51 all = True)
52 waiting_commands[who] = []
53 whois.callback = do_commands
55 def reply(who, where, what, all=False):
56 from connection import hal
57 if where == private:
58 hal.connection.privmsg(who, what)
59 elif all:
60 hal.connection.privmsg(where, what)
61 else:
62 hal.connection.privmsg(where, "%s: %s" % (who, what))
64 commands['raise error'] = (perms.voice, reply)
66 def ping(who, where, args):
67 "$ping: Asks Hal to reply to you, so that you can tell you're both connected."
68 reply(who, where, "Pong!")
69 commands['ping'] = (perms.voice, ping)
71 class TestException(Exception): pass
73 def error(who, where, args):
74 "$error: Raises a test error."
75 raise TestException, str(args)
76 commands['error'] = (perms.ircop, error)
78 def join(who, where, args):
79 "Asks Hal to join the channel you're in. Always implicit, via /join."
80 from connection import hal
81 hal.connection.join(where)
82 commands['do join'] = (perms.op, join)
84 def shutdown(who, where, args):
85 "$shutdown: Shuts Hal down."
86 from connection import hal
87 hal.connection.quit("Daisy, daaaisy...")
88 raise SystemExit
89 commands['shutdown'] = (perms.ircop, shutdown)
91 def get_time(who, where, args):
92 "$time: Asks Hal what time it is, according to him."
93 reply(who, where, "Current time is: " + get_timestamp())
94 commands['time'] = (perms.voice, get_time)
96 def ignore(who, where, args):
97 "$ignore <nick>!<user>@<host>: Makes Hal ignore someone."
98 if args.lower().strip() == "list":
99 banlist = ", ".join([user for user in my_users if my_users[user] == perms.ban])
100 reply(who, where, "Currently ignoring: %s" % banlist)
101 return
102 if not weak_mask_re.search(args):
103 reply(who, where, "Please give a full nick!user@host mask.")
104 return
105 my_users[args] = perms.ban
106 reply(who, where, "Done.")
107 commands['ignore'] = (perms.ircop, ignore)
109 def unignore(who, where, args):
110 "$unignore <nick>!<user>@<host>: Makes Hal stop ignoring someone."
111 if args in my_users and my_users[args] == perms.ban:
112 my_users[args] = perms.none
113 reply(who, where, "Done.")
114 else:
115 reply(who, where, "I wasn't ignoring them.")
116 commands['unignore'] = (perms.ircop, unignore)
118 def tell_commands(who, where, args, user_perms):
119 "$commands: Shows you all the stuff you can do."
120 command_list = [command for command in commands
121 if " " not in command
122 if commands[command][0] <= user_perms]
123 command_list.sort()
124 commands_str = ", ".join(command_list)
125 reply(who, where,
126 "Available commands at your permission level: " + commands_str)
127 commands['commands'] = (perms.voice, tell_commands, "I want perms.")
129 def get_help(who, where, args):
130 "$help <command>: Gets help on a command. Use $commands to get a list of available commands. Confused? Try: $help basic"
131 args = args.lower()
132 if not args:
133 args = "help"
134 elif args in ("basic", "usage", "basic usage", "hal"):
135 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.")
136 return
137 elif " " in args:
138 reply(who, where, "One command at a time, please.")
139 return
140 elif args[0] == "$":
141 args = args[1:]
142 if args not in commands:
143 reply(who, where, "I don't have that command.")
144 return
145 (required_perms, command) = resize(commands[args],2)
146 if required_perms <= perms.voice:
147 permstr = ""
148 else:
149 permstr = " (Requires %s.)" % required_perms
150 docstr = getattr(command, '__doc__', None)
151 if not docstr:
152 docstr = "No help available for this command."
153 reply(who, where, docstr + permstr)
154 commands['help'] = (perms.voice, get_help)
156 def troggie(func):
157 def continue_if_no_troggie(who, where, *args, **kwargs):
158 from connection import hal
159 if where in hal.channels:
160 chan = hal.channels[where]
161 if "troggie" not in chan.userdict:
162 func(who, where, *args, **kwargs)
163 # Pass the docstring through.
164 continue_if_no_troggie.__doc__ = func.__doc__
165 return continue_if_no_troggie