Пример #1
0
    def test_load_with_subs(self):
        subs = Substitutions()
        subs.add_substitute("$ALLOW_SYSTEM", True)

        config_data = XMLConfigurationFile()
        self.assertIsNotNone(config_data)
        configuration = config_data.load_from_text("""<?xml version="1.0" encoding="UTF-8" ?>
<root>
	<brain>
		<overrides>
			<allow_system_aiml>true</allow_system_aiml>
			<allow_learn_aiml>true</allow_learn_aiml>
			<allow_learnf_aiml>true</allow_learnf_aiml>
		</overrides>
    </brain>
</root>""", ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        section = config_data.get_section("brainx")
        self.assertIsNone(section)

        section = config_data.get_section("brain")
        self.assertIsNotNone(section)

        child_section = config_data.get_section("overrides", section)
        self.assertIsNotNone(child_section)

        self.assertEqual(True, config_data.get_option(child_section, "allow_system_aiml"))
        self.assertEqual(True, config_data.get_bool_option(child_section, "allow_system_aiml"))
        self.assertEqual(False, config_data.get_bool_option(child_section, "other_value"))
Пример #2
0
    def test_load_with_subs(self):

        subs = Substitutions()
        subs.add_substitute("$ALLOW_SYSTEM", True)

        config_data = YamlConfigurationFile()
        self.assertIsNotNone(config_data)
        configuration = config_data.load_from_text("""
            brain:
                overrides:
                  allow_system_aiml: true
                  allow_learn_aiml: true
                  allow_learnf_aiml: true
          """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        section = config_data.get_section("brainx")
        self.assertIsNone(section)

        section = config_data.get_section("brain")
        self.assertIsNotNone(section)

        child_section = config_data.get_section("overrides", section)
        self.assertIsNotNone(child_section)

        self.assertEqual(True, config_data.get_option(child_section, "allow_system_aiml"))
        self.assertEqual(True, config_data.get_bool_option(child_section, "allow_system_aiml"))
        self.assertEqual(False, config_data.get_bool_option(child_section, "other_value"))
Пример #3
0
    def test_add_duplicate(self):

        sub = Substitutions()

        sub.add_substitute("$FIRSTNAME", "Fred")
        sub.add_substitute("$FIRSTNAME", "Fred")

        self.assertTrue(sub.has_substitute("$FIRSTNAME"))
Пример #4
0
    def test_load_bad_subs(self):

        sub = Substitutions()

        sub.load_substitutions(
            os.path.dirname(__file__) + os.sep + "bad_subs.txt")

        with self.assertRaises(ValueError):
            _ = sub.get_substitute("$FIRSTNAME")
Пример #5
0
    def test_load(self):

        sub = Substitutions()

        sub.load_substitutions(os.path.dirname(__file__) + os.sep + "subs.txt")

        self.assertEquals("Fred", sub.get_substitute("$FIRSTNAME"))
        self.assertEquals("West", sub.get_substitute("$SURNAME"))
        self.assertEquals("Mary", sub.get_substitute("$WIFE"))

        with self.assertRaises(ValueError):
            sub.get_substitute("$NUMBER")
Пример #6
0
    def __init__(self, botid, argument_parser=None):
        self._id = botid
        self._license_keys = LicenseKeys()
        self._storage = None
        self._scheduler = None
        self._email = None
        self._trigger_mgr = None
        self._configuration = None
        self._ping_responder = None

        self._questions = 0

        self._arguments = self.parse_arguments(argument_parser=argument_parser)

        self.initiate_logging(self.arguments)

        self._subsitutions = Substitutions()
        if self.arguments.substitutions is not None:
            self._subsitutions.load_substitutions(self.arguments.substitutions)

        self.load_configuration(self.arguments)
        self.parse_configuration()

        self.load_storage()

        self.load_license_keys()
        self.get_license_keys()
        self._configuration.client_configuration.check_for_license_keys(
            self._license_keys)

        self._bot_factory = BotFactory(self,
                                       self.configuration.client_configuration)

        self.load_scheduler()

        self._renderer = None
        self.load_renderer()

        self.load_email()

        self.load_trigger_manager()

        self.load_ping_responder()

        self.post_initialise()
Пример #7
0
    def __init__(self, id, argument_parser=None):
        self._id = id
        self._license_keys = LicenseKeys()
        self._storage = None
        self._scheduler = None
        self._email = None
        self._trigger_mgr = None
        self._configuration = None
        self._bot_root = '.'
        self._engine_version = None

        self._arguments = self.parse_arguments(argument_parser=argument_parser)
        self._engine_version = self._arguments.version

        self.initiate_logging(self.arguments)

        self._subsitutions = Substitutions()
        if self.arguments.substitutions is not None:
            self._subsitutions.load_substitutions(self.arguments.substitutions)
            self.load_configuration(self.arguments, subs=self._subsitutions)
        else:
            self.load_configuration(self.arguments)

        self.parse_configuration()

        self.load_storage()

        self._bot_factory = BotFactory(self,
                                       self.configuration.client_configuration)

        self.load_license_keys()
        self.get_license_keys()
        self._configuration.client_configuration.check_for_license_keys(
            self._license_keys)

        self.load_scheduler()

        self.load_renderer()

        self.load_email()

        self.load_trigger_manager()
Пример #8
0
    def test_substitutions(self):

        sub = Substitutions()

        sub.load_substitutions(os.path.dirname(__file__) + os.sep + "subs.txt")

        self.assertEquals("My name is Fred West", sub.replace("My name is $FIRSTNAME $SURNAME"))
        self.assertEquals("My name is FredWest", sub.replace("My name is $FIRSTNAME$SURNAME"))
Пример #9
0
    def test_basics(self):

        sub = Substitutions()

        sub.add_substitute("$FIRSTNAME", "Fred")
        sub.add_substitute("$SURNAME", "West")
        sub.add_substitute("$WIFE", "Mary")

        self.assertTrue(sub.has_substitute("$FIRSTNAME"))
        self.assertFalse(sub.has_substitute("$FRED"))

        self.assertEquals("Fred", sub.get_substitute("$FIRSTNAME"))
        self.assertEquals("West", sub.get_substitute("$SURNAME"))
        self.assertEquals("Mary", sub.get_substitute("$WIFE"))

        with self.assertRaises(ValueError):
            sub.get_substitute("$NUMBER")

        sub.empty()

        self.assertFalse(sub.has_substitute("$FIRSTNAME"))
        self.assertFalse(sub.has_substitute("$SURNAME"))
        self.assertFalse(sub.has_substitute("$WIFE"))
Пример #10
0
 def test_replace_subs(self):
     config = MockBaseConfigurationFile()
     subs = Substitutions()
     subs.add_substitute("TEST", "VALUE")
     self.assertEquals("VALUE", config._replace_subs(subs, "TEST"))
Пример #11
0
class BotClient(ResponseLogger):
    def __init__(self, id, argument_parser=None):
        self._id = id
        self._license_keys = LicenseKeys()
        self._storage = None
        self._scheduler = None
        self._email = None
        self._trigger_mgr = None
        self._configuration = None

        self._arguments = self.parse_arguments(argument_parser=argument_parser)

        self.initiate_logging(self.arguments)

        self._subsitutions = Substitutions()
        if self.arguments.substitutions is not None:
            self._subsitutions.load_substitutions(self.arguments.substitutions)
            self.load_configuration(self.arguments, subs=self._subsitutions)
        else:
            self.load_configuration(self.arguments)

        self.parse_configuration()

        self.load_storage()

        self._bot_factory = BotFactory(self,
                                       self.configuration.client_configuration)

        self.load_license_keys()
        self.get_license_keys()
        self._configuration.client_configuration.check_for_license_keys(
            self._license_keys)

        self.load_scheduler()

        self.load_renderer()

        self.load_email()

        self.load_trigger_manager()

    def ylogger_type(self):
        return "client"

    @property
    def configuration(self):
        return self._configuration

    @property
    def id(self):
        return self._id

    @property
    def arguments(self):
        return self._arguments

    @property
    def license_keys(self):
        return self._license_keys

    @property
    def scheduler(self):
        return self._scheduler

    @property
    def storage_factory(self):
        return self._storage

    @property
    def bot_factory(self):
        return self._bot_factory

    @property
    def renderer(self):
        return self._renderer

    @property
    def trigger_manager(self):
        return self._trigger_mgr

    def get_description(self):
        if self.configuration is not None:
            if self.configuration.client_configuration is not None:
                return self.configuration.client_configuration.description
        return "Bot Client"

    def add_client_arguments(self, parser=None):
        # Nothing to add
        return

    def parse_configuration(self):
        # Nothing to add
        return

    def parse_args(self, arguments, parsed_args):
        # Nothing to add
        return

    def parse_arguments(self, argument_parser):
        client_args = CommandLineClientArguments(self, parser=argument_parser)
        client_args.parse_args(self)
        return client_args

    def load_license_keys(self):
        if self.storage_factory.entity_storage_engine_available(
                StorageFactory.LICENSE_KEYS) is True:
            storage_engine = self.storage_factory.entity_storage_engine(
                StorageFactory.LICENSE_KEYS)
            keys_store = storage_engine.license_store()
            keys_store.load(self._license_keys)
        else:
            YLogger.warning(self,
                            "No storage factory setting for license_keys")

    def get_license_keys(self):
        return

    def initiate_logging(self, arguments):
        if arguments.logging is not None:
            try:
                with open(arguments.logging, 'r+',
                          encoding="utf-8") as yml_data_file:
                    logging_config = yaml.load(yml_data_file)
                    logging.config.dictConfig(logging_config)
                    YLogger.debug(self, "Now logging under configuration")

            except Exception as excep:
                YLogger.exception(self,
                                  "Failed to open logging configuration [%s]",
                                  excep, arguments.logging)
        else:
            print(
                "Warning. No logging configuration file defined, using defaults..."
            )

    def get_client_configuration(self):
        """
        By overriding this class in you Configuration file, you can add new configurations
        and stil use the dynamic loader capabilities
        :return: Client configuration object
        """
        raise NotImplementedError(
            "You must override this and return a subclassed client configuration"
        )

    def load_configuration(self, arguments, subs: Substitutions = None):
        if arguments.bot_root is None:
            if arguments.config_filename is not None:
                arguments.bot_root = os.path.dirname(arguments.config_filename)
            else:
                arguments.bot_root = "."
            YLogger.debug(
                None, "No bot root argument set, defaulting to [%s]" %
                arguments.bot_root)

        if arguments.config_filename is not None:
            self._configuration = ConfigurationFactory.load_configuration_from_file(
                self.get_client_configuration(), arguments.config_filename,
                arguments.config_format, arguments.bot_root, subs)
        else:
            YLogger.debug(
                None, "No configuration file specified, using defaults only !")
            self._configuration = ProgramyConfiguration(
                self.get_client_configuration())

    def load_scheduler(self):
        if self.configuration.client_configuration.scheduler is not None:
            YLogger.debug(None, "Loading Scheduler")
            self._scheduler = ProgramyScheduler(
                self, self.configuration.client_configuration.scheduler)
            self._scheduler.start()

    def load_email(self):
        if self._configuration.client_configuration.email is not None:
            YLogger.debug(None, "Loading Email Manager")
            self._email = EmailSender(
                self._configuration.client_configuration.email)

    def load_trigger_manager(self):
        if self._configuration.client_configuration.triggers is not None:
            YLogger.debug(None, "Loading Trigger Manager")
            self._trigger_mgr = TriggerManager.load_trigger_manager(
                self._configuration.client_configuration.triggers)

    def load_storage(self):
        self._storage = StorageFactory()
        if self.configuration.client_configuration.storage is not None:
            YLogger.debug(None, "Loading Storage Factory")
            self._storage.load_engines_from_config(
                self.configuration.client_configuration.storage)
        else:
            YLogger.debug(None, "No storage defined!")

    def load_renderer(self):
        try:
            if self.get_client_configuration().renderer is not None:
                YLogger.debug(None, "Loading Renderer")
                clazz = ClassLoader.instantiate_class(
                    self.get_client_configuration().renderer.renderer)
                self._renderer = clazz(self)
                return

        except Exception as e:
            YLogger.exception(None, "Failed to load config specified renderer",
                              e)

        self._renderer = self.get_default_renderer()

    def get_default_renderer(self):
        return TextRenderer(self)

    def create_client_context(self, userid):
        client_context = ClientContext(self, userid)
        client_context.bot = self._bot_factory.select_bot()
        client_context.brain = client_context.bot._brain_factory.select_brain()
        return client_context

    def startup(self):
        if self._trigger_mgr is not None:
            self._trigger_mgr.trigger(event=SystemTriggers.SYSTEM_STARTUP)

    def shutdown(self):
        if self._trigger_mgr is not None:
            self._trigger_mgr.trigger(event=SystemTriggers.SYSTEM_SHUTDOWN)

    def process_question(self, client_context, question):
        raise NotImplementedError(
            "You must override this and implement the logic to create a response to the question"
        )

    def render_response(self, client_context, response):
        raise NotImplementedError(
            "You must override this and implement the logic to process the response by rendering"
            " using a RCS renderer")

    def process_response(self, client_context, response):
        raise NotImplementedError(
            "You must override this and implement the logic to display the response to the user"
        )

    def run(self):
        raise NotImplementedError(
            "You must override this and implement the logic to run the client")
Пример #12
0
    def __init__(self, id, config_file_path, src_root_path=None):
        """
        BotClient that can be initilized in runtime from YAML config

        WARNING this module changes CWD (Current Working Directory)!

        ProgramY has assumptions about current directories and uses environmental variables
        to specify search paths when launched from bash scripts.

        First, ProgramY uses file paths relative to config file.
        Second, ProgramY allows to specify paths to modules which are in dot notation relative to
            project root, which is different from config dir and usually placed 2 directories higher

        In this module we gather all this configurations via parameters.

        :param id: str, unique identifier of the bot
        :param config_file_path: path to the YAML config file
        :param src_root_path: sometimes YAML config path asserts that we reference to
            modules which are part of another project, and src_modules_root_path - is a path from
            which we look for specified modules. For example YAML config
                joiner:
                    classname: templatey.processors.sentence_joiner_deduplicator.SentenceJoinerDeDuplicator
            means that a class SentenceJoinerDeDuplicator will be searched from
            src_modules_root_path by appending dot prefixes.

        """
        self._id = id
        self._license_keys = LicenseKeys()
        self._storage = None
        self._scheduler = None
        self._email = None
        self._trigger_mgr = None
        self._configuration = None
        self._ping_responder = None

        self._questions = 0

        self._arguments = self.parse_arguments(argument_parser=None)

        # hack:
        if self._arguments._logging == 10:
            self._arguments._logging = None

        self.initiate_logging(self.arguments)

        self._subsitutions = Substitutions()
        if self.arguments.substitutions is not None:
            self._subsitutions.load_substitutions(self.arguments.substitutions)

        # specify configuration file
        self._config_filename = config_file_path

        self.load_configuration(self.arguments)
        # self.parse_configuration()

        self.load_storage()

        ##############################################################################
        # set path because config uses relative paths
        # this required so the files specified as relative paths in YAML will be interpreted
        # correctly like in the example:
        # categories_storage:
        #                   dirs: ../../storage/categories
        #                   subdirs: true
        #                   extension: .aiml
        current_dir_path = os.path.dirname(self._config_filename)
        os.chdir(current_dir_path)
        ##############################################################################

        ##############################################################################
        # to be able to find modules of dream aiml such as SentenceDeduplicator
        if not src_root_path:
            src_root_path = os.path.dirname(os.path.dirname(current_dir_path))
            src_root_path += "/src"
        sys.path.append(src_root_path)
        ##############################################################################

        self._bot_factory = BotFactory(self,
                                       self.configuration.client_configuration)

        self.load_license_keys()
        self.get_license_keys()
        self._configuration.client_configuration.check_for_license_keys(
            self._license_keys)

        self.load_scheduler()

        self.load_renderer()

        self.load_email()

        self.load_trigger_manager()

        self.load_ping_responder()
Пример #13
0
    def _replace_subs(self, subs: Substitutions, value):
        if subs is not None:
            return subs.replace(value)

        return value
Пример #14
0
    def test_substitutions_no_file(self):

        sub = Substitutions()

        sub.load_substitutions(None)