# -*- coding: utf-8 -*- ########################################################################## # OpenLP - Open Source Lyrics Projection # # ---------------------------------------------------------------------- # # Copyright (c) 2008-2022 OpenLP Developers # # ---------------------------------------------------------------------- # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # ########################################################################## """ The :mod:`core` module provides state management All the core functions of the OpenLP application including the GUI, settings, logging and a plugin framework are contained within the openlp.core module. """ import logging from openlp.core.common import Singleton from openlp.core.common.registry import Registry from openlp.core.common.mixins import LogMixin from openlp.core.lib.plugin import PluginStatus log = logging.getLogger() class StateModule(LogMixin): def __init__(self): """ Holder of State information per module """ super(StateModule, self).__init__() self.name = None self.order = 0 self.is_plugin = None self.status = PluginStatus.Inactive self.pass_preconditions = False self.requires = None self.required_by = None self.text = None class State(LogMixin, metaclass=Singleton): def load_settings(self): self.modules = {} def save_settings(self): pass def add_service(self, name, order, is_plugin=False, status=PluginStatus.Active, requires=None): """ Add a module to the array and load dependencies. There will only be one item per module :param name: Module name :param order: Order to display :param is_plugin: Am I a plugin :param status: The active status :param requires: Module name this requires :return: """ if name not in self.modules: state = StateModule() state.name = name state.order = order state.is_plugin = is_plugin state.status = status state.requires = requires state.required_by = [] self.modules[name] = state if requires and requires in self.modules: if requires not in self.modules[requires].required_by: self.modules[requires].required_by.append(name) def missing_text(self, name, text): """ Updates the preconditions state of a module :param name: Module name :param text: Module missing text :return: """ self.modules[name].text = text def get_text(self): """ return an string of error text :return: a string of text """ error_text = '' for mod in self.modules: if self.modules[mod].text: error_text = error_text + self.modules[mod].text + '\n' return error_text def update_pre_conditions(self, name, status): """ Updates the preconditions state of a module :param name: Module name :param status: Module new status :return: """ self.modules[name].pass_preconditions = status if self.modules[name].is_plugin: plugin = Registry().get('{mod}_plugin'.format(mod=name)) if status: self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name))) plugin.set_status() else: plugin.status = PluginStatus.Disabled def flush_preconditions(self): """ Now all modules are loaded lets update all the preconditions. :return: """ for mods in self.modules: for req in self.modules[mods].required_by: self.modules[req].pass_preconditions = self.modules[mods].pass_preconditions plugins_list = sorted(self.modules, key=lambda state: self.modules[state].order) mdl = {} for pl in plugins_list: mdl[pl] = self.modules[pl] self.modules = mdl def is_module_active(self, name): return self.modules[name].status == PluginStatus.Active def check_preconditions(self, name): """ Checks if a modules preconditions have been met. :param name: Module name :return: Have the preconditions been met. :rtype: bool """ try: if self.modules[name].requires is None: return self.modules[name].pass_preconditions else: mod = self.modules[name].requires return self.modules[mod].pass_preconditions except KeyError: # Module is missing so therefore not found. return False def list_plugins(self): """ Return a list of plugins :return: an array of plugins """ plugins = [] for mod in self.modules: if self.modules[mod].is_plugin: plugins.append(Registry().get('{mod}_plugin'.format(mod=mod))) return plugins