Ejemplo n.º 1
0
    def get(raw_command_id):
        command_string = raw_command_id
        command_id = None

        try:
            command_id = int(command_string)
        except (ValueError, TypeError):
            pass

        if command_id:
            command = find(
                lambda c: c["id"] == command_id,
                greenbot.web.utils.get_cached_commands(),
            )
        else:
            command = find(
                lambda c: c["resolve_string"] == command_string,
                greenbot.web.utils.get_cached_commands(),
            )

        if not command:
            return {
                "message": "A command with the given ID was not found."
            }, 404

        return {"command": command}, 200
Ejemplo n.º 2
0
    def command_detailed(raw_command_string):
        command_string_parts = raw_command_string.split("-")
        command_string = command_string_parts[0]
        command_id = None
        try:
            command_id = int(command_string)
        except ValueError:
            pass

        bot_commands_list = get_commands_list()

        if command_id is not None:
            command = find(lambda c: c["id"] == command_id, bot_commands_list)
        else:
            command = find(lambda c: c["resolve_string"] == command_string,
                           bot_commands_list)

        if command is None:
            # XXX: Is it proper to have it return a 404 code as well?
            return render_template("command_404.html")

        examples = command["examples"]

        return render_template("command_detailed.html",
                               command=command,
                               examples=examples)
Ejemplo n.º 3
0
 def find_match(self, message, banphrase_id=None):
     match = None
     if banphrase_id is not None:
         match = find(lambda banphrase: banphrase.id == banphrase_id,
                      self.banphrases)
     if match is None:
         match = find(lambda banphrase: banphrase.exact_match(message),
                      self.banphrases)
     return match
Ejemplo n.º 4
0
    def on_banphrase_update(self, data):
        try:
            banphrase_id = int(data["id"])
        except (KeyError, ValueError):
            log.warning("No banphrase ID found in on_banphrase_update")
            return False

        updated_banphrase = find(
            lambda banphrase: banphrase.id == banphrase_id, self.banphrases)
        if updated_banphrase:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                db_session.add(updated_banphrase)
                db_session.refresh(updated_banphrase)
                db_session.expunge(updated_banphrase)
        else:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                updated_banphrase = (db_session.query(Banphrase).filter_by(
                    id=banphrase_id).one_or_none())
                db_session.expunge_all()
                if updated_banphrase is not None:
                    self.db_session.add(updated_banphrase.data)

        if updated_banphrase:
            if updated_banphrase not in self.banphrases:
                self.banphrases.append(updated_banphrase)
            if (updated_banphrase.enabled is True
                    and updated_banphrase not in self.enabled_banphrases):
                self.enabled_banphrases.append(updated_banphrase)

        for banphrase in self.enabled_banphrases:
            if banphrase.enabled is False:
                self.enabled_banphrases.remove(banphrase)
Ejemplo n.º 5
0
    def load(self, do_reload=True):
        """ Load module classes """

        from greenbot.modules import available_modules

        self.all_modules = [module(self.bot) for module in available_modules]

        with DBManager.create_session_scope() as db_session:
            # Make sure there's a row in the DB for each module that's available
            db_modules = db_session.query(Module).all()
            for module in self.all_modules:
                mod = find(
                    lambda db_module, registered_module=module: db_module.id ==
                    registered_module.ID,
                    db_modules,
                )
                if mod is None:
                    log.info(f"Creating row in DB for module {module.ID}")
                    mod = Module(module.ID, enabled=module.ENABLED_DEFAULT)
                    db_session.add(mod)

        if do_reload is True:
            self.reload()

        return self
Ejemplo n.º 6
0
    def parse_settings(self, **in_settings):
        ret = {}
        for key, value in in_settings.items():
            setting = find(
                lambda setting, setting_key=key: setting.key == setting_key,
                self.SETTINGS,
            )
            if setting is None:
                # We were passed a setting that's not available for this module
                return False
            log.debug(f"{key}: {value}")
            res, new_value = setting.validate(value)
            if res is False:
                # Something went wrong when validating one of the settings
                log.warning(new_value)
                return False

            ret[key] = new_value

        for setting in self.SETTINGS:
            if setting.type == "boolean":
                if setting.key not in ret:
                    ret[setting.key] = False
                    log.debug("{}: {} - special".format(setting.key, False))

        return ret
Ejemplo n.º 7
0
def validate_module(module_id):
    module = find(lambda m: m.ID == module_id,
                  greenbot.modules.available_modules)

    if module is None:
        return False

    return module.MODULE_TYPE not in (ModuleType.TYPE_ALWAYS_ENABLED, )
