Advertisement
Guest User

Untitled

a guest
Jul 10th, 2013
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.60 KB | None | 0 0
  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,2008,2009 Fluendo, S.L.
  6. # Copyright (C) 2010,2011 Flumotion Services, S.A.
  7. # All rights reserved.
  8. #
  9. # This file may be distributed and/or modified under the terms of
  10. # the GNU Lesser General Public License version 2.1 as published by
  11. # the Free Software Foundation.
  12. # This file is distributed without any warranty; without even the implied
  13. # warranty of merchantability or fitness for a particular purpose.
  14. # See "LICENSE.LGPL" in the source distribution for more information.
  15. #
  16. # Headers in this file shall remain intact.
  17.  
  18. """boostrapping functions for flumotion"""
  19.  
  20. import os
  21. import sys
  22.  
  23. from flumotion.common.log import safeprintf
  24.  
  25. __version__ = "$Rev$"
  26. # Keep in sync with configure.ac
  27. #PYGTK_REQ = (2, 10, 0)
  28. KIWI_REQ = (1, 9, 13)
  29. GST_REQ = {'0.10': {'gstreamer': (0, 10, 10),
  30. 'gst-python': (0, 10, 4)}}
  31. USE_GOPTION_PARSER = False
  32. USE_GTK = False
  33. USE_GST = True
  34.  
  35.  
  36. def init_gobject():
  37. """
  38. Initialize pygobject. A missing or too-old pygobject will cause a
  39. SystemExit exception to be raised.
  40. """
  41. try:
  42. #import pygtk
  43. #pygtk.require('2.0')
  44.  
  45. from gi.repository import GObject
  46. except ImportError:
  47. raise SystemExit('ERROR: PyGTK could not be found')
  48.  
  49. #if GObject.pygtk_version < PYGTK_REQ:
  50. # raise SystemExit('ERROR: PyGTK %s or higher is required'
  51. # % '.'.join(map(str, PYGTK_REQ)))
  52.  
  53. GObject.threads_init()
  54.  
  55.  
  56. def _init_gst_version(gst_majorminor):
  57.  
  58. def tup2version(tup):
  59. return '.'.join(map(str, tup))
  60.  
  61. if gst_majorminor not in GST_REQ:
  62. raise SystemExit('ERROR: Invalid FLU_GST_VERSION: %r (expected '
  63. 'one of %r)' % (gst_majorminor, GST_REQ.keys()))
  64.  
  65. pygst_req = GST_REQ[gst_majorminor]['gst-python']
  66. gst_req = GST_REQ[gst_majorminor]['gstreamer']
  67.  
  68. try:
  69. import pygst
  70. pygst.require(gst_majorminor)
  71. from gi.repository import Gst
  72. except ImportError:
  73. return False
  74. except AssertionError:
  75. return False
  76.  
  77. try:
  78. gst_version = Gst.get_gst_version()
  79. pygst_version = Gst.get_pygst_version()
  80. except AttributeError:
  81. # get_foo_version() added in 0.10.4, fall back
  82. gst_version = Gst.gst_version
  83. pygst_version = Gst.pygst_version
  84.  
  85. if gst_req[:2] != gst_version[:2]:
  86. raise SystemExit(
  87. 'ERROR: Expected GStreamer %s, but got incompatible %s'
  88. % (gst_majorminor, tup2version(gst_version[:2])))
  89.  
  90. if gst_version < gst_req:
  91. raise SystemExit(
  92. 'ERROR: GStreamer %s too old; install %s or newer'
  93. % (tup2version(gst_version), tup2version(gst_req)))
  94.  
  95. if pygst_version < pygst_req:
  96. raise SystemExit(
  97. 'ERROR: gst-python %s too old; install %s or newer'
  98. % (tup2version(pygst_version), tup2version(pygst_req)))
  99.  
  100. return True
  101.  
  102.  
  103. def init_gst():
  104. """
  105. Initialize pygst. A missing or too-old pygst will cause a
  106. SystemExit exception to be raised.
  107. """
  108. assert 'GObject' in sys.modules, "Run init_gobject() first"
  109.  
  110. gst_majorminor = os.getenv('FLU_GST_VERSION')
  111.  
  112. if gst_majorminor:
  113. if not _init_gst_version(gst_majorminor):
  114. raise SystemExit('ERROR: requested GStreamer version %s '
  115. 'not available' % gst_majorminor)
  116. else:
  117. majorminors = GST_REQ.keys()
  118. majorminors.sort()
  119. while majorminors:
  120. majorminor = majorminors.pop()
  121. if _init_gst_version(majorminor):
  122. gst_majorminor = majorminor
  123. break
  124. if not gst_majorminor:
  125. raise SystemExit('ERROR: no GStreamer available '
  126. '(looking for versions %r)' % (GST_REQ.keys(), ))
  127.  
  128. return gst_majorminor
  129.  
  130.  
  131. def init_kiwi():
  132. from gi.repository import GObject
  133.  
  134. try:
  135. from kiwi.__version__ import version as kiwi_version
  136. except ImportError:
  137. return False
  138.  
  139. if kiwi_version < KIWI_REQ:
  140. raise SystemExit('ERROR: Kiwi %s or higher is required'
  141. % '.'.join(map(str, KIWI_REQ)))
  142. elif GObject.pygobject_version > (2, 26, 0):
  143. # Kiwi is not compatible yet with the changes introduced in
  144. # http://git.gnome.org/browse/pygobject/commit/?id=84d614
  145. # Basically, what we do is to revert the changes in _type_register of
  146. # GObjectMeta at least until kiwi works properly with new pygobject
  147. from GObject._gobject import type_register
  148.  
  149. def _type_register(cls, namespace):
  150. ## don't register the class if already registered
  151. if '__gtype__' in namespace:
  152. return
  153.  
  154. if not ('__gproperties__' in namespace or
  155. '__gsignals__' in namespace or
  156. '__gtype_name__' in namespace):
  157. return
  158.  
  159. # Do not register a new GType for the overrides, as this would sort
  160. # of defeat the purpose of overrides...
  161. if cls.__module__.startswith('gi.overrides.'):
  162. return
  163.  
  164. type_register(cls, namespace.get('__gtype_name__'))
  165.  
  166. GObject.GObjectMeta._type_register = _type_register
  167.  
  168. return True
  169.  
  170.  
  171. def init_option_parser(Gst):
  172. # We should only use the GOption parser if we are already going to
  173. # import gobject, and if we can find a recent enough version of
  174. # pygobject on our system. There were bugs in the GOption parsing
  175. # until pygobject 2.15.0, so just revert to optparse if our
  176. # pygobject is too old.
  177. global USE_GOPTION_PARSER
  178. if not Gst:
  179. USE_GOPTION_PARSER = False
  180. else:
  181. from gi.repository import GObject
  182. if getattr(GObject, 'pygobject_version', ()) >= (2, 15, 0):
  183. USE_GOPTION_PARSER = True
  184. else:
  185. USE_GOPTION_PARSER = False
  186.  
  187.  
  188. def wrap_for_statprof(main, output_file):
  189. try:
  190. import statprof
  191. except ImportError, e:
  192. print "Profiling requested, but statprof not available (%s)" % e
  193. return main
  194.  
  195. def wrapped(*args, **kwargs):
  196. statprof.start()
  197. try:
  198. return main(*args, **kwargs)
  199. finally:
  200. statprof.stop()
  201. statprof.display(OUT=file(output_file, 'wb'))
  202. return wrapped
  203.  
  204.  
  205. def wrap_for_builtin_profiler(main, output_file):
  206. try:
  207. import cProfile as profile
  208. except ImportError:
  209. import profile
  210.  
  211. def wrapped(*args, **kwargs):
  212. prof = profile.Profile()
  213. try:
  214. return prof.runcall(main, *args, **kwargs)
  215. finally:
  216. prof.dump_stats(output_file)
  217. return wrapped
  218.  
  219.  
  220. def wrap_for_profiling(main):
  221.  
  222. def generate_output_file():
  223. import tempfile
  224. return os.path.join(tempfile.gettempdir(),
  225. 'flustat.%s.%s.%d' %
  226. (main.__module__, main.__name__, os.getpid()))
  227.  
  228. if os.getenv('FLU_PROFILE'):
  229. return wrap_for_statprof(main, generate_output_file())
  230. elif os.getenv('FLU_BUILTIN_PROFILE'):
  231. return wrap_for_builtin_profiler(main, generate_output_file())
  232. else:
  233. return main
  234.  
  235.  
  236. def boot(path, gtk=False, Gst=True, installReactor=True):
  237. # python 2.5 and twisted < 2.5 don't work together
  238. pythonMM = sys.version_info[0:2]
  239. from twisted.copyright import version
  240. twistedMM = tuple([int(n) for n in version.split('.')[0:2]])
  241. if pythonMM >= (2, 5) and twistedMM < (2, 5):
  242. raise SystemError(
  243. "Twisted versions older than 2.5.0 do not work with "
  244. "Python 2.5 and newer. "
  245. "Please upgrade Twisted or downgrade Python.")
  246.  
  247. if gtk or Gst:
  248. init_gobject()
  249.  
  250. if gtk:
  251. init_kiwi()
  252.  
  253. if Gst:
  254. from flumotion.configure import configure
  255. configure.gst_version = init_gst()
  256.  
  257. global USE_GTK, USE_GST
  258. USE_GTK=gtk
  259. USE_GST=Gst
  260. init_option_parser(Gst)
  261.  
  262. # installing the reactor could override our packager's import hooks ...
  263. if installReactor:
  264. from twisted.internet import gtk3reactor
  265. try:
  266. gtk3reactor.install(useGtk=gtk)
  267. except RuntimeError, e:
  268. safeprintf(sys.stderr, 'ERROR: %s\n', e)
  269. sys.exit(1)
  270. from twisted.internet import reactor
  271.  
  272. # ... so we install them again here to be safe
  273. from flumotion.common import package
  274. package.getPackager().install()
  275.  
  276. # this monkeypatched var exists to let reconnecting factories know
  277. # when they should warn about a connection being closed, and when
  278. # they shouldn't because the system is shutting down.
  279. #
  280. # there is no race condition here -- the reactor doesn't handle
  281. # signals until it is run().
  282. reactor.killed = False
  283.  
  284. def setkilled(killed):
  285. reactor.killed = killed
  286.  
  287. reactor.addSystemEventTrigger('before', 'startup', setkilled, False)
  288. reactor.addSystemEventTrigger('before', 'shutdown', setkilled, True)
  289.  
  290. from flumotion.twisted import reflect
  291. from flumotion.common import errors
  292. from flumotion.common import setup
  293.  
  294. setup.setup()
  295.  
  296. from flumotion.common import log
  297. log.logTwisted()
  298.  
  299. main = reflect.namedAny(path)
  300.  
  301. wrapped = wrap_for_profiling(main)
  302. wrapped.__name__ = main.__name__
  303.  
  304. try:
  305. sys.exit(wrapped(sys.argv))
  306. except (errors.FatalError, SystemError), e:
  307. safeprintf(sys.stderr, 'ERROR: %s\n', e)
  308. sys.exit(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement