Package flumotion :: Package common :: Module boot
[hide private]

Source Code for Module flumotion.common.boot

  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  import sys 
 24  from flumotion.common.log import safeprintf 
 25   
 26  PYGTK_REQ = (2, 6, 3) 
 27   
 28  GST_REQ = {'0.10': {'gstreamer': (0, 10, 0, 1), 
 29                      'gst-python': (0, 10, 0, 1)}} 
 30   
31 -def init_gobject():
32 """ 33 Initialize pygobject. A missing or too-old pygobject will cause a 34 SystemExit exception to be raised. 35 """ 36 try: 37 import pygtk 38 pygtk.require('2.0') 39 40 import gobject 41 except ImportError: 42 raise SystemExit('ERROR: PyGTK could not be found') 43 44 if gobject.pygtk_version < PYGTK_REQ: 45 raise SystemExit('ERROR: PyGTK %s or higher is required' 46 % '.'.join(map(str, PYGTK_REQ))) 47 48 gobject.threads_init()
49
50 -def _init_gst_version(gst_majorminor):
51 52 def tup2version(tup): 53 return '.'.join(map(str, tup))
54 55 if gst_majorminor not in GST_REQ: 56 raise SystemExit('ERROR: Invalid FLU_GST_VERSION: %r (expected ' 57 'one of %r)' % (gst_majorminor, GST_REQ.keys())) 58 59 pygst_req = GST_REQ[gst_majorminor]['gst-python'] 60 gst_req = GST_REQ[gst_majorminor]['gstreamer'] 61 62 try: 63 import pygst 64 pygst.require(gst_majorminor) 65 import gst 66 except ImportError: 67 return False 68 except AssertionError: 69 return False 70 71 try: 72 gst_version = gst.get_gst_version() 73 pygst_version = gst.get_pygst_version() 74 except AttributeError: 75 # get_foo_version() added in 0.10.4, fall back 76 gst_version = gst.gst_version 77 pygst_version = gst.pygst_version 78 79 if gst_req[:2] != gst_version[:2]: 80 raise SystemExit('ERROR: Expected GStreamer %s, but got incompatible %s' 81 % (gst_majorminor, tup2version(gst_version[:2]))) 82 83 if gst_version < gst_req: 84 raise SystemExit('ERROR: GStreamer %s too old; install %s or newer' 85 % (tup2version(gst_version), tup2version(gst_req))) 86 87 if pygst_version < pygst_req: 88 raise SystemExit('ERROR: gst-python %s too old; install %s or newer' 89 % (tup2version(pygst_version), tup2version(pygst_req))) 90 91 return True 92
93 -def init_gst():
94 """ 95 Initialize pygst. A missing or too-old pygst will cause a 96 SystemExit exception to be raised. 97 """ 98 assert 'gobject' in sys.modules, "Run init_gobject() first" 99 100 gst_majorminor = os.getenv('FLU_GST_VERSION') 101 102 if gst_majorminor: 103 if not _init_gst_version(gst_majorminor): 104 raise SystemExit('ERROR: requested GStreamer version %s ' 105 'not available' % gst_majorminor) 106 else: 107 majorminors = GST_REQ.keys() 108 majorminors.sort() 109 while majorminors: 110 majorminor = majorminors.pop() 111 if _init_gst_version(majorminor): 112 gst_majorminor = majorminor 113 break 114 if not gst_majorminor: 115 raise SystemExit('ERROR: no GStreamer available ' 116 '(looking for versions %r)' % (GST_REQ.keys(),)) 117 118 return gst_majorminor
119 120 USE_GOPTION_PARSER = False
121 -def init_option_parser(gtk, gst):
122 # We should only use the GOption parser if we are already going to 123 # import gobject, and if we can find a recent enough version of 124 # pygobject on our system. There were bugs in the GOption parsing 125 # until pygobject 2.15.0, so just revert to optparse if our 126 # pygobject is too old. 127 global USE_GOPTION_PARSER 128 if not gtk and not gst: 129 USE_GOPTION_PARSER = False 130 else: 131 import gobject 132 if getattr(gobject, 'pygobject_version', ()) >= (2, 15, 0): 133 USE_GOPTION_PARSER = True 134 else: 135 USE_GOPTION_PARSER = False
136 137 USE_GTK = False 138 USE_GST = True
139 -def boot(path, gtk=False, gst=True, installReactor=True):
140 # python 2.5 and twisted < 2.5 don't work together 141 pythonMM = sys.version_info[0:2] 142 from twisted.copyright import version 143 twistedMM = tuple([int(n) for n in version.split('.')[0:2]]) 144 if pythonMM >= (2, 5) and twistedMM < (2, 5): 145 raise SystemError( 146 "Twisted versions older than 2.5.0 do not work with " 147 "Python 2.5 and newer. " 148 "Please upgrade Twisted or downgrade Python.") 149 150 if gtk or gst: 151 init_gobject() 152 153 if gst: 154 from flumotion.configure import configure 155 configure.gst_version = init_gst() 156 157 global USE_GTK, USE_GST 158 USE_GTK=gtk 159 USE_GST=gst 160 init_option_parser(gtk, gst) 161 162 # installing the reactor could override our packager's import hooks ... 163 if installReactor: 164 from twisted.internet import gtk2reactor 165 gtk2reactor.install(useGtk=gtk) 166 from twisted.internet import reactor 167 168 # ... so we install them again here to be safe 169 from flumotion.common import package 170 package.getPackager().install() 171 172 # this monkeypatched var exists to let reconnecting factories know 173 # when they should warn about a connection being closed, and when 174 # they shouldn't because the system is shutting down. 175 # 176 # there is no race condition here -- the reactor doesn't handle 177 # signals until it is run(). 178 reactor.killed = False 179 def setkilled(killed): 180 reactor.killed = killed
181 reactor.addSystemEventTrigger('before', 'startup', setkilled, False) 182 reactor.addSystemEventTrigger('before', 'shutdown', setkilled, True) 183 184 from flumotion.twisted import reflect 185 from flumotion.common import errors 186 from flumotion.common import setup 187 188 setup.setup() 189 190 from flumotion.common import log 191 log.logTwisted() 192 193 # we redefine catching 194 __pychecker__ = 'no-reuseattr' 195 196 if os.getenv('FLU_PROFILE'): 197 def catching(proc, *args, **kwargs): 198 import statprof 199 statprof.start() 200 try: 201 return proc(*args, **kwargs) 202 finally: 203 statprof.stop() 204 statprof.display() 205 elif os.getenv('FLU_ATEXIT'): 206 def catching(proc, *args, **kwargs): 207 env = os.getenv('FLU_ATEXIT').split(' ') 208 fqfn = env.pop(0) 209 log.info('atexit', 'FLU_ATEXIT set, will call %s(*%r) on exit', 210 fqfn, env) 211 atexitproc = reflect.namedAny(fqfn) 212 213 try: 214 return proc(*args, **kwargs) 215 finally: 216 log.info('atexit', 'trying to call %r(*%r)', 217 atexitproc, env) 218 atexitproc(*env) 219 else: 220 def catching(proc, *args, **kwargs): 221 return proc(*args, **kwargs) 222 223 main = reflect.namedAny(path) 224 225 try: 226 sys.exit(catching(main, sys.argv)) 227 except (errors.SystemError, SystemError), e: 228 safeprintf(sys.stderr, 'ERROR: %s\n', e) 229 sys.exit(1) 230