Source code for soma.application
# -*- coding: utf-8 -*-
# This software and supporting documentation are distributed by
# Institut Federatif de Recherche 49
# CEA/NeuroSpin, Batiment 145,
# 91191 Gif-sur-Yvette cedex
# France
#
# This software is governed by the CeCILL-B license under
# French law and abiding by the rules of distribution of free software.
# You can use, modify and/or redistribute the software under the
# terms of the CeCILL-B license as circulated by CEA, CNRS
# and INRIA at the following URL "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL-B license and that you accept its terms.
'''
* author: Yann Cointepas
* organization: NeuroSpin
* license: `CeCILL B <http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html>`_
'''
from __future__ import absolute_import
__docformat__ = "restructuredtext en"
import os
import sys
import platform
import traceback
from os.path import dirname
os.environ['ETS_TOOLKIT'] = 'qt4'
try:
from enthought.traits.api import ReadOnly, Directory, ListStr, Instance
except ImportError:
from traits.api import ReadOnly, Directory, ListStr, Instance
from soma.singleton import Singleton
from soma.controller import Controller
#-------------------------------------------------------------------------
[docs]class Application(Singleton, Controller):
'''Any program using soma should create an Application instance to manage
its configuration and to store any kind of value that have to be global to
the program.'''
name = ReadOnly(desc='Name of the application')
version = ReadOnly()
plugin_modules = ListStr(
desc='List of Python module to load after application configuration')
def __singleton_init__(self, name=None, version=None, *args, **kwargs):
'''Replaces __init__ in Singleton.'''
super(Application, self).__singleton_init__(*args, **kwargs)
# Warning : Traits bug
# Using the trait Directory() might instanciate a QApplication (seems to depend on the
# traits release). If it is declared in the class, the QApplication is instanciated at
# module importation which prevent to customize QApplication.
self.add_trait('install_directory', Directory(
desc='Base directory where the application is installed'))
self.add_trait('user_directory', Directory(
desc='Base directory where user specific information can be find'))
self.add_trait('application_directory', Directory(
desc='Base directory where application specifc information can be find'))
self.add_trait('site_directory', Directory(
desc='Base directory where site specifc information can be find'))
self._controller_factories = None
if name is None:
name = os.path.basename(sys.argv[0])
self.name = name
self.version = version
self.loaded_plugin_modules = {}
[docs] def initialize(self):
'''This method must be called once to setup the application.'''
self.install_directory = dirname(dirname(dirname(__file__)))
homedir = os.getenv('HOME')
if not homedir:
homedir = ''
if platform.system() == 'Windows':
homedir = os.getenv('USERPROFILE')
if not homedir:
homedir = os.getenv('HOMEPATH')
if not homedir:
homedir = '\\'
drive = os.getenv('HOMEDRIVE')
if not drive:
drive = os.getenv('SystemDrive')
if not drive:
drive = os.getenv('SystemRoot')
if not drive:
drive = os.getenv('windir')
if drive and len(drive) >= 2:
drive = drive[:2]
else:
drive = ''
homedir = drive + homedir
if homedir and os.path.exists(homedir):
self.user_directory = homedir
# Load early plugin modules
for plugin_module in self.plugin_modules:
module = self.load_plugin_module(plugin_module)
if module is not None:
self.loaded_plugin_modules[plugin_module] = module
init = getattr(
module, 'call_before_application_initialization', None)
if init is not None:
init(self)
appdir = os.path.normpath(
os.path.dirname(os.path.dirname(sys.argv[0])))
if os.path.exists(appdir):
self.application_directory = appdir
sitedir = os.path.join('/etc', self.name)
if os.path.exists(sitedir):
self.site_directory = sitedir
# Load plugin modules
for plugin_module in self.plugin_modules:
module = self.loaded_plugin_modules.get(plugin_module)
if module is None:
module = self.load_plugin_module(plugin_module)
if module is not None:
self.loaded_plugin_modules[plugin_module] = module
init = getattr(
module, 'call_after_application_initialization', None)
if init is not None:
init(self)
[docs] @staticmethod
def load_plugin_module(plugin_module):
'''This method loads a plugin module. It imports the module without raising
an exception if it fails.'''
try:
__import__(plugin_module, level=0)
return sys.modules[plugin_module]
except Exception:
# Python 2.6 hack : print_last may fail here (maybe due to threads management)
# traceback.print_last()
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
traceback.print_exception(
exceptionType, exceptionValue, exceptionTraceback)
return None