summaryrefslogtreecommitdiff
path: root/nephilim/plugins/__init__.py
blob: 7ecca22b75b57c9ee0849ca9f05729ec6a0e7577 (plain)
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import sys
import logging

# { className => [module, className, instance, msg] }
_plugins=None
PLUGIN_MODULE=0
PLUGIN_CLASS=1
PLUGIN_INSTANCE=2
PLUGIN_MSG=3

class Plugins:

    def __init__(self):
        """(Re)load all modules in the plugins directory."""
        global _plugins
        _plugins={}
        for file in os.listdir('nephilim/plugins'):
            if file[-3:]=='.py' and file!='__init__.py':
                name=file[:-3]  # name without ext
                mod='nephilim.plugins.%s'%(name) # mod name
                className='plugin%s'%(name) # classname

                _plugins[className.lower()]=[mod, className, None, None]
                self.loadPlugin(className, None)

    def setPluginMessage(self, name, msg):
        global _plugins
        try:
            _plugins[name.lower()][PLUGIN_MSG]=msg
        except:
            try:
                _plugins["plugin%s"%(name.lower())][PLUGIN_MODULE]=msg
            except:
                pass

    def getPlugin(self, name):
        global _plugins
        try:
            return _plugins[name.lower()][PLUGIN_INSTANCE]
        except:
            try:
                return _plugins["plugin%s"%(name.lower())][PLUGIN_INSTANCE]
            except:
                return None

    def loadPlugin(self, className, parent):
        """Constructs a plugin."""
        global _plugins
        entry=_plugins[className.lower()]
        mod=entry[PLUGIN_MODULE]
        # ensure we get the latest version
        try:
            try:
                sys.modules[mod]
                reimport=True
            except:
                reimport=False

            if reimport:
                reload(sys.modules[mod])
            else:
                module=__import__(mod, globals(), locals(), className, -1)

        except Exception, e:
            _plugins[className.lower()][PLUGIN_MSG]=str(e)
            _plugins[className.lower()][PLUGIN_INSTANCE]=None
            logging.warning("Failed to load plugin %s: %s %s"%(className, str(type(e)), str(e)))
            return None

        module=sys.modules[mod]
        _plugins[className.lower()][PLUGIN_MSG]=None

        if parent:
            # instantiate the plugin
            _plugins[className.lower()][PLUGIN_INSTANCE]=module.__dict__[className](parent)
        else:
            _plugins[className.lower()][PLUGIN_INSTANCE]=None
        return _plugins[className.lower()][PLUGIN_INSTANCE]

    def listPlugins(self):
        """Get the list of plugins available as { className => [mod, className, instance, msg] }."""
        global _plugins
        return _plugins