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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
# Copyright 2004-2007 Nanorex, Inc. See LICENSE file for details.
"""
Plugins.py - a collection of general plugin helper functions for the purpose of
checking and/or verifying that a plugin is enabled and that the path pointed
to by its pref_key is the plugin.
@version: $Id$
@copyright: 2004-2007 Nanorex, Inc. See LICENSE file for details.
History:
mark 2007-12-01
- split out of qutemol.py
Module classification: [bruce 071215, 080104]
Contains ui, operations or utility, and io code.
For now, classified as code type of ui, somewhat arbitrarily,
but filed into "processes" package, since it's all about letting
the user maintain info needed to run external processes.
"""
import foundation.env as env
import os
from PyQt4.Qt import QMessageBox
from processes.Process import Process
def _dialogToOfferPluginPrefsFixup(caption, text):
"""
[private helper for _fixPluginProblem()]
Offer the user a chance to fix a plugin problem.
@param caption: The dialog border caption.
@type caption: text
@param text: The dialog text.
@type text: text
@return: 0 if they accept (after letting them try),
1 if they decline.
@rtype: int
"""
win = env.mainwindow()
ret = QMessageBox.warning(win, caption, text,
"&OK", "Cancel", "",
0, 1 )
if ret == 0: # User clicked "OK"
win.userPrefs.show(pagename = 'Plug-ins') # Show Preferences | Plug-in.
return 0 # let caller figure out whether user fixed the problem
elif ret == 1: # User clicked "Cancel"
return 1
pass
def _fixPluginProblem(plugin_name, errortext):
"""
[private helper for checkPluginPreferences()]
@param plugin_name: name of plug-in (i.e. "QuteMolX", "GROMACS", etc.)
@type plugin_name: text
"""
caption = "%s Problem" % plugin_name
text = "Error: %s.\n" % (errortext,) + \
" Select OK to fix this now in the Plugins page of\n" \
"the Preferences dialog and retry rendering, or Cancel."
return _dialogToOfferPluginPrefsFixup(caption, text)
def verifyExecutable(executable_path):
if (os.access(executable_path, os.F_OK)):
if (os.access(executable_path, os.X_OK)):
return None
return "%s exists, but is not executable" % executable_path
return "%s: file does not exist" % executable_path
def _checkPluginPreferences_0(plugin_name,
plugin_prefs_keys,
insure_executable):
"""
[private helper for checkPluginPreferences()]
Checks <plugin_name> to make sure it is enabled and
that its path points to a file.
@param plugin_name: name of plug-in (i.e. "QuteMolX", "GROMACS", etc.)
@type plugin_name: text
@param plugin_keys: list containing the plugin enable prefs key and the
path prefs key.
@type plugin_keys: List
@return: 0, plugin path on success, or
1, an error message indicating the problem.
@rtype: List
"""
plugin_enabled_prefs_key, plugin_path_prefs_key = plugin_prefs_keys
if env.prefs[plugin_enabled_prefs_key]:
plugin_path = env.prefs[plugin_path_prefs_key]
else:
return 1, "%s is not enabled" % plugin_name
if not plugin_path:
return 1, "%s plug-in executable path is empty" % plugin_name
# We'd like to allow arguments to an executable to be specified,
# but perhaps the executable path itself contains a space in it.
# So, we break the string at each space and check the first part.
# If any of those substrings exists, accept it. We start by
# checking the whole string.
executable_path = plugin_path
while (not os.path.exists(executable_path)):
last_space = executable_path.rfind(" ")
# some platform might report that the empty string file name
# exists, so we don't want to check for it.
if (last_space <= 0):
return 1, "%s executable not found at specified path %s" % (plugin_name, plugin_path)
executable_path = executable_path[0:last_space]
if (insure_executable):
message = verifyExecutable(executable_path)
if (message):
return 1, message
##e should check version of plugin, if we know how
return 0, plugin_path
def checkPluginPreferences(plugin_name,
plugin_prefs_keys,
ask_for_help = True,
extra_check = None,
insure_executable = False):
"""
Checks I{plugin_name} to make sure it is enabled and that its path points
to a file. I{ask_for_help} can be set to B{False} if the user shouldn't be
given a chance to fix the problem via the "Plugin" page in the Preferences
dialog.
Note: this should be refactored to use exceptions.
Returns :0, plugin path on success, or
1 and an error message indicating the problem.
@param plugin_name: name of plug-in (i.e. "QuteMolX", "GROMACS", etc.)
@type plugin_name: text
@param plugin_keys: list containing the plugin enable prefs key and the
path prefs key.
@type plugin_keys: List
@param ask_for_help: If True (default), give the user a chance to fix
problems via the "Plugin" page of the Preferences
dialog (i.e. enable the plugin and set the path to
its executable).
@type ask_for_help: bool
@param extra_check: If not None (default is None), is a routine to
perform extra validation checks on the plugin
path.
@type extra_check: Function which takes path as argument, and
returns either an error message, or None if all
is ok.
@return: 0, plugin path on success, or
1, an error message indicating the problem.
@rtype: List
"""
# Make sure the other prefs settings are correct; if not, maybe repeat
# until user fixes them or gives up.
while 1:
errorcode, errortext_or_path = \
_checkPluginPreferences_0(plugin_name,
plugin_prefs_keys,
insure_executable)
if (extra_check and not errorcode):
extra_message = extra_check(errortext_or_path)
if (extra_message):
errorcode = 1
errortext_or_path = extra_message
if errorcode:
if not ask_for_help:
return errorcode, errortext_or_path
ret = _fixPluginProblem(plugin_name, errortext_or_path)
if ret == 0: # Subroutine has shown Preferences | Plug-in.
continue # repeat the checks, to figure out whether user fixed
# the problem.
elif ret == 1: # User declined to try to fix it now
return errorcode, errortext_or_path
else:
return 0, errortext_or_path
pass # end of checkPluginPreferences
def verifyPluginUsingVersionFlag(plugin_path, version_flag, vstring):
"""
Verifies a plugin by running it with I{version_flag} as the only
command line argument and matching the output to I{vstring}.
@return: 0 if there is a match. Otherwise, returns 1
@rtype: int
@note: This is only useful if the plug-in supports a version flag arguments.
"""
if not plugin_path:
return 1
if not os.path.exists(plugin_path):
return 1
args = [version_flag]
arguments = []
for arg in args:
if arg != "":
arguments.append(arg)
p = Process()
p.start(plugin_path, arguments)
if not p.waitForFinished (10000): # Wait for 10000 milliseconds = 10 seconds
return 1
output = 'Not vstring'
output = str(p.readAllStandardOutput())
#print "output=", output
#print "vstring=", vstring
if output.find(vstring) == -1:
return 1
else:
return 0 # Match found.
|