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