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