bots: Add manual command to get bot output.
This eliminates the need to setup dev environment and to
create a bot, setup zuliprc file, subscribe the bot to the
stream in order to try out a bot.
Manual command get-bot-output gives the bots response content
directly.
MODIFY
zulip_bots/setup.py
zulip_bots/setup.py
@@ -27,6 +27,7 @@ package_info = dict(
entry_points={
'console_scripts': [
'zulip-run-bot=zulip_bots.run:main',
+ 'zulip-bot-output=zulip_bots.zulip_bot_output:main'
],
},
include_package_data=True,

ADD
zulip_bots/zulip_bots/zulip_bot_output.py
+#!/usr/bin/env python
+from __future__ import print_function
+from __future__ import absolute_import
+
+import argparse
+import sys
+import os
+from types import ModuleType
+from importlib import import_module
+from os.path import basename, splitext
+
+import six
+import mock
+from mock import MagicMock, patch
+
+from zulip_bots.lib import run_message_handler_for_bot, StateHandler
+from zulip_bots.provision import provision_bot
+from zulip_bots.run import import_module_from_source
+
+
+def parse_args():
+ usage = '''
+ zulip-bot-output <bot_name> --message "Send this message to the bot"
+ Example: zulip-bot-output xkcd --message "1"
+ This tool can be used for testing bots by sending simple messages
+ and capturing the response.
+ (Internally, this program loads bot-related code from the
+ library code and then feeds the message provided
+ in the command to the library code to handle.)
+ '''
+
+ parser = argparse.ArgumentParser(usage=usage)
+ parser.add_argument('name',
+ action='store',
+ nargs='?',
+ default=None,
+ help='the name of an existing bot to run')
+ parser.add_argument('--message',
+ action='store',
+ help='the message content to send to the bot')
+
+ parser.add_argument('--path-to-bot',
+ action='store',
+ help='path to the file with the bot handler class')
+
+ parser.add_argument('--force',
+ action='store_true',
+ help='Try running the bot even if dependencies install fails.')
+
+ parser.add_argument('--provision',
+ action='store_true',
+ help='Install dependencies for the bot.')
+
+ options = parser.parse_args()
+ if not options.name and not options.path_to_bot:
+ error_message = """
+You must either specify the name of an existing bot or
+specify a path to the file (--path-to-bot) that contains
+the bot handler class.
+"""
+ parser.error(error_message)
+
+ return options
+
+def main():
+ # type: () -> None
+ options = parse_args()
+ bot_name = options.name
+ if options.path_to_bot:
+ if options.provision:
+ bot_dir = os.path.dirname(os.path.abspath(options.path_to_bot))
+ provision_bot(bot_dir, options.force)
+ lib_module = import_module_from_source(options.path_to_bot, name=bot_name)
+ elif options.name:
+ if options.provision:
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ bots_parent_dir = os.path.join(current_dir, "bots")
+ bot_dir = os.path.join(bots_parent_dir, options.name)
+ provision_bot(bot_dir, options.force)
+ lib_module = import_module('zulip_bots.bots.{bot}.{bot}'.format(bot=bot_name))
+
+ message = {'content': options.message}
+ message_handler = lib_module.handler_class()
+
+ with patch('zulip_bots.lib.ExternalBotHandler') as mock_bot_handler:
+ mock_bot_handler.send_reply = MagicMock()
+ message_handler.handle_message(
+ message=message,
+ bot_handler=mock_bot_handler,
+ state_handler=StateHandler()
+ )
+ print("On sending ", options.name, " bot the following message:\n\"", options.message, "\"")
+ print("\nThe bot gives the following output message:\n\"", list(mock_bot_handler.send_reply.call_args)[0][1], "\"")
+
+if __name__ == '__main__':
+ main()

bots: Add manual command to get bot output.

This eliminates the need to setup dev environment and to
create a bot, setup zuliprc file, subscribe the bot to the
stream in order to try out a bot.

Manual command get-bot-output gives the bots response content
directly.