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 errors, log, messages, gstreamer
28 from flumotion.common.i18n import N_, gettexter
29
30 __version__ = "$Rev: 7094 $"
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 if gerror.code == int(gst.RESOURCE_ERROR_OPEN_WRITE):
57 m = messages.Error(T_(
58 N_("Could not open device '%s' for writing. "
59 "Check permissions on the device."), device), mid=mid)
60 elif gerror.code == int(gst.RESOURCE_ERROR_OPEN_READ_WRITE):
61 m = messages.Error(T_(
62 N_("Could not open device '%s'. "
63 "Check permissions on the device."), device), mid=mid)
64 elif gerror.code == int(gst.RESOURCE_ERROR_BUSY):
65 m = messages.Error(T_(
66 N_("Device '%s' is already in use."), device), mid=mid)
67 elif gerror.code == int(gst.RESOURCE_ERROR_SETTINGS):
68 m = messages.Error(T_(
69 N_("Device '%s' did not accept the requested settings."),
70 device),
71 debug="%s\n%s" % (gerror.message, debug), mid=mid)
72
73
74 if not m:
75 m = messages.Error(T_(N_("Internal unhandled GStreamer error.")),
76 debug="%s\n%s: %d\n%s" % (
77 gerror.message, gerror.domain, gerror.code, debug), 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
85 """
86 Create debug info from a failure.
87 """
88 return "Failure %r: %s\n%s" % (failure, failure.getErrorMessage(),
89 failure.getTraceback())
90
92 """
93 I am a callback to add to a do_element_check deferred.
94 """
95 log.debug('check', 'returning succeeded Result, value %r' % (value,))
96 result.succeed(value)
97 return result
98
100 """
101 I am an errback to add to a do_element_check deferred, after your
102 specific one.
103
104 I handle several generic cases, including some generic GStreamer errors.
105
106 @param mid: the id to set on the message
107 """
108 m = None
109 if failure.check(errors.GStreamerGstError):
110 m = handleGStreamerDeviceError(failure, device, mid=mid)
111
112 if not m:
113 log.debug('check', 'unhandled failure: %r (%s)\nTraceback:\n%s' % (
114 failure, failure.getErrorMessage(), failure.getTraceback()))
115 m = messages.Error(T_(N_("Could not probe device '%s'."), device),
116 debug=debugFailure(failure))
117
118 m.id = mid
119 result.add(m)
120 return result
121
123 """
124 I am an errback to add to a do_element_check deferred
125 to check for RESOURCE_ERROR_NOT_FOUND, and add a message to the result.
126
127 @param mid: the id to set on the message
128 """
129 failure.trap(errors.GStreamerGstError)
130 source, gerror, debug = failure.value.args
131
132 if gerror.domain == "gst-resource-error-quark" and \
133 gerror.code == int(gst.RESOURCE_ERROR_NOT_FOUND):
134 m = messages.Warning(T_(
135 N_("No device found on %s."), device), mid=mid)
136 result.add(m)
137 return result
138
139
140 return failure
141
143 'Utility error for element checker procedures'
144 data = None
145
148
152
154 log.debug('check', 'checkElements: element names to check %r',
155 elementNames)
156 ret = []
157 for name in elementNames:
158 try:
159 gst.element_factory_make(name)
160 ret.append(name)
161 except gst.PluginNotFoundError:
162 log.debug('check', 'no plugin found for element factory %s', name)
163 pass
164 log.debug('check', 'checkElements: returning elements names %r', ret)
165 return ret
166
168 """
169 Check if a path is a directory and that it is readable and
170 executable
171 @param pathName: path to check
172 @type pathName: string
173 @returns: if the path is a directory and readable
174 @rtype: L{messages.Result}
175 """
176
177 result = messages.Result()
178 succeeded = False
179 if (os.path.isdir(pathName) and
180 os.access(pathName, os.R_OK|os.X_OK)):
181 succeeded = True
182
183 result.succeed(succeeded)
184 return result
185
186 -def checkPlugin(pluginName, packageName, minimumVersion=None,
187 featureName=None, featureCheck=None):
188 """
189 Check if the given plug-in is available.
190 Return a result with an error if it is not, or not new enough.
191
192 @param pluginName: name of the plugin to check
193 @param packageName: name of the package to tell the user to install
194 if the check fails
195 @param minimumVersion: minimum version of the plugin, as a tuple.
196 Optional.
197 @param featureName: name of a specific feature to check for in the
198 plugin. Optional. Overrides the minimum version check, if given.
199 @param featureCheck: function to call on the found feature, which
200 should return a boolean representing whether the feature is good or
201 not. Optional, and only makes sense if you specify featureName.
202 @rtype: L{messages.Result}
203 """
204 result = messages.Result()
205 version = gstreamer.get_plugin_version(pluginName)
206
207 if not version:
208 m = messages.Error(T_(
209 N_("This host is missing the '%s' GStreamer plug-in.\n"),
210 pluginName))
211 m.add(T_(N_(
212 "Please install '%s'.\n"), packageName))
213 result.add(m)
214 elif featureName:
215 r = gst.registry_get_default()
216 features = r.get_feature_list_by_plugin(pluginName)
217 byname = dict([(f.get_name(), f) for f in features])
218 if (featureName not in byname
219 or (featureCheck and not featureCheck(byname[featureName]))):
220 m = messages.Error(T_(
221 N_("Your '%s' GStreamer plug-in is too old.\n"), pluginName),
222 id = 'plugin-%s-check' % pluginName)
223 m.add(T_(N_(
224 "Please upgrade '%s' to version %s or higher."),
225 packageName, ".".join([str(x) for x in minimumVersion])))
226 result.add(m)
227 elif version < minimumVersion:
228 m = messages.Error(T_(
229 N_("Version %s of the '%s' GStreamer plug-in is too old.\n"),
230 ".".join([str(x) for x in version]), pluginName),
231 id = 'plugin-%s-check' % pluginName)
232 m.add(T_(N_(
233 "Please upgrade '%s' to version %s."), packageName,
234 ".".join([str(x) for x in minimumVersion])))
235 result.add(m)
236
237 result.succeed(None)
238 return defer.succeed(result)
239
240
241 -def do_check(obj, callable, *args, **kwargs):
242 """
243 This method can be used in component do_check vmethods.
244 It will add messages from the result to the UI state.
245
246 @param obj: an object having a addMessage method
247 @param callable: a callable which returns a deferred method
248 returning a Result.
249
250 @rtype: L{twisted.internet.defer.Deferred}
251 """
252 def checkCallback(result):
253 for m in result.messages:
254 obj.addMessage(m)
255
256 d = callable(*args, **kwargs)
257 d.addCallback(checkCallback)
258 return d
259