Package flumotion :: Package worker :: Package checks :: Module check
[hide private]

Source Code for Module flumotion.worker.checks.check

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 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   
34 -def handleGStreamerDeviceError(failure, device, mid=None):
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 # fallback GStreamer GstError handling 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
84 -def debugFailure(failure):
85 """ 86 Create debug info from a failure. 87 """ 88 return "Failure %r: %s\n%s" % (failure, failure.getErrorMessage(), 89 failure.getTraceback())
90
91 -def callbackResult(value, result):
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
99 -def errbackResult(failure, result, mid, device):
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
122 -def errbackNotFoundResult(failure, result, mid, device):
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 # let failure fall through otherwise 140 return failure
141
142 -class CheckProcError(Exception):
143 'Utility error for element checker procedures' 144 data = None 145
146 - def __init__(self, data):
147 self.data = data
148
149 -def checkImport(moduleName):
150 log.debug('check', 'checkImport: %s', moduleName) 151 __import__(moduleName)
152
153 -def checkElements(elementNames):
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
167 -def checkDirectory(pathName):
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 # FIXME: I would prefer to have this in flumotion/component/base/check.py
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