extensions.py 3.51 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import os
import sys
import importlib

from flask import current_app

try:
    from flask import _app_ctx_stack as stack
except ImportError:
    from flask import _request_ctx_stack as stack

from blueprints import nif_blueprint
from git import Repo, InvalidGitRepositoryError

class Senpy(object):

    def __init__(self, app=None, plugin_folder="plugins"):
        self.app = app
        base_folder = os.path.join(os.path.dirname(__file__), "plugins")

        self.search_folders = (folder for folder in (base_folder, plugin_folder)
                                if folder and os.path.isdir(folder))

        if app is not None:
            self.init_app(app)

    """

        Note: I'm not particularly fond of adding self.app and app.senpy, but
        I can't think of a better way to do it.
    """
    def init_app(self, app, plugin_folder="plugins"):
        app.senpy = self
        #app.config.setdefault('SQLITE3_DATABASE', ':memory:')
        # Use the newstyle teardown_appcontext if it's available,
        # otherwise fall back to the request context
        if hasattr(app, 'teardown_appcontext'):
            app.teardown_appcontext(self.teardown)
        else:
            app.teardown_request(self.teardown)
        app.register_blueprint(nif_blueprint)

    def analyse(self, **params):
        if "algorithm" in params:
            algo = params["algorithm"]
            if algo in self.plugins and self.plugins[algo].enabled:
47
48
49
50
                plug = self.plugins[algo]
                resp = plug.analyse(**params)
                resp.analysis.append(plug.jsonable())
                return resp
51
52
        return {"status": 500, "message": "No valid algorithm"}

53
54
55
56
57
    def parameters(self, algo):
        if algo in self.plugins:
            if hasattr(self.plugins[algo], "parameters"):
                return self.plugins[algo].parameters
        return {}
58
59
60

    def _load_plugin(self, plugin, search_folder, enabled=True):
        sys.path.append(search_folder)
61
        tmp = importlib.import_module(plugin).plugin
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
        sys.path.remove(search_folder)
        tmp.path = search_folder
        try:
            repo_path = os.path.join(search_folder, plugin)
            tmp.repo = Repo(repo_path)
        except InvalidGitRepositoryError:
            tmp.repo = None
        if not hasattr(tmp, "enabled"):
            tmp.enabled = enabled
        return tmp


    def _load_plugins(self):
        #print(sys.path)
        #print(search_folder)
        plugins = {}
        for search_folder in self.search_folders:
            for item in os.listdir(search_folder):
                if os.path.isdir(os.path.join(search_folder, item)) \
                        and os.path.exists(
                            os.path.join(search_folder, item, "__init__.py")):
                    plugins[item] = self._load_plugin(item, search_folder)

        return plugins

    def teardown(self, exception):
        pass

    def enable_all(self):
        for plugin in self.plugins:
            self.enable_plugin(plugin)

    def enable_plugin(self, item):
        self.plugins[item].enabled = True

    def disable_plugin(self, item):
        self.plugins[item].enabled = False

    @property
    def plugins(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(self, '_plugins'):
                self._plugins = self._load_plugins()
            return self._plugins

if __name__ == '__main__':
    from flask import Flask
    app = Flask(__name__)
    sp = Senpy()
    sp.init_app(app)
    with app.app_context():
        sp._load_plugins()