-
Notifications
You must be signed in to change notification settings - Fork 0
/
PluginManager.py
127 lines (102 loc) · 4.49 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
123
124
from plugin import Plugin, __criteria_key__, NecessaryModuleNotFound, \
ApiKeyNotFoundException
from types import FunctionType
import logging
import os
import re
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():
global apiKeys
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