forked from xapi-project/xsconsole
-
Notifications
You must be signed in to change notification settings - Fork 0
/
XSConsoleImporter.py
185 lines (153 loc) · 6.92 KB
/
XSConsoleImporter.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env python
# Copyright (c) 2007-2009 Citrix Systems Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import imp, os, re, sys, traceback
from XSConsoleLog import *
from XSConsoleMenus import *
# pylint: disable-next=function-redefined # function is already defined
class Importer:
plugIns = {}
menuEntries = {}
menuRegenerators = {}
resources = {}
@classmethod
def Reset(cls):
cls.plugIns = {}
cls.menuEntries = {}
cls.menuRegenerators = {}
cls.resources = {}
@classmethod
def ImportAbsDir(cls, inDir):
if os.path.isdir(inDir): # Ignore non-existent directories
for root, dirs, files in os.walk(inDir):
for filename in files:
match = re.match(r'([^/]+)\.py$', filename) # Pick out .py files in the base directory
if match:
importName = match.group(1)
fileObj = None
try:
try:
# Import using variable as module name
(fileObj, pathName, description) = imp.find_module(importName, [root])
imp.load_module(importName, fileObj, pathName, description)
except Exception as e:
try: XSLogError(*traceback.format_tb(sys.exc_info()[2]))
except: pass
try: XSLogError("*** PlugIn '"+importName+"' failed to load: "+str(e))
except: pass
finally:
if fileObj is not None:
fileObj.close()
@classmethod
def ImportRelativeDir(self, inDir):
basePath = sys.path[0]
if basePath == '' and len(sys.path) > 1:
# Handle redundant empty string when running from IDE
basePath = sys.path[1]
self.ImportAbsDir(basePath+'/'+inDir)
@classmethod
def RegisterMenuEntry(cls, inObj, inName, inParams):
if inName not in cls.menuEntries:
cls.menuEntries[inName] = []
cls.menuEntries[inName].append(inParams)
menuName = inParams.get('menuname', None)
menuRegenerator = inParams.get('menuregenerator', None)
if menuName is not None and menuRegenerator is not None:
cls.menuRegenerators[menuName] = menuRegenerator
# Store inObj only when we need to reregister plugins
@classmethod
def UnregisterMenuEntry(cls, inName):
del cls.menuEntries[inName]
@classmethod
def RegisterNamedPlugIn(cls, inObj, inName, inParams):
cls.plugIns[inName] = inParams
# Store inObj only when we need to reregister plugins
@classmethod
def UnregisterNamedPlugIn(cls, inName):
del cls.plugIns[inName]
@classmethod
def RegisterResource(cls, inObj, inName, inParams):
cls.resources[inName] = inParams
# Store inObj only when we need to reregister plugins
@classmethod
def UnregisterResource(cls, inName):
del cls.resources[inName]
@classmethod
def ActivateNamedPlugIn(cls, inName, *inParams):
plugIn = cls.plugIns.get(inName, None)
if plugIn is None:
raise Exception(Lang("PlugIn (for activation) named '")+inName+Lang("' does not exist"))
handler = plugIn.get('activatehandler', None)
if handler is None:
raise Exception(Lang("PlugIn (for activation) named '")+inName+Lang("' has no activation handler"))
handler(*inParams)
@classmethod
def CallReadyHandlers(cls):
# Sort plugins in descending priority order with a default of 1000
plugins = list(cls.plugIns.values())
plugins.sort(key=lambda p: p.get('readyhandlerpriority', 1000), reverse=True)
for plugin in plugins:
handler = plugin.get('readyhandler', None)
if handler:
handler()
@classmethod
def GetResource(cls, inName): # Don't use this until all of the PlugIns have had a chance to register
retVal = None
for resource in cls.resources.values():
item = resource.get(inName, None)
if item is not None:
retVal = item
break
return retVal
def GetResourceOrThrow(cls, inName): # Don't use this until all of the PlugIns have had a chance to register
retVal = cls.GetResource(inName)
if retVal is None:
raise Exception(Lang("Resource named '")+inName+Lang("' does not exist"))
return retVal
@classmethod
def BuildRootMenu(cls, inParent):
retVal = RootMenu(inParent)
for name, entries in cls.menuEntries.items():
for entry in entries:
# Create the menu that this item is in
retVal.CreateMenuIfNotPresent(name)
# Create the menu that this item leads to when you select it
if entry['menuname'] is not None:
retVal.CreateMenuIfNotPresent(entry['menuname'], entry['menutext'], name)
choiceDef = ChoiceDef(entry['menutext'], entry.get('activatehandler', None), entry.get('statushandler', None))
choiceDef.StatusUpdateHandlerSet(entry.get('statusupdatehandler', None))
retVal.AddChoice(name, choiceDef, entry.get('menupriority', None))
for entry in cls.plugIns.values():
menuName = entry.get('menuname', None)
if menuName is not None:
choiceDef = ChoiceDef(entry['menutext'], entry.get('activatehandler', None), entry.get('statushandler', None))
choiceDef.StatusUpdateHandlerSet(entry.get('statusupdatehandler', None))
retVal.AddChoice(menuName, choiceDef, entry.get('menupriority', None))
return retVal
@classmethod
def RegenerateMenu(cls, inName, inMenu):
retVal = inMenu
regenerator = cls.menuRegenerators.get(inName, None)
if regenerator is not None:
retVal = regenerator(inName, inMenu)
return retVal
@classmethod
def Dump(cls):
print("Contents of PlugIn registry:")
pprint(cls.plugIns)
print("\nRegistered menu entries:")
pprint(cls.menuEntries)
print("\nRegistered resources:")
pprint(cls.resources)