Completed
Push — master ( bd2cb5...b3c20f )
by Daniel
01:02
created

App.__init__()   B

Complexity

Conditions 6

Size

Total Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
c 2
b 0
f 0
dl 0
loc 58
rs 7.8167

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
        #: Absolute application path. Is configurable by parameter "APP_PATH" of a configuration file.
55
        #: If not given, the current working  directory is taken.
56
        #: The path is used to calculate absolute paths for tests, documentation and much more.
57
        self.path = self.config.get("APP_PATH", None)
58
        if self.path is None:
59
            self.path = os.getcwd()
60
        elif not os.path.isabs(self.path):
61
            self.path = os.path.abspath(self.path)
62
            self.log.warning("Given APP_PATH is relative, calculated following, absolute path: %s" % self.path)
63
        elif not os.path.exists(self.path):
64
            raise NotADirectoryError("Given APP_PATH does not exist: %s" % self.path)
65
66
        self._configure_logging(self.config.get("GROUNDWORK_LOGGING"))
67
68
        #: Name of the application. Is configurable by parameter "APP_NAME" of a configuration file.
69
        self.name = self.config.get("APP_NAME", None) or "NoName App"
70
71
        #: Instance of :class:`~groundwork.signals.SignalsApplication`. Provides functions to register and fire
72
        # signals or receivers on application level.
73
        self.signals = SignalsApplication(app=self)
74
75
        self.signals.register("plugin_activate_pre", self,
76
                              "Gets send right before activation routine of a plugins will be executed")
77
        self.signals.register("plugin_activate_post", self,
78
                              "Gets send right after activation routine of a plugins was executed")
79
        self.signals.register("plugin_deactivate_pre", self,
80
                              "Gets send right before deactivation routine of a plugins will be executed")
81
        self.signals.register("plugin_deactivate_post", self,
82
                              "Gets send right after deactivation routine of a plugins was executed")
83
84
        #: Instance of :class:`~groundwork.pluginmanager.PluginManager`- Provides functions to load, activate and
85
        # deactivate plugins.
86
        self.plugins = PluginManager(app=self)
87
88
        if plugins is not None:
89
            self.plugins.classes.register(plugins)
90
91
    def _configure_logging(self, logger_dict=None):
92
        """
93
        Configures the logging module with a given dictionary, which in most cases was loaded from a configuration
94
        file.
95
96
        If no dictionary is provided, it falls back to a default configuration.
97
98
        See `Python docs
99
        <https://docs.python.org/3.5/library/logging.config.html#logging.config.dictConfig>`_ for more information.
100
101
        :param logger_dict: dictionary for logger.
102
        """
103
        self.log.debug("Configure logging")
104
105
        # Let's be sure, that for our log no handlers are registered anymore
106
        if self.log.hasHandlers():
107
                for handler in self.log.handlers:
108
                    self.log.removeHandler(handler)
109
        if logger_dict is None:
110
            self.log.debug("No logger dictionary defined. Doing default logger configuration")
111
            formatter = logging.Formatter("%(name)s - %(asctime)s - [%(levelname)s] - %(module)s - %(message)s")
112
            stream_handler = logging.StreamHandler(sys.stdout)
113
            stream_handler.setLevel(logging.WARNING)
114
            stream_handler.setFormatter(formatter)
115
            self.log.addHandler(stream_handler)
116
            self.log.setLevel(logging.WARNING)
117
        else:
118
            self.log.debug("Logger dictionary defined. Loading dictConfig for logging")
119
            logging.config.dictConfig(logger_dict)
120
            self.log.debug("dictConfig loaded")
121