Fixed ircbot's channel mode dicts.
[halbot.git] / basic_commands.py
blob5d773cb85861cab38e8163e28e27e63eb7081800
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 args == "poker":
138 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, fandango, laptop, finals, pokernight.")
139 return
140 elif " " in args:
141 reply(who, where, "One command at a time, please.")
142 return
143 elif args[0] == "$":
144 args = args[1:]
145 if args not in commands:
146 reply(who, where, "I don't have that command.")
147 return
148 (required_perms, command) = resize(commands[args],2)
149 if required_perms <= perms.voice:
150 permstr = ""
151 else:
152 permstr = " (Requires %s.)" % required_perms
153 docstr = getattr(command, '__doc__', None)
154 if not docstr:
155 docstr = "No help available for this command."
156 reply(who, where, docstr + permstr)
157 commands['help'] = (perms.voice, get_help)
159 def troggie(func):
160 def continue_if_no_troggie(who, where, *args, **kwargs):
161 from connection import hal
162 if where in hal.channels:
163 chan = hal.channels[where]
164 if "troggie" not in chan.userdict:
165 func(who, where, *args, **kwargs)
166 # Pass the docstring through.
167 continue_if_no_troggie.__doc__ = func.__doc__
168 return continue_if_no_troggie