def reload(self, mess, args): """reload a plugin""" if self.is_plugin_blacklisted(args): self.unblacklist_plugin(args) result = "%s / %s" % (self.deactivate_plugin(args), self.activate_plugin(args)) get_plugin_obj_by_name(args).callback_connect() return result
def status(self, mess, args): """ If I am alive I should be able to respond to this one """ all_blacklisted = self.get_blacklisted_plugin() all_loaded = get_all_active_plugin_names() all_attempted = sorted([p.name for p in self.all_candidates]) plugins_statuses = [] for name in all_attempted: if name in all_blacklisted: if name in all_loaded: plugins_statuses.append(('BL', name)) else: plugins_statuses.append(('BU', name)) elif name in all_loaded: plugins_statuses.append(('L', name)) elif get_plugin_obj_by_name(name) is not None and get_plugin_obj_by_name(name).get_configuration_template() is not None and self.get_plugin_configuration(name) is None: plugins_statuses.append(('C', name)) else: plugins_statuses.append(('U', name)) #noinspection PyBroadException try: from posix import getloadavg loads = getloadavg() except Exception as _: loads = None return {'plugins_statuses': plugins_statuses, 'loads': loads, 'gc': gc.get_count()}
def status_plugins(self, mess, args): """ shows the plugin status """ all_blacklisted = self.get_blacklisted_plugin() all_loaded = get_all_active_plugin_names() all_attempted = sorted([p.name for p in self.all_candidates]) plugins_statuses = [] for name in all_attempted: if name in all_blacklisted: if name in all_loaded: plugins_statuses.append(('BL', name)) else: plugins_statuses.append(('BU', name)) elif name in all_loaded: plugins_statuses.append(('L', name)) elif get_plugin_obj_by_name( name) is not None and get_plugin_obj_by_name( name).get_configuration_template( ) is not None and self.get_plugin_configuration( name) is None: plugins_statuses.append(('C', name)) else: plugins_statuses.append(('U', name)) return {'plugins_statuses': plugins_statuses}
def status(self, mess, args): """ If I am alive I should be able to respond to this one """ all_blacklisted = self.get_blacklisted_plugin() all_loaded = get_all_active_plugin_names() all_attempted = sorted([p.name for p in self.all_candidates]) plugins_statuses = [] for name in all_attempted: if name in all_blacklisted: plugins_statuses.append(("B", name)) elif name in all_loaded: plugins_statuses.append(("L", name)) elif ( get_plugin_obj_by_name(name) is not None and get_plugin_obj_by_name(name).get_configuration_template() is not None and self.get_plugin_configuration(name) is None ): plugins_statuses.append(("C", name)) else: plugins_statuses.append(("E", name)) try: from posix import getloadavg loads = getloadavg() except Exception as e: loads = None return {"plugins_statuses": plugins_statuses, "loads": loads, "gc": gc.get_count()}
def status(self, mess, args): """ If I am alive I should be able to respond to this one """ all_blacklisted = self.get_blacklisted_plugin() all_loaded = get_all_active_plugin_names() all_attempted = sorted([p.name for p in self.all_candidates]) plugins_statuses = [] for name in all_attempted: if name in all_blacklisted: plugins_statuses.append(('B', name)) elif name in all_loaded: plugins_statuses.append(('L', name)) elif get_plugin_obj_by_name( name) is not None and get_plugin_obj_by_name( name).get_configuration_template( ) is not None and self.get_plugin_configuration( name) is None: plugins_statuses.append(('C', name)) else: plugins_statuses.append(('E', name)) #noinspection PyBroadException try: from posix import getloadavg loads = getloadavg() except Exception as _: loads = None return { 'plugins_statuses': plugins_statuses, 'loads': loads, 'gc': gc.get_count() }
def activate_plugin(self, name): try: if name in get_all_active_plugin_names(): return "Plugin already in active list" if name not in get_all_plugin_names(): return "I don't know this %s plugin" % name activate_plugin_with_version_check(name, self.get_plugin_configuration(name)) except Exception as e: logging.exception("Error loading %s" % name) return '%s failed to start : %s\n' % (name, e) get_plugin_obj_by_name(name).callback_connect() return "Plugin %s activated" % name
def setUp(self): me = os.path.dirname(os.path.realpath(os.path.abspath(__file__))) # Adding /la/bla to path is needed because of the path mangling # FullStackTest does on extra_test_file. plugin_dir = os.path.join(me, 'la', 'bla') super(MathBotTests, self).setUp(extra_test_file=plugin_dir) self.plugin = plugin_manager.get_plugin_obj_by_name('MathBot')
def test_load_data_sources_loads_StringIO_correctly(self): p = get_plugin_obj_by_name('GarakBot') fp = StringIO(json.dumps(self.random_quotes)) p.garak_quote_ds = fp quote_data = p.load_data_sources() assert quote_data is not None assert len(quote_data) == len(self.random_quotes)
def test_mycommand_tellme_something_returns_expected_output(self): p = get_plugin_obj_by_name('GarakBot') fp = StringIO(json.dumps(self.random_quotes)) p.garak_quote_ds = fp p.clear_garak_quote_datasource() push_message('! tellme something') self.assertRegex(pop_message(), r'^\w+ Quote!')
def config(self, mess, args): """ configure or get the configuration / configuration template for a specific plugin ie. !config ExampleBot could return a template if it is not configured: {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/toto'} Copy paste, adapt so can configure the plugin : !config ExampleBot {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} It will then reload the plugin with this config. You can at any moment retreive the current values: !config ExampleBot should return : {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} """ plugin_name = args[0] if self.is_plugin_blacklisted(plugin_name): return 'Load this plugin first with ' + self.prefix + 'load %s' % plugin_name obj = get_plugin_obj_by_name(plugin_name) if obj is None: return 'Unknown plugin or the plugin could not load %s' % plugin_name template_obj = obj.get_configuration_template() if template_obj is None: return 'This plugin is not configurable.' if len(args) == 1: current_config = self.get_plugin_configuration(plugin_name) response = ( "Default configuration for this plugin (you can copy and paste " "this directly as a command):\n{prefix}config {plugin_name} \n{config}" ).format(prefix=self.prefix, plugin_name=plugin_name, config=pformat(template_obj)) if current_config: response += "\n\nCurrent configuration:\n{prefix}config {plugin_name} \n{config}".format( prefix=self.prefix, plugin_name=plugin_name, config=pformat(current_config)) return response # noinspection PyBroadException try: real_config_obj = literal_eval(' '.join(args[1:])) except Exception as _: logging.exception( 'Invalid expression for the configuration of the plugin') return 'Syntax error in the given configuration' if type(real_config_obj) != type(template_obj): return 'It looks fishy, your config type is not the same as the template !' self.set_plugin_configuration(plugin_name, real_config_obj) self.deactivate_plugin(plugin_name) try: self.activate_plugin(plugin_name) except PluginConfigurationException as ce: logging.debug( 'Invalid configuration for the plugin, reverting the plugin to unconfigured' ) self.set_plugin_configuration(plugin_name, None) return 'Incorrect plugin configuration: %s' % ce return 'Plugin configuration done.'
def test_load_data_sources_loads_DiskFile_correctly(self): p = get_plugin_obj_by_name('GarakBot') file = NamedTemporaryFile(dir=tempdir, suffix='.json') json.dump(self.random_quotes2, open(file.name, mode='w')) p.garak_quote_ds = file.name quote_data = p.load_data_sources() assert quote_data is not None assert len(quote_data) == len(self.random_quotes2)
def config(self, mess, args): """ configure or get the configuration / configuration template for a specific plugin ie. !config ExampleBot could return a template if it is not configured: {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/toto'} Copy paste, adapt so can configure the plugin : !config ExampleBot {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} It will then reload the plugin with this config. You can at any moment retreive the current values: !config ExampleBot should return : {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} """ plugin_name = args[0] if self.is_plugin_blacklisted(plugin_name): return "Load this plugin first with " + self.prefix + "load %s" % plugin_name obj = get_plugin_obj_by_name(plugin_name) if obj is None: return "Unknown plugin or the plugin could not load %s" % plugin_name template_obj = obj.get_configuration_template() if template_obj is None: return "This plugin is not configurable." if len(args) == 1: current_config = self.get_plugin_configuration(plugin_name) if current_config: return ( "Copy paste and adapt one of the following:\nDefault Config: " + self.prefix + "config %s %s\nCurrent Config: !config %s %s" % (plugin_name, repr(template_obj), plugin_name, repr(current_config)) ) return ( "Copy paste and adapt of the following:\n" + self.prefix + "config %s %s" % (plugin_name, repr(template_obj)) ) # noinspection PyBroadException try: real_config_obj = literal_eval(" ".join(args[1:])) except Exception as _: logging.exception("Invalid expression for the configuration of the plugin") return "Syntax error in the given configuration" if type(real_config_obj) != type(template_obj): return "It looks fishy, your config type is not the same as the template !" self.set_plugin_configuration(plugin_name, real_config_obj) self.deactivate_plugin(plugin_name) try: self.activate_plugin(plugin_name) except PluginConfigurationException as ce: logging.debug("Invalid configuration for the plugin, reverting the plugin to unconfigured") self.set_plugin_configuration(plugin_name, None) return "Incorrect plugin configuration: %s" % ce return "Plugin configuration done."
def test_get_garak_quote_datasource_returns_dict(self): p = get_plugin_obj_by_name('GarakBot') fp = StringIO(json.dumps(self.random_quotes)) p.garak_quote_ds = fp p.clear_garak_quote_datasource() quote_data = p.get_garak_quote_datasource() assert quote_data is not None assert len(quote_data) == 5 assert self.random_quotes == quote_data
def config(self, mess, args): """ configure or get the configuration / configuration template for a specific plugin ie. !config ExampleBot could return a template if it is not configured: {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/toto'} Copy paste, adapt so can configure the plugin : !config ExampleBot {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} It will then reload the plugin with this config. You can at any moment retreive the current values: !config ExampleBot should return : {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} """ plugin_name = args[0] if self.is_plugin_blacklisted(plugin_name): return 'Load this plugin first with ' + BOT_PREFIX + 'load %s' % plugin_name obj = get_plugin_obj_by_name(plugin_name) if obj is None: return 'Unknown plugin or the plugin could not load %s' % plugin_name template_obj = obj.get_configuration_template() if template_obj is None: return 'This plugin is not configurable.' if len(args) == 1: current_config = self.get_plugin_configuration(plugin_name) if current_config: return 'Copy paste and adapt one of the following:\nDefault Config: ' + BOT_PREFIX + 'config %s %s\nCurrent Config: !config %s %s' % ( plugin_name, repr(template_obj), plugin_name, repr(current_config)) return 'Copy paste and adapt of the following:\n' + BOT_PREFIX + 'config %s %s' % ( plugin_name, repr(template_obj)) try: real_config_obj = literal_eval(' '.join(args[1:])) except Exception as e: logging.exception( 'Invalid expression for the configuration of the plugin') return 'Syntax error in the given configuration' if type(real_config_obj) != type(template_obj): return 'It looks fishy, your config type is not the same as the template !' self.set_plugin_configuration(plugin_name, real_config_obj) self.deactivate_plugin(plugin_name) try: self.activate_plugin(plugin_name) except PluginConfigurationException, ce: logging.debug( 'Invalid configuration for the plugin, reverting the plugin to unconfigured' ) self.set_plugin_configuration(plugin_name, None) return 'Incorrect plugin configuration: %s' % ce
def config(self, mess, args): """ configure or get the configuration / configuration template for a specific plugin ie. !config ExampleBot could return a template if it is not configured: {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/toto'} Copy paste, adapt so can configure the plugin : !config ExampleBot {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} It will then reload the plugin with this config. You can at any moment retreive the current values: !config ExampleBot should return : {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} """ plugin_name = args[0] if self.is_plugin_blacklisted(plugin_name): return 'Load this plugin first with ' + self.prefix + 'load %s' % plugin_name obj = get_plugin_obj_by_name(plugin_name) if obj is None: return 'Unknown plugin or the plugin could not load %s' % plugin_name template_obj = obj.get_configuration_template() if template_obj is None: return 'This plugin is not configurable.' if len(args) == 1: current_config = self.get_plugin_configuration(plugin_name) response = ("Default configuration for this plugin (you can copy and paste " "this directly as a command):\n{prefix}config {plugin_name} \n{config}").format( prefix=self.prefix, plugin_name=plugin_name, config=pformat(template_obj)) if current_config: response += "\n\nCurrent configuration:\n{prefix}config {plugin_name} \n{config}".format( prefix=self.prefix, plugin_name=plugin_name, config=pformat(current_config)) return response #noinspection PyBroadException try: real_config_obj = literal_eval(' '.join(args[1:])) except Exception as _: logging.exception('Invalid expression for the configuration of the plugin') return 'Syntax error in the given configuration' if type(real_config_obj) != type(template_obj): return 'It looks fishy, your config type is not the same as the template !' self.set_plugin_configuration(plugin_name, real_config_obj) self.deactivate_plugin(plugin_name) try: self.activate_plugin(plugin_name) except PluginConfigurationException as ce: logging.debug('Invalid configuration for the plugin, reverting the plugin to unconfigured') self.set_plugin_configuration(plugin_name, None) return 'Incorrect plugin configuration: %s' % ce return 'Plugin configuration done.'
def test_mycommand_tellme_something_returns_random_output(self): p = get_plugin_obj_by_name('GarakBot') fp = StringIO(json.dumps(self.random_quotes2)) p.garak_quote_ds = fp p.clear_garak_quote_datasource() push_message('! tellme something') a = pop_message() push_message('! tellme something') b = pop_message() push_message('! tellme something') c = pop_message() assert a is not None assert b is not None assert c is not None assert a != b != c
def config(self, mess, args): """ configure or get the configuration / configuration template for a specific plugin ie. !config ExampleBot could return a template if it is not configured: {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/toto'} Copy paste, adapt so can configure the plugin : !config ExampleBot {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} It will then reload the plugin with this config. You can at any moment retreive the current values: !config ExampleBot should return : {'LOGIN': '******', 'PASSWORD': '******', 'DIRECTORY': '/tmp'} """ plugin_name = args[0] if self.is_plugin_blacklisted(plugin_name): return 'Load this plugin first with !load %s' % plugin_name obj = get_plugin_obj_by_name(plugin_name) if obj is None: return 'Unknown plugin or the plugin could not load %s' % plugin_name template_obj = obj.get_configuration_template() if template_obj is None: return 'This plugin is not configurable.' if len(args) == 1: current_config = self.get_plugin_configuration(plugin_name) answer = 'Copy paste and adapt the following:\n!config %s ' % plugin_name if current_config: return answer + str(current_config) return answer + str(template_obj) try: real_config_obj = literal_eval(' '.join(args[1:])) except Exception as e: logging.exception('Invalid expression for the configuration of the plugin') return 'Syntax error in the given configuration' if type(real_config_obj) != type(template_obj): return 'It looks fishy, your config type is not the same as the template !' self.set_plugin_configuration(plugin_name, real_config_obj) self.deactivate_plugin(plugin_name) try: self.activate_plugin(plugin_name) except PluginConfigurationException, ce: logging.debug('Invalid configuration for the plugin, reverting the plugin to unconfigured') self.set_plugin_configuration(plugin_name, None) return 'Incorrect plugin configuration: %s' % ce
def test_plugin_callbacks(self, testbot): p = get_plugin_obj_by_name('RoomTest') assert p is not None # Drains the event queue. `p.events.empty()` is unreliable. while True: try: p.events.get(timeout=5) except Empty: break p.query_room('*****@*****.**').join() assert p.events.get(timeout=5) == "callback_room_joined [email protected]" p.query_room('*****@*****.**').topic = "Err rocks!" assert p.events.get(timeout=5) == "callback_room_topic Err rocks!" p.query_room('*****@*****.**').leave() assert p.events.get(timeout=5) == "callback_room_left [email protected]"
def test_plugin_callbacks(self, testbot): p = get_plugin_obj_by_name('RoomTest') assert p is not None # Drains the event queue. `p.events.empty()` is unreliable. while True: try: p.events.get(timeout=5) except Empty: break p.query_room('*****@*****.**').join() assert p.events.get( timeout=5) == "callback_room_joined [email protected]" p.query_room('*****@*****.**').topic = "Err rocks!" assert p.events.get(timeout=5) == "callback_room_topic Err rocks!" p.query_room('*****@*****.**').leave() assert p.events.get( timeout=5) == "callback_room_left [email protected]"
def test_plugin_methods(self, testbot): p = get_plugin_obj_by_name('ChatRoom') assert p is not None assert hasattr(p, 'rooms') assert hasattr(p, 'query_room')
def test_get_garak_quote_datasource_returns_none_on_empty_file(self): p = get_plugin_obj_by_name('GarakBot') p.garak_quote_ds = None p.clear_garak_quote_datasource() quote_data = p.get_garak_quote_datasource() assert quote_data is None
def test_mycommand_tellme_something_with_nodata_fails_gracefully(self): p = get_plugin_obj_by_name('GarakBot') p.garak_quote_ds = None p.clear_garak_quote_datasource() self.assertCommand('! tellme something', "I'm Sorry, I have nothing to say. For now.")
def test_load_data_sources_fails_gracefully_with_StringIO(self): p = get_plugin_obj_by_name('GarakBot') fp = StringIO('') p.garak_quote_ds = fp quote_data = p.load_data_sources() assert quote_data is None
def test_load_data_sources_fails_gracefully_with_DiskFile(self): p = get_plugin_obj_by_name('GarakBot') p.garak_quote_ds = 'BAD_FILE' quote_data = p.load_data_sources() assert quote_data is None