-
Notifications
You must be signed in to change notification settings - Fork 103
/
PluginManager.py
125 lines (100 loc) · 4.46 KB
/
PluginManager.py
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
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
115
116
117
118
119
120
121
122
import os
import re
import logging
from plugin import Plugin, __criteria_key__, NecessaryModuleNotFound, ApiKeyNotFoundException
from types import FunctionType
logger = logging.getLogger("logger")
pluginPath = "plugins"
__config_file__ = "plugins.conf"
__apikeys_file__ = "apiKeys.conf"
plugins = dict()
prioritizedPlugins = dict()
apiKeys = dict()
def load_plugins():
with open(__config_file__, "r") as fh:
for line in fh:
line = line.strip()
if line.startswith("#") or line == "":
continue
# just load the whole shit...
try:
__import__(pluginPath+"."+line, globals(), locals(), [], -1)
except NecessaryModuleNotFound as e:
logger.critical("Failed loading plugin due to missing module: "+str(e))
except ApiKeyNotFoundException as e:
logger.critical("Failed loading plugin due to missing API key: "+str(e))
except:
logger.exception("Plugin loading failed")
# as they are loaded in the order in the file we will have the same order in __subclasses__()... I hope
for clazz in Plugin.__subclasses__():
# look at all functions of a class lets filter them first
methods = filter(lambda x: type(x) == FunctionType, clazz.__dict__.values())
# now we check if the method is decorated by register
for method in methods:
if __criteria_key__ in method.__dict__:
criterias = method.__dict__[__criteria_key__]
for lang, regex in criterias.items():
if not lang in plugins:
plugins[lang] = []
# yeah... save the regex, the clazz and the method, shit just got loaded...
plugins[lang].append((regex, clazz, method))
def reload_api_keys():
apiKeys = dict()
load_api_keys()
def load_api_keys():
with open(__apikeys_file__, "r") as fh:
for line in fh:
line = line.strip()
if line.startswith("#") or line == "":
continue
kv = line.split("=", 1)
try:
apiName = str.lower(kv[0]).strip()
kv[1] = kv[1].strip()
apiKey = kv[1][1:-1] #stip the ""
apiKeys[apiName] = apiKey
except:
logger.critical("There was an error parsing an API in the line: "+ line)
def getAPIKeyForAPI(APIname):
apiName = str.lower(APIname)
if apiName in apiKeys:
return apiKeys[apiName]
return None
def getPlugin(speech, language):
if language in plugins:
for (regex, clazz, method) in plugins[language]:
if regex.match(speech) != None:
return (clazz, method)
return (None, None)
def clearPriorityFor(assistantId):
if assistantId in prioritizedPlugins:
del prioritizedPlugins[assistantId]
def prioritizePluginObject(pluginObj, assistantId):
prioritizedPlugins[assistantId] = dict()
for lang in plugins.keys():
for (regex, clazz, method) in plugins[lang]:
if pluginObj.__class__ == clazz:
if not lang in prioritizedPlugins[assistantId]:
prioritizedPlugins[assistantId][lang] = []
prioritizedPlugins[assistantId][lang].append((regex, pluginObj, method))
def searchPrioritizedPlugin(assistantId, speech, language):
if assistantId in prioritizedPlugins:
if language in prioritizedPlugins[assistantId]:
for (regex, pluginObj, method) in prioritizedPlugins[assistantId][language]:
if regex.match(speech) != None:
return (pluginObj, method)
return (None, None)
def getPluginForImmediateExecution(assistantId, speech, language, otherPluginParams):
(sendObj, sendPlist, assistant, location) = otherPluginParams
(pluginObj, method) = searchPrioritizedPlugin(assistantId, speech, language)
if pluginObj == None and method == None:
(clazz, method) = getPlugin(speech, language)
if clazz != None and method != None:
pluginObj = clazz()
pluginObj.initialize(method, speech, language, sendObj, sendPlist, assistant, location)
#prioritizePluginObject(pluginObj, assistantId)
else:
#reinitialize it
logger.info("Found a matching prioritized plugin")
pluginObj.initialize(method, speech, language, sendObj, sendPlist, assistant, location)
return pluginObj