Passed
Pull Request — master (#319)
by Jaisen
01:52
created

elodie.plugins.plugins   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 55
dl 0
loc 97
rs 10
c 0
b 0
f 0
wmc 14

8 Methods

Rating   Name   Duplication   Size   Complexity  
A Plugins.__init__() 0 4 1
A PluginBase.log() 0 2 1
A PluginBase.after() 0 2 1
A PluginBase.__init__() 0 2 1
A Plugins.load() 0 26 4
A PluginBase.before() 0 2 1
A Plugins.run_all_after() 0 2 1
A Plugins.run_all_before() 0 21 4
1
"""
2
Plugin object.
3
4
.. moduleauthor:: Jaisen Mathai <[email protected]>
5
"""
6
from __future__ import print_function
7
from builtins import object
8
9
from importlib import import_module
10
from sys import exc_info
11
from traceback import format_exc
12
13
from elodie.config import load_config_for_plugin, load_plugin_config
14
from elodie import log
15
16
class ElodiePluginError(Exception):
17
    pass
18
19
20
class PluginBase(object):
21
22
    __name__ = 'PluginBase'
23
24
    def __init__(self):
25
        self.config_for_plugin = load_config_for_plugin(self.__name__)
26
27
    def after(self, file_path, destination_folder, final_file_path, media):
28
        pass
29
30
    def before(self, file_path, destination_folder, media):
31
        pass
32
33
    def log(self, msg):
34
        log.info(msg)
35
36
37
38
class Plugins(object):
39
    """A class to execute plugin actions."""
40
41
    def __init__(self):
42
        self.plugins = []
43
        self.classes = {}
44
        self.loaded = False
45
46
    def load(self):
47
        """Load plugins from config file.
48
        """
49
        # If plugins have been loaded then return
50
        if self.loaded == True:
51
            return
52
53
        plugin_list = load_plugin_config()
54
        for plugin in plugin_list:
55
            plugin_lower = plugin.lower()
56
            try:
57
                # We attempt to do the following.
58
                #  1. Load the module of the plugin.
59
                #  2. Instantiate an object of the plugin's class.
60
                #  3. Add the plugin to the list of plugins.
61
                #  
62
                #  #3 should only happen if #2 doesn't throw an error
63
                this_module = import_module('elodie.plugins.{}.{}'.format(plugin_lower, plugin_lower))
64
                self.classes[plugin] = getattr(this_module, plugin)()
65
                # We only append to self.plugins if we're able to load the class
66
                self.plugins.append(plugin)
67
            except:
68
                log.error('An error occurred initiating plugin {}'.format(plugin))
69
                log.error(format_exc())
70
71
        self.loaded = True
72
73
    def run_all_before(self, file_path, destination_folder, media):
74
        self.load()
75
        """Process `before` methods of each plugin that was loaded.
76
        """
77
        pass_status = True
78
        for cls in self.classes:
79
            this_method = getattr(self.classes[cls], 'before')
80
            # We try to call the plugin's `before()` method.
81
            # If the method explicitly raises an ElodiePluginError we'll fail the import
82
            #  by setting pass_status to False.
83
            # If any other error occurs we log the message and proceed as usual.
84
            # By default, plugins don't change behavior.
85
            try:
86
                this_method(file_path, destination_folder, media)
87
            except ElodiePluginError as err:
88
                log.warn('Plugin {} raised an exception: {}'.format(cls, err))
89
                log.error(format_exc())
90
                pass_status = False
91
            except:
92
                log.error(format_exc())
93
        return pass_status
94
95
    def run_all_after(self, file_path, destination_folder, final_file_path, media):
96
        pass
97