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)) if not options.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) run_message_handler_for_bot(lib_module=lib_module, config_file=options.config_file, quiet=options.quiet, bot_name=bot_name)
def main() -> None: args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ( "ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main() -> None: args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath(os.path.join(current_dir, 'bots', args.bot, args.bot+'.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ("ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name ) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main(): # type: () -> None args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(os.path.basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot bot_dir = os.path.dirname(bot_path) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) lib_module = import_module_from_source(bot_path, bot_name) message = {'content': args.message, 'sender_email': '*****@*****.**'} message_handler = lib_module.handler_class() with patch('zulip.Client') as mock_client: mock_bot_handler = ExternalBotHandler(mock_client, bot_dir) mock_bot_handler.send_reply = MagicMock() mock_bot_handler.send_message = MagicMock() mock_bot_handler.update_message = MagicMock() if hasattr(message_handler, 'initialize') and callable( message_handler.initialize): message_handler.initialize(mock_bot_handler) message_handler.handle_message(message=message, bot_handler=mock_bot_handler, state_handler=StateHandler()) print("On sending {} bot the message \"{}\"".format( bot_name, args.message)) # send_reply and send_message have slightly arguments; the # following takes that into account. # send_reply(original_message, response) # send_message(response_message) if mock_bot_handler.send_reply.called: output_message = list(mock_bot_handler.send_reply.call_args)[0][1] elif mock_bot_handler.send_message.called: output_message = list( mock_bot_handler.send_message.call_args)[0][0] elif mock_bot_handler.update_message.called: output_message = list( mock_bot_handler.update_message.call_args)[0][0]['content'] print( "the bot updates a message with the following text (in quotes):\n\"{}\"" .format(output_message)) sys.exit() else: print("the bot sent no reply.") sys.exit() print( "the bot gives the following output message (in quotes):\n\"{}\"". format(output_message))
def main(): # type: () -> None args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) lib_module = import_module_from_source(bot_path, bot_name) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main(): # type: () -> None args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot if args.provision: provision_bot(os.path.dirname(bot_path), args.force) lib_module = import_module_from_source(bot_path, bot_name) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, quiet=args.quiet, bot_name=bot_name)
def main() -> None: args = parse_args() if args.registry: try: bot_source, lib_module = finder.import_module_from_zulip_bot_registry( args.bot) except finder.DuplicateRegisteredBotName as error: print( f'ERROR: Found duplicate entries for "{error}" in zulip bots registry.\n' "Make sure that you don't install bots using the same entry point. Exiting now." ) sys.exit(1) if lib_module: bot_name = args.bot else: result = finder.resolve_bot_path(args.bot) if result: bot_path, bot_name = result sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = finder.import_module_from_source( bot_path.as_posix(), bot_name) except ImportError: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ( "ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print( dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) bot_source = "source" else: lib_module = finder.import_module_by_name(args.bot) if lib_module: bot_name = lib_module.__name__ bot_source = "named module" if args.provision: print( "ERROR: Could not load bot's module for '{}'. Exiting now." ) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_is_missing(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name, bot_source=bot_source, ) except NoBotConfigException: print(""" ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. """) sys.exit(1)
def main() -> None: args = parse_args() result = finder.resolve_bot_path(args.bot) if result: bot_path, bot_name = result sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = finder.import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ("ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) else: lib_module = finder.import_module_by_name(args.bot) if lib_module: bot_name = lib_module.__name__ # Removed: Not needed as lib_module would have # been imported during runtime if control # flow reaches here. Adding any other provision # check after this would be unnecessary as # provision_bots require bot_path which # could not be found, hence result is None # and control is here. if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_is_missing(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name ) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
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, 'sender_email': '*****@*****.**' } message_handler = lib_module.handler_class() with patch('zulip_bots.lib.ExternalBotHandler') as mock_bot_handler: def get_config_info(bot_name, section=None, optional=False): # type: (str, Optional[str], Optional[bool]) -> Dict[str, Any] conf_file_path = os.path.realpath( os.path.join('zulip_bots', 'bots', bot_name, bot_name + '.conf')) section = section or bot_name config = configparser.ConfigParser() try: with open(conf_file_path) as conf: config.readfp(conf) # type: ignore except IOError: if optional: return dict() raise return dict(config.items(section)) mock_bot_handler.get_config_info = get_config_info if hasattr(message_handler, 'initialize') and callable( message_handler.initialize): message_handler.initialize(mock_bot_handler) mock_bot_handler.send_reply = MagicMock() mock_bot_handler.send_message = 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, "\"") # send_reply and send_message have slightly arguments; the # following takes that into account. # send_reply(original_message, response) # send_message(response_message) if mock_bot_handler.send_reply.called: print("\nThe bot gives the following output message:\n\"", list(mock_bot_handler.send_reply.call_args)[0][1], "\"") elif mock_bot_handler.send_message.called: print("\nThe bot sends the following output to zulip:\n\"", list(mock_bot_handler.send_message.call_args)[0][0], "\"") else: print("\nThe bot sent no reply.")