1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import os
23
24 import gst
25 from twisted.internet import defer
26
27 from flumotion.common import documentation, errors, gstreamer, log, messages
28 from flumotion.common.i18n import N_, gettexter
29
30 __version__ = "$Rev$"
31 T_ = gettexter()
32
33
35 """
36 Handle common GStreamer GstErrors or other.
37 Return a message or None.
38 """
39 if not mid:
40 log.warning('check',
41 'handleGStreamerDeviceError: no message id specified')
42
43 m = None
44
45 if failure.check(errors.GStreamerGstError):
46 source, gerror, debug = failure.value.args
47 log.debug('check',
48 'GStreamer GError: %s (domain %s, code %d, debug %s)' % (
49 gerror.message, gerror.domain, gerror.code, debug))
50
51 if gerror.domain == "gst-resource-error-quark":
52 if gerror.code == int(gst.RESOURCE_ERROR_OPEN_READ):
53 m = messages.Error(T_(
54 N_("Could not open device '%s' for reading. "
55 "Check permissions on the device."), device), mid=mid)
56 documentation.messageAddFixBadPermissions(m)
57 if gerror.code == int(gst.RESOURCE_ERROR_OPEN_WRITE):
58 m = messages.Error(T_(
59 N_("Could not open device '%s' for writing. "
60 "Check permissions on the device."), device), mid=mid)
61 documentation.messageAddFixBadPermissions(m)
62 elif gerror.code == int(gst.RESOURCE_ERROR_OPEN_READ_WRITE):
63 m = messages.Error(T_(
64 N_("Could not open device '%s'. "
65 "Check permissions on the device."), device), mid=mid)
66 documentation.messageAddFixBadPermissions(m)
67 elif gerror.code == int(gst.RESOURCE_ERROR_BUSY):
68 m = messages.Error(T_(
69 N_("Device '%s' is already in use."), device), mid=mid)
70 elif gerror.code == int(gst.RESOURCE_ERROR_SETTINGS):
71 m = messages.Error(T_(
72 N_("Device '%s' did not accept the requested settings."),
73 device),
74 debug="%s\n%s" % (gerror.message, debug), mid=mid)
75
76
77 if not m:
78 m = messages.Error(T_(N_("Internal unhandled GStreamer error.")),
79 debug="%s\n%s: %d\n%s" % (
80 gerror.message, gerror.domain, gerror.code, debug),
81 mid=mid)
82 elif failure.check(errors.GStreamerError):
83 m = messages.Error(T_(N_("Internal GStreamer error.")),
84 debug=debugFailure(failure), mid=mid)
85 log.debug('check', 'handleGStreamerError: returning %r' % m)
86 return m
87
88
90 """
91 Create debug info from a failure.
92 """
93 return "Failure %r: %s\n%s" % (failure, failure.getErrorMessage(),
94 failure.getTraceback())
95
96
98 """
99 I am a callback to add to a do_element_check deferred.
100 """
101 log.debug('check', 'returning succeeded Result, value %r' % (value, ))
102 result.succeed(value)
103 return result
104
105
107 """
108 I am an errback to add to a do_element_check deferred, after your
109 specific one.
110
111 I handle several generic cases, including some generic GStreamer errors.
112
113 @param mid: the id to set on the message
114 """
115 m = None
116 if failure.check(errors.GStreamerGstError):
117 m = handleGStreamerDeviceError(failure, device, mid=mid)
118
119 if not m:
120 log.debug('check', 'unhandled failure: %r (%s)\nTraceback:\n%s' % (
121 failure, failure.getErrorMessage(), failure.getTraceback()))
122 m = messages.Error(T_(N_("Could not probe device '%s'."), device),
123 debug=debugFailure(failure))
124
125 m.id = mid
126 result.add(m)
127 return result
128
129
131 """
132 I am an errback to add to a do_element_check deferred
133 to check for RESOURCE_ERROR_NOT_FOUND, and add a message to the result.
134
135 @param mid: the id to set on the message
136 """
137 failure.trap(errors.GStreamerGstError)
138 source, gerror, debug = failure.value.args
139
140 if gerror.domain == "gst-resource-error-quark" and \
141 gerror.code == int(gst.RESOURCE_ERROR_NOT_FOUND):
142 m = messages.Warning(T_(
143 N_("No device found on %s."), device), mid=mid)
144 result.add(m)
145 return result
146
147
148 return failure
149
150
152 'Utility error for element checker procedures'
153 data = None
154
157
158
163
164
166 log.debug('check', 'checkElements: element names to check %r',
167 elementNames)
168 ret = []
169 for name in elementNames:
170 try:
171 gst.element_factory_make(name)
172 ret.append(name)
173 except gst.PluginNotFoundError:
174 log.debug('check', 'no plugin found for element factory %s', name)
175 pass
176 log.debug('check', 'checkElements: returning elements names %r', ret)
177 return ret
178
179
181 """
182 Check if a path is a directory and that it is readable and
183 executable
184 @param pathName: path to check
185 @type pathName: string
186 @returns: if the path is a directory and readable
187 @rtype: L{messages.Result}
188 """
189
190 result = messages.Result()
191 succeeded = False
192 if (os.path.isdir(pathName) and
193 os.access(pathName, os.R_OK|os.X_OK)):
194 succeeded = True
195
196 result.succeed(succeeded)
197 return result
198
199
201 """
202 Checks if a path is a file.
203
204 @param filePath : The path of the file
205 @type filePath : str
206
207 @returns : True if filePath exists and is a file, False otherwise.
208 @rtype : L{messages.Result}
209 """
210 log.debug('check', 'checkFile: %s', filePath)
211 result = messages.Result()
212 result.succeed(os.path.isfile(filePath))
213 return result
214
215
259
260 from gst.extend import discoverer
261 dcv = discoverer.Discoverer(filePath)
262 dcv.connect('discovered', discovered)
263 dcv.discover()
264 return d
265
266
267 -def checkPlugin(pluginName, packageName, minimumVersion=None,
268 featureName=None, featureCheck=None):
269 """
270 Check if the given plug-in is available.
271 Return a result with an error if it is not, or not new enough.
272
273 @param pluginName: name of the plugin to check
274 @param packageName: name of the package to tell the user to install
275 if the check fails
276 @param minimumVersion: minimum version of the plugin, as a tuple.
277 Optional.
278 @param featureName: name of a specific feature to check for in the
279 plugin. Optional. Overrides the minimum version check, if given.
280 @param featureCheck: function to call on the found feature, which
281 should return a boolean representing whether the feature is good or
282 not. Optional, and only makes sense if you specify featureName.
283 @rtype: L{messages.Result}
284 """
285 result = messages.Result()
286 version = gstreamer.get_plugin_version(pluginName)
287
288 if not version:
289 m = messages.Error(T_(
290 N_("This host is missing the '%s' GStreamer plug-in.\n"),
291 pluginName))
292 m.add(T_(N_(
293 "Please install '%s'.\n"), packageName))
294 documentation.messageAddGStreamerInstall(m)
295 result.add(m)
296 elif featureName:
297 r = gst.registry_get_default()
298 features = r.get_feature_list_by_plugin(pluginName)
299 byname = dict([(f.get_name(), f) for f in features])
300 if (featureName not in byname
301 or (featureCheck and not featureCheck(byname[featureName]))):
302 m = messages.Error(T_(
303 N_("Your '%s' GStreamer plug-in is too old.\n"), pluginName),
304 mid = 'plugin-%s-check' % pluginName)
305 m.add(T_(N_(
306 "Please upgrade '%s' to version %s or higher."),
307 packageName, ".".join([str(x) for x in minimumVersion])))
308 documentation.messageAddGStreamerInstall(m)
309 result.add(m)
310 elif version < minimumVersion:
311 m = messages.Error(T_(
312 N_("Version %s of the '%s' GStreamer plug-in is too old.\n"),
313 ".".join([str(x) for x in version]), pluginName),
314 mid = 'plugin-%s-check' % pluginName)
315 m.add(T_(N_(
316 "Please upgrade '%s' to version %s."), packageName,
317 ".".join([str(x) for x in minimumVersion])))
318 documentation.messageAddGStreamerInstall(m)
319 result.add(m)
320
321 result.succeed(None)
322 return defer.succeed(result)
323
324
325
326
327 -def do_check(obj, callable, *args, **kwargs):
328 """
329 This method can be used in component do_check vmethods.
330 It will add messages from the result to the UI state.
331
332 @param obj: an object having a addMessage method
333 @param callable: a callable which returns a deferred method
334 returning a Result.
335
336 @rtype: L{twisted.internet.defer.Deferred}
337 """
338
339 def checkCallback(result):
340 for m in result.messages:
341 obj.addMessage(m)
342
343 d = callable(*args, **kwargs)
344 d.addCallback(checkCallback)
345 return d
346