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 )
@@ -159,6 +161,46 @@ def state(self, default):
159
161
yield new_state
160
162
self .set_state (new_state )
161
163
164
+ def setup_default_commands (bot_details , message_handler ):
165
+ def def_about ():
166
+ if bot_details ['description' ] == "" :
167
+ return "**{}**" .format (bot_details ['name' ])
168
+ return "**{}**: {}" .format (bot_details ['name' ], bot_details ['description' ])
169
+ def def_help ():
170
+ return ("\n " .join ("**{}** - {}" .format (k , v [1 ])
171
+ for k , v in defaults .items () if k ) + "\n " +
172
+ "\n " .join ("**{}** - {}" .format (k , v )
173
+ for k , v in bot_details ['commands' ].items () if k ))
174
+ def def_commands ():
175
+ return "**Commands**: {} {}" .format (
176
+ " " .join (k for k in defaults if k ),
177
+ " " .join (k for k in bot_details ['commands' ] if k ))
178
+ defaults = OrderedDict ([ # Variable definition required for callbacks above
179
+ ('' , (lambda : "Oops. Your message was empty." , "[BLANK MESSAGE NOT SHOWN]" )),
180
+ ('about' , (def_about , "The type and use of this bot" )),
181
+ ('usage' , ((lambda : message_handler .usage (), "Bot-provided usage text" ))),
182
+ ('help' , (lambda : "{}\n {}\n {}" .format (def_about (), message_handler .usage (), def_help ()),
183
+ "This help text" )),
184
+ ('commands' , (def_commands , "A short list of supported commands" ))
185
+ ])
186
+ return defaults
187
+
188
+ def sync_botdetails_defaultcommands (bot_details , default_commands ):
189
+ # Update default_commands from any changes in bot_details
190
+ if not bot_details ['defaults' ]: # Bot class will handle all commands
191
+ default_commands = {}
192
+ else :
193
+ if len (bot_details ['commands' ]) == 0 : # No commands specified, so don't use this feature
194
+ del default_commands ['commands' ]
195
+ del default_commands ['help' ]
196
+ else :
197
+ for command in bot_details ['commands' ]: # Bot commands override defaults
198
+ if command in default_commands :
199
+ del default_commands [command ]
200
+ # Sync default_commands changes with bot_details
201
+ if len (default_commands ) == 0 :
202
+ bot_details ['defaults' ] = False
203
+
162
204
def run_message_handler_for_bot (lib_module , quiet , config_file , bot_name ):
163
205
# type: (Any, bool, str) -> Any
164
206
#
@@ -178,7 +220,22 @@ def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name):
178
220
179
221
state_handler = StateHandler ()
180
222
223
+ # Set default bot_details, then override from class, if provided
224
+ bot_details = { 'name' : bot_name .capitalize (),
225
+ 'description' : "" ,
226
+ 'commands' : {},
227
+ 'defaults' : True ,
228
+ }
229
+ bot_details .update (getattr (lib_module .handler_class , 'META' , {}))
230
+
231
+ # Initialise default commands, then override & sync with bot_details
232
+ default_commands = setup_default_commands (bot_details , message_handler )
233
+ sync_botdetails_defaultcommands (bot_details , default_commands )
234
+
181
235
if not quiet :
236
+ print ("Running {} Bot:" .format (bot_details ['name' ]))
237
+ if bot_details ['description' ] != "" :
238
+ print ("\n {}" .format (bot_details ['description' ]))
182
239
print (message_handler .usage ())
183
240
184
241
def extract_query_without_mention (message , client ):
@@ -220,6 +277,18 @@ def handle_message(message):
220
277
return
221
278
222
279
if is_private_message or is_mentioned :
280
+ # Handle any default_commands first
281
+ if len (default_commands ) > 0 :
282
+ if '' in default_commands and len (message ['content' ]) == 0 :
283
+ restricted_client .send_reply (message , default_commands ['' ][0 ]())
284
+ return
285
+ for command in default_commands :
286
+ if command == '' :
287
+ continue
288
+ if message ['content' ].startswith (command ):
289
+ restricted_client .send_reply (message , default_commands [command ][0 ]())
290
+ return
291
+ # ...then pass anything else to bot to deal with
223
292
message_handler .handle_message (
224
293
message = message ,
225
294
bot_handler = restricted_client ,
0 commit comments