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
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)
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
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)
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
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
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, )
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.")
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)
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)
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()
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()
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
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
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)
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()
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, )
def get_module(self, module_id): return find(lambda m: m.ID == module_id, self.all_modules)