|
18 | 18 |
|
19 | 19 | from zulip import Client
|
20 | 20 |
|
| 21 | +from collections import OrderedDict |
| 22 | + |
21 | 23 | def exit_gracefully(signum, frame):
|
22 | 24 | # type: (int, Optional[Any]) -> None
|
23 | 25 | sys.exit(0)
|
@@ -156,7 +158,58 @@ def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name):
|
156 | 158 |
|
157 | 159 | state_handler = StateHandler()
|
158 | 160 |
|
| 161 | + # Bot details and default commands from defaults, then override if provided |
| 162 | + bot_details = { 'name': bot_name.capitalize(), |
| 163 | + 'description': "", |
| 164 | + 'commands': {}, |
| 165 | + 'no_defaults': False, |
| 166 | + } |
| 167 | + def def_about(): |
| 168 | + desc = bot_details['description'] |
| 169 | + return "**{}**{}".format(bot_details['name'], |
| 170 | + "" if desc == "" else ": {}".format(desc)) |
| 171 | + def def_help(): |
| 172 | + return ("\n".join("**{}** - {}".format(k, v[1]) |
| 173 | + for k, v in default_commands.items() if k != '') + |
| 174 | + "\n" + |
| 175 | + "\n".join("**{}** - {}".format(k, v) |
| 176 | + for k, v in bot_details['commands'].items() if k != '')) |
| 177 | + def def_commands(): |
| 178 | + return "**Commands**: {} {}".format( |
| 179 | + " ".join(k for k in default_commands if k != ''), |
| 180 | + " ".join(k for k in bot_details['commands'] if k != '')) |
| 181 | + default_commands = OrderedDict([ |
| 182 | + ('', lambda: ("Oops. Your message was empty.", )), |
| 183 | + ('about', (def_about, "The type and use of this bot")), |
| 184 | + ('usage', ((lambda: message_handler.usage(), "Bot-provided usage text"))), |
| 185 | + ('help', (lambda: "{}\n{}\n{}".format(def_about(), message_handler.usage(), def_help()), |
| 186 | + "This help text")), |
| 187 | + ('commands', (def_commands, "A short list of supported commands")) |
| 188 | + ]) |
| 189 | + # Update bot_details from those in class, if present |
| 190 | + try: |
| 191 | + bot_details.update(lib_module.handler_class.META) |
| 192 | + except AttributeError: |
| 193 | + pass |
| 194 | + # Update default_commands from any changes in bot_details |
| 195 | + if bot_details['no_defaults']: # Bot class will handle all commands |
| 196 | + default_commands = {} |
| 197 | + else: |
| 198 | + if len(bot_details['commands']) == 0: # No commands specified, so don't use this feature |
| 199 | + del default_commands['commands'] |
| 200 | + del default_commands['help'] |
| 201 | + else: |
| 202 | + for command in bot_details['commands']: # Bot commands override defaults |
| 203 | + if command in default_commands: |
| 204 | + del default_commands[command] |
| 205 | + # Sync default_commands changes with bot_details |
| 206 | + if len(default_commands) == 0: |
| 207 | + bot_details['no_defaults'] = True |
| 208 | + |
159 | 209 | if not quiet:
|
| 210 | + print("Running {} Bot:".format(bot_details['name'])) |
| 211 | + if bot_details['description'] != "": |
| 212 | + print("\n{}".format(bot_details['description'])) |
160 | 213 | print(message_handler.usage())
|
161 | 214 |
|
162 | 215 | def extract_query_without_mention(message, client):
|
@@ -198,6 +251,18 @@ def handle_message(message):
|
198 | 251 | return
|
199 | 252 |
|
200 | 253 | if is_private_message or is_mentioned:
|
| 254 | + # Handle any default_commands first |
| 255 | + if len(default_commands) > 0: |
| 256 | + if '' in default_commands and len(message['content']) == 0: |
| 257 | + restricted_client.send_reply(message, default_commands[''][0]()) |
| 258 | + return |
| 259 | + for command in default_commands: |
| 260 | + if command == '': |
| 261 | + continue |
| 262 | + if message['content'].startswith(command): |
| 263 | + restricted_client.send_reply(message, default_commands[command][0]()) |
| 264 | + return |
| 265 | + # ...then pass anything else to bot to deal with |
201 | 266 | message_handler.handle_message(
|
202 | 267 | message=message,
|
203 | 268 | bot_handler=restricted_client,
|
|
0 commit comments