Ejemplo n.º 8
0
 def remove_handler(event, method):
     handler = None
     try:
         handler = find(
             lambda h: HandlerManager.method_matches(h, method),
             HandlerManager.handlers[event],
         )
         if handler is not None:
             HandlerManager.handlers[event].remove(handler)
     except KeyError:
         # No handlers for this event found
         log.error(f"remove_handler No handler for {event} found.")
Ejemplo n.º 9
0
 def tick(self):
     if self.bot.is_online:
         for timer in self.online_timers:
             timer.time_to_send_online -= 1
         timer = find(lambda timer: timer.time_to_send_online <= 0,
                      self.online_timers)
         if timer:
             timer.run(self.bot)
             timer.time_to_send_online = timer.interval_online
             self.online_timers.remove(timer)
             self.online_timers.append(timer)
     else:
         for timer in self.offline_timers:
             timer.time_to_send_offline -= 1
         timer = find(lambda timer: timer.time_to_send_offline <= 0,
                      self.offline_timers)
         if timer:
             timer.run(self.bot)
             timer.time_to_send_offline = timer.interval_offline
             self.offline_timers.remove(timer)
             self.offline_timers.append(timer)
Ejemplo n.º 10
0
    def modules(**options):
        module_manager = ModuleManager(None).load(do_reload=False)
        for module in module_manager.all_modules:
            module.db_module = None
        with DBManager.create_session_scope() as db_session:
            for db_module in db_session.query(Module):
                module = find(lambda m: m.ID == db_module.id,
                              module_manager.all_modules)
                if module:
                    module.db_module = db_module

            return render_template("admin/modules.html",
                                   modules=module_manager.all_modules)
Ejemplo n.º 11
0
    def reload(self):
        # TODO: Make disable/enable better, so we don't need to disable modules
        # that we're just going to enable again further down below.
        for module in self.modules:
            module.disable(self.bot)

        self.modules = []

        with DBManager.create_session_scope() as db_session:
            for enabled_module in db_session.query(Module).filter_by(
                    enabled=True):
                module = self.get_module(enabled_module.id)
                if module is not None:
                    options = {}
                    if enabled_module.settings is not None:
                        try:
                            options["settings"] = json.loads(
                                enabled_module.settings)
                        except ValueError:
                            log.warning("Invalid JSON")

                    self.modules.append(module.load(**options))
                    module.enable(self.bot)

        to_be_removed = []
        self.modules.sort(
            key=lambda m: 1 if m.PARENT_MODULE is not None else 0)
        for module in self.modules:
            if module.PARENT_MODULE is None:
                module.submodules = []
            else:
                parent = find(lambda m: m.__class__ == module.PARENT_MODULE,
                              self.modules)
                if parent is not None:
                    parent.submodules.append(module)
                    module.parent_module = parent
                else:
                    # log.warning('Missing parent for module {}, disabling it.'.format(module.NAME))
                    module.parent_module = None
                    to_be_removed.append(module)

        for module in to_be_removed:
            module.disable(self.bot)
            self.modules.remove(module)

        # Perform a last on_loaded call on each module.
        # This is used for things that require submodules to be loaded properly
        # i.e. the quest system
        for module in self.modules:
            module.on_loaded()
Ejemplo n.º 12
0
    async def on_command_update(self, data):
        try:
            command_id = int(data["command_id"])
        except (KeyError, ValueError):
            log.warning("No command ID found in on_command_update")
            return

        command = find(lambda command: command.id == command_id,
                       self.db_commands.values())
        if command is not None:
            self.remove_command_aliases(command)

        self.load_by_id(command_id)

        log.debug(f"Reloaded command with id {command_id}")

        self.rebuild()
Ejemplo n.º 13
0
    def on_timer_remove(self, data):
        try:
            timer_id = int(data["id"])
        except (KeyError, ValueError):
            log.warning("No timer ID found in on_timer_update")
            return False

        removed_timer = find(lambda timer: timer.id == timer_id, self.timers)
        if removed_timer:
            if removed_timer in self.timers:
                self.timers.remove(removed_timer)
            if removed_timer in self.online_timers:
                self.online_timers.remove(removed_timer)
            if removed_timer in self.offline_timers:
                self.offline_timers.remove(removed_timer)

        return True
