Completed
Push — master ( e1c780...e7077f )
by Daniel
56s
created

App.strict()   A

Complexity

Conditions 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
1
"""
2
groundwork module provides mainly the App class, which is a container for all functions and
3
data related to plugins and their patterns.
4
"""
5
import logging
6
import logging.config
7
import sys
8
import os
9
10
from groundwork.configuration import ConfigManager
11
from groundwork.pluginmanager import PluginManager
12
from groundwork.signals import SignalsApplication
13
14
15
class App(object):
16
    """
17
    Application object for a groundwork app.
18
    Loads configurations, configures logs, initialises and activates plugins and provides managers.
19
20
    Performed steps during start up:
21
      1. load configuration
22
      2. configure logs
23
      3. get valid groundwork plugins
24
      4. activate configured plugins
25
26
    :param config_files: List of config files, which shall be loaded
27
    :type config_files: list of str
28
    :param plugins: List of plugins, which shall be registered
29
    :type plugins: Plugin-Classes, based on :class:`~groundwork.patterns.gw_base_pattern.GwBasePattern`
30
    :param strict: If true, Exceptions are thrown, if a plugin can not be initialised or activated.
31
    """
32
    def __init__(self, config_files=None, plugins=None, strict=False):
33
        if config_files is None:
34
            config_files = []
35
36
        self.strict = strict
37
38
        #: logging object for sending log messages. Example::
39
        #:
40
        #:  from groundwork import App
41
        #:  my_app = App()
42
        #:  my_app.log.debug("Send debug message")
43
        #:  my_app.log.error("Send error....")
44
        self.log = logging.getLogger("groundwork")
45
46
        self._configure_logging()
47
        self.log.info("Initializing groundwork")
48
        self.log.info("Reading configuration")
49
50
        #: Instance of :class:`~groundwork.configuration.configmanager.ConfigManager`.
51
        #: Used to load different configuration files and create a common configuration object.
52
        self.config = ConfigManager().load(config_files)
53
54
        self._configure_logging(self.config.get("GROUNDWORK_LOGGING"))
55
56
        #: Name of the application. Is configurable by parameter "APP_NAME" of a configuration file.
57
        self.name = self.config.get("APP_NAME", None) or "NoName App"
58
59
        #: Absolute application path. Is configurable by parameter "APP_PATH" of a configuration file.
60
        #: If not given, the current working  directory is taken.
61
        #: The path is used to calculate absolute paths for tests, documentation and much more.
62
        self.path = os.path.abspath(self.config.get("APP_PATH", None) or os.getcwd())
63
64
        #: Instance of :class:`~groundwork.signals.SignalsApplication`. Provides functions to register and fire
65
        # signals or receivers on application level.
66
        self.signals = SignalsApplication(app=self)
67
68
        self.signals.register("plugin_activate_pre", self,
69
                              "Gets send right before activation routine of a plugins will be executed")
70
        self.signals.register("plugin_activate_post", self,
71
                              "Gets send right after activation routine of a plugins was executed")
72
        self.signals.register("plugin_deactivate_pre", self,
73
                              "Gets send right before deactivation routine of a plugins will be executed")
74
        self.signals.register("plugin_deactivate_post", self,
75
                              "Gets send right after deactivation routine of a plugins was executed")
76
77
        #: Instance of :class:`~groundwork.pluginmanager.PluginManager`- Provides functions to load, activate and
78
        # deactivate plugins.
79
        self.plugins = PluginManager(app=self)
80
81
        if plugins is not None:
82
            self.plugins.classes.register(plugins)
83
84
    def _configure_logging(self, logger_dict=None):
85
        """
86
        Configures the logging module with a given dictionary, which in most cases was loaded from a configuration
87
        file.
88
89
        If no dictionary is provided, it falls back to a default configuration.
90
91
        See `Python docs
92
        <https://docs.python.org/3.5/library/logging.config.html#logging.config.dictConfig>`_ for more information.
93
94
        :param logger_dict: dictionary for logger.
95
        """
96
        self.log.debug("Configure logging")
97
98
        # Let's be sure, that for our log no handlers are registered anymore
99
        if self.log.hasHandlers():
100
                for handler in self.log.handlers:
101
                    self.log.removeHandler(handler)
102
        if logger_dict is None:
103
            self.log.debug("No logger dictionary defined. Doing default logger configuration")
104
            formatter = logging.Formatter("%(name)s - %(asctime)s - [%(levelname)s] - %(module)s - %(message)s")
105
            stream_handler = logging.StreamHandler(sys.stdout)
106
            stream_handler.setLevel(logging.WARNING)
107
            stream_handler.setFormatter(formatter)
108
            self.log.addHandler(stream_handler)
109
            self.log.setLevel(logging.WARNING)
110
        else:
111
            self.log.debug("Logger dictionary defined. Loading dictConfig for logging")
112
            logging.config.dictConfig(logger_dict)
113
            self.log.debug("dictConfig loaded")
114