Ejemplo n.º 14
0
    def on_timer_update(self, data):
        try:
            timer_id = int(data["id"])
        except (KeyError, ValueError):
            log.warning("No timer ID found in on_timer_update")
            return False

        updated_timer = find(lambda timer: timer.id == timer_id, self.timers)
        if updated_timer:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                db_session.add(updated_timer)
                db_session.refresh(updated_timer)
                updated_timer.refresh_action()
                db_session.expunge(updated_timer)
        else:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                updated_timer = (db_session.query(Timer).filter_by(
                    id=timer_id).one_or_none())

        # Add the updated timer to the timer lists if required
        if updated_timer:
            if updated_timer not in self.timers:
                self.timers.append(updated_timer)

            if updated_timer not in self.online_timers:
                if updated_timer.interval_online > 0:
                    self.online_timers.append(updated_timer)
                    updated_timer.refresh_tts()

            if updated_timer not in self.offline_timers:
                if updated_timer.interval_offline > 0:
                    self.offline_timers.append(updated_timer)
                    updated_timer.refresh_tts()

        for timer in self.online_timers:
            if timer.enabled is False or timer.interval_online <= 0:
                self.online_timers.remove(timer)

        for timer in self.offline_timers:
            if timer.enabled is False or timer.interval_offline <= 0:
                self.offline_timers.remove(timer)

        return True
Ejemplo n.º 15
0
    def on_banphrase_remove(self, data):
        try:
            banphrase_id = int(data["id"])
        except (KeyError, ValueError):
            log.warning("No banphrase ID found in on_banphrase_remove")
            return False

        removed_banphrase = find(
            lambda banphrase: banphrase.id == banphrase_id, self.banphrases)
        if removed_banphrase:
            if removed_banphrase.data and removed_banphrase.data in self.db_session:
                self.db_session.expunge(removed_banphrase.data)

            if removed_banphrase in self.enabled_banphrases:
                self.enabled_banphrases.remove(removed_banphrase)

            if removed_banphrase in self.banphrases:
                self.banphrases.remove(removed_banphrase)
Ejemplo n.º 16
0
    async def on_command_remove(self, data):
        try:
            command_id = int(data["command_id"])
        except (KeyError, ValueError):
            log.warning("No command ID found in on_command_update")
            return

        command = find(lambda command: command.id == command_id,
                       self.db_commands.values())
        if command is None:
            log.warning("Invalid ID sent to on_command_update")
            return

        self.db_session.expunge(command.data)
        self.remove_command_aliases(command)

        log.debug(f"Remove command with id {command_id}")

        self.rebuild()
Ejemplo n.º 17
0
    def modules_edit(module_id, **options):
        module_manager = ModuleManager(None).load(do_reload=False)
        current_module = find(lambda m: m.ID == module_id,
                              module_manager.all_modules)

        user = options["user"]

        if user.level < current_module.CONFIGURE_LEVEL:
            return (
                render_template(
                    "errors/403.html",
                    extra_message=
                    "You do not have permission to configure this module.",
                ),
                403,
            )

        if current_module is None:
            return render_template("admin/module_404.html"), 404

        sub_modules = []
        for module in module_manager.all_modules:
            module.db_module = None

        with DBManager.create_session_scope() as db_session:
            for db_module in db_session.query(Module):
                module = find(lambda m: m.ID == db_module.id,
                              module_manager.all_modules)
                if module:
                    module.db_module = db_module
                    if module.PARENT_MODULE == current_module.__class__:
                        sub_modules.append(module)

            if current_module.db_module is None:
                return render_template("admin/module_404.html"), 404

            if request.method != "POST":
                settings = None
                try:
                    settings = json.loads(current_module.db_module.settings)
                except (TypeError, ValueError):
                    pass
                current_module.load(settings=settings)

                return render_template(
                    "admin/configure_module.html",
                    module=current_module,
                    sub_modules=sub_modules,
                )

            form_values = {key: value for key, value in request.form.items()}
            res = current_module.parse_settings(**form_values)
            if res is False:
                return render_template("admin/module_404.html"), 404

            current_module.db_module.settings = json.dumps(res)
            db_session.commit()

            settings = None
            try:
                settings = json.loads(current_module.db_module.settings)
            except (TypeError, ValueError):
                pass
            current_module.load(settings=settings)

            payload = {"id": current_module.db_module.id}

            SocketClientManager.send("module.update", payload)

            AdminLogManager.post("Module edited", user.discord_id,
                                 current_module.NAME)

            return render_template(
                "admin/configure_module.html",
                module=current_module,
                sub_modules=sub_modules,
            )
Ejemplo n.º 18
0
 def get_module(self, module_id):
     return find(lambda m: m.ID == module_id, self.all_modules)