Ejemplo n.º 1
0
    def __init__(self):

        super(LibrarySettingsProfile, self).__init__(False)

        ## Configure Traits
        self.TRAITS_CONFIGURATION = EnhancedDictionary()
        self.TRAITS_CONFIGURATION.interface_method_name = 'interface'
        self.TRAITS_CONFIGURATION.use_storage = False
Ejemplo n.º 2
0
class LibraryProfile():
    """
    Profile needed at the level of TVB Simulator Library.
    It needs to respect a minimal pattern, common to all TVB available profiles.
    """

    ## Number used for estimation of TVB used storage space
    MAGIC_NUMBER = 9

    ## Maximum number of vertices accepted on a Surface object.
    ## Used for validation purposes.
    MAX_SURFACE_VERTICES_NUMBER = 300000

    ## Default value of folder where to store logging files.
    TVB_STORAGE = os.path.expanduser(os.path.join("~", "TVB" + os.sep))

    ## Temporary add-on used in DataTypes_Framework.
    ## When DataType_Framework classes will get moved, this should be removed.
    WEB_VISUALIZERS_URL_PREFIX = ""

    ## Way of functioning traits is different when using storage or not.
    ## Storage set to false is valid when using TVB_Simulator_Library stand-alone.
    TRAITS_CONFIGURATION = EnhancedDictionary()
    TRAITS_CONFIGURATION.interface_method_name = 'interface'
    TRAITS_CONFIGURATION.use_storage = False

    ## Name of file where logging configuration is stored.
    LOGGER_CONFIG_FILE_NAME = "library_logger.conf"

    @ClassProperty
    @staticmethod
    def TVB_TEMP_FOLDER():
        """ 
        Represents a temporary folder, where to store things for a while.
        Content of this folder can be deleted at any time.
        """
        tmp_path = os.path.join(LibraryProfile.TVB_STORAGE, "TEMP")
        if not os.path.exists(tmp_path):
            os.makedirs(tmp_path)
        return tmp_path

    @ClassProperty
    @staticmethod
    def TVB_LOG_FOLDER():
        """ Return a folder, where all log files are to be stored. """
        tmp_path = os.path.join(LibraryProfile.TVB_STORAGE, "logs")
        if not os.path.exists(tmp_path):
            os.makedirs(tmp_path)
        return tmp_path

    @classmethod
    def initialize_profile(cls):
        """No initialization needed for this particular profile. But useful in general"""
        pass
Ejemplo n.º 3
0
    def __init__(self, web_enabled=True):

        self.manager = stored.SettingsManager(self.TVB_CONFIG_FILE)

        ## Actual storage of all TVB related files
        self.TVB_STORAGE = self.manager.get_attribute(stored.KEY_STORAGE,
                                                      self.FIRST_RUN_STORAGE,
                                                      unicode)
        self.TVB_LOG_FOLDER = os.path.join(self.TVB_STORAGE, "logs")
        self.TVB_TEMP_FOLDER = os.path.join(self.TVB_STORAGE, "TEMP")
        self.TVB_PATH = self.manager.get_attribute(stored.KEY_TVB_PATH, '')

        self.env = Environment()
        self.cluster = ClusterSettings(self.manager)
        self.web = WebSettings(self.manager, web_enabled)
        self.db = DBSettings(self.manager, self.DEFAULT_STORAGE,
                             self.TVB_STORAGE)
        self.version = VersionSettings(self.manager, self.BIN_FOLDER)

        self.EXTERNALS_FOLDER_PARENT = os.path.dirname(self.BIN_FOLDER)
        if not self.env.is_distribution():
            self.EXTERNALS_FOLDER_PARENT = os.path.dirname(
                self.EXTERNALS_FOLDER_PARENT)

        # The path to the matlab executable (if existent). Otherwise just return an empty string.
        value = self.manager.get_attribute(stored.KEY_MATLAB_EXECUTABLE, '',
                                           str) or ''
        if value == 'None':
            value = ''
        self.MATLAB_EXECUTABLE = value

        # Maximum number of vertices acceptable o be part of a surface at import time.
        self.MAX_SURFACE_VERTICES_NUMBER = self.manager.get_attribute(
            stored.KEY_MAX_NR_SURFACE_VERTEX, 300000, int)
        # Max number of ops that can be scheduled from UI in a PSE. To be correlated with the oarsub limitations
        self.MAX_RANGE_NUMBER = self.manager.get_attribute(
            stored.KEY_MAX_RANGE_NR, 2000, int)
        # Max number of threads in the pool of ops running in parallel. TO be correlated with CPU cores
        self.MAX_THREADS_NUMBER = self.manager.get_attribute(
            stored.KEY_MAX_THREAD_NR, 4, int)
        # The maximum disk space that can be used by one single user, in KB.
        self.MAX_DISK_SPACE = self.manager.get_attribute(
            stored.KEY_MAX_DISK_SPACE_USR, 5 * 1024 * 1024, int)

        ## Configure Traits
        self.TRAITS_CONFIGURATION = EnhancedDictionary()
        self.TRAITS_CONFIGURATION.interface_method_name = 'interface'
        self.TRAITS_CONFIGURATION.use_storage = True
Ejemplo n.º 4
0
class BaseProfile():
    """
    Class handling correct settings to be loaded.
    Contains default values for all settings.
    """
    # I. Attributes that are going to be set at initialization time:
    MPLH5_Server_Thread = None
    #The settings loaded from the configuration file. At first import, if this
    #variable is None, it will try to load the settings from the TVB_CONFIG_FILE
    FILE_SETTINGS = None

    MAGIC_NUMBER = 9


    # II. Attributes with value not changeable from settings page:
    DB_CURRENT_VERSION = 4
    # Overwrite number of connections to the DB. 
    # Otherwise might reach PostgreSQL limit when launching multiple concurrent operations.
    # MAX_DB_CONNECTION default value will be used for WEB  
    # When launched on cluster, the MAX_DB_ASYNC_CONNECTIONS overwrites MAX_DB_CONNECTIONS value 
    MAX_DB_CONNECTIONS = 20
    MAX_DB_ASYNC_CONNECTIONS = 2
    BASE_VERSION = "1.1"
    # Nested transactions are not supported by all databases and not really necessary in TVB so far so
    # we don't support them yet. However when running tests we can use them to out advantage to rollback 
    # any database changes between tests.
    ALLOW_NESTED_TRANSACTIONS = False

    # This is the version of the data stored in H5 and XML files
    # and should be used by next versions to know how to import
    # data in TVB format, in case data structure changes.
    # Value should be updated every time data structure is changed.
    DATA_VERSION = 2
    DATA_VERSION_ATTRIBUTE = "Data_version"


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def DATA_CHECKED_TO_VERSION():
        """The version up until we done the upgrade properly for the file data storage."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_LAST_CHECKED_FILE_VERSION, 1, int)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def FILE_STORAGE_UPGRADE_STATUS():
        """Keeps track if the storage upgrade was successfull or not. This is set to `invalid` in case
        some of the datatypes upgrade failed. It's not used thus far but we might want to have it so 
        we can re-run an improved upgrade script on all datatypes that are invalid."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_FILE_STORAGE_UPDATE_STATUS, 'valid')


    @ClassProperty
    @staticmethod
    def SVN_VERSION():
        """Current SVN version in the package running now."""
        result = '1'
        try:
            import bin

            with open(os.path.join(os.path.dirname(bin.__file__), 'tvb.version'), 'r') as version_file:
                result = version_file.read()
        except Exception:
            pass
        try:
            _proc = Popen(["svnversion", "."], stdout=PIPE)
            result = _proc.communicate()[0]
        except Exception:
            pass
        return BaseProfile.parse_svn_version(result)


    @ClassProperty
    @staticmethod
    def CURRENT_VERSION():
        """ Concatenate BASE_VERSION with svn revision number"""
        if FrameworkSettings.SVN_VERSION == -1:
            return FrameworkSettings.BASE_VERSION
        else:
            return FrameworkSettings.BASE_VERSION + '-' + str(FrameworkSettings.SVN_VERSION)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def CODE_CHECKED_TO_VERSION():
        """The version up until we done the upgrade properly for the file data storage."""
        version_string = FrameworkSettings.get_attribute(FrameworkSettings.KEY_LAST_CHECKED_CODE_VERSION, '-1', str)
        return BaseProfile.parse_svn_version(version_string)


    # Access rights for TVB generated files/folders.
    ACCESS_MODE_TVB_FILES = 0744

    LOCALHOST = "127.0.0.1"
    SYSTEM_USER_NAME = 'TVB system'
    DEFAULT_ADMIN_EMAIL = '*****@*****.**'
    CURRENT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    EXTERNALS_FOLDER_PARENT = os.path.dirname(os.path.dirname(bin.__file__))

    # Specify if the current process is executing an operation (via clusterLauncher)
    OPERATION_EXECUTION_PROCESS = False

    CLUSTER_SCHEDULE_COMMAND = 'oarsub -S "/home/tvbadmin/clusterLauncher %s %s"'
    CLUSTER_STOP_COMMAND = 'oardel %s'

    _CACHED_RUNNING_ON_CLUSTER_NODE = None


    @ClassProperty
    @staticmethod
    def RUNNING_ON_CLUSTER_NODE():
        """
        Returns True if current execution happens on cluster node.
        """
        if FrameworkSettings._CACHED_RUNNING_ON_CLUSTER_NODE is None:
            FrameworkSettings._CACHED_RUNNING_ON_CLUSTER_NODE = FrameworkSettings.CLUSTER_NODE_NAME is not None

        return FrameworkSettings._CACHED_RUNNING_ON_CLUSTER_NODE


    _CACHED_CLUSTER_NODE_NAME = None


    @ClassProperty
    @staticmethod
    def CLUSTER_NODE_NAME():
        """
        Returns the name of the cluster on which TVB code is executed.
        If code is executed on a normal machine (not cluster node) returns None
        """
        # Check if the name wasn't computed before.
        if FrameworkSettings._CACHED_CLUSTER_NODE_NAME is None:
            # Read env variable which contains path the the file containing node name
            env_oar_nodefile = os.getenv('OAR_NODEFILE')
            if env_oar_nodefile is not None and len(env_oar_nodefile) > 0:
                # Read node name from file
                with open(env_oar_nodefile, 'r') as f:
                    node_name = f.read()

                if node_name is not None and len(node_name.strip()) > 0:
                    FrameworkSettings._CACHED_CLUSTER_NODE_NAME = node_name.strip()
                    return FrameworkSettings._CACHED_CLUSTER_NODE_NAME
        else:
            return FrameworkSettings._CACHED_CLUSTER_NODE_NAME

        return None


    TVB_CONFIG_FILE = os.path.expanduser(os.path.join("~", '.tvb.configuration'))
    #the folder containing the XSD files used for validating applications XMLs
    SCHEMA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'core', 'schema')
    # Web Specifications:
    RENDER_HTML = True
    TEMPLATE_ROOT = os.path.join(CURRENT_DIR, 'interfaces', 'web', 'templates', 'genshi')
    WEB_VISUALIZERS_ROOT = "tvb.interfaces.web.templates.genshi.visualizers"
    WEB_VISUALIZERS_URL_PREFIX = "/flow/read_datatype_attribute/"
    # Traits Specific
    TRAITS_CONFIGURATION = EnhancedDictionary()
    TRAITS_CONFIGURATION.interface_method_name = 'interface'
    TRAITS_CONFIGURATION.use_storage = True
    #Logger specific
    LOGGER_CONFIG_FILE_NAME = "logger_config.conf"


    @classmethod
    def initialize_profile(cls):
        """
        This method is called at the time the config.py module is first imported. Any specific
        initializations for the profile should be placed here.
        """
        pass


    # III. Attributes that can be overwritten from config file.
    #     Will have only default values in here.
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def TVB_STORAGE():
        """Root folder for all projects and users."""
        default = os.path.expanduser(os.path.join("~", "TVB" + os.sep))
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_STORAGE, default)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MAX_DISK_SPACE():
        """ The maximum disk space that can be used by one single user, in KB. """
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_MAX_DISK_SPACE_USR, 5 * 1024 * 1024, int)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MATLAB_EXECUTABLE():
        """ The path to the matlab executable (if existend). Otherwise just return an empty string. """
        value = FrameworkSettings.get_attribute(FrameworkSettings.KEY_MATLAB_EXECUTABLE, '', str) or ''
        if value == 'None':
            value = ''
        return value


    @ClassProperty
    @staticmethod
    def TVB_TEMP_FOLDER():
        """ 
        Represents a temporary folder, where to store things for a while.
        Content of this folder can be deleted at any time.
        """
        tmp_path = os.path.join(FrameworkSettings.TVB_STORAGE, "TEMP")
        if not os.path.exists(tmp_path):
            os.makedirs(tmp_path)
        return tmp_path


    @ClassProperty
    @staticmethod
    def TVB_LOG_FOLDER():
        """ 
        Represents a folder, where all log files are stored.
        """
        tmp_path = os.path.join(FrameworkSettings.TVB_STORAGE, "logs")
        if not os.path.exists(tmp_path):
            os.makedirs(tmp_path)
        return tmp_path


    # DB related attributes:
    @ClassProperty
    @staticmethod
    def ACEEPTED_DBS():
        """A dictionary with accepted db's and their default URLS"""
        return {'postgres': FrameworkSettings.POSTGRES_URL,
                'sqlite': ('sqlite:///' + os.path.join(FrameworkSettings.TVB_STORAGE, "tvb-database.db"))}


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def SELECTED_DB():
        """Selected DB should be a key that exists in 
        the ACCEPTED_DBS dictionary"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_SELECTED_DB, 'sqlite')


    @ClassProperty
    @staticmethod
    def DB_URL():
        """Used DB url: IP,PORT. The DB  needs to be created in advance."""
        if FrameworkSettings.SELECTED_DB in FrameworkSettings.ACEEPTED_DBS:
            return FrameworkSettings.ACEEPTED_DBS[FrameworkSettings.SELECTED_DB]
        return 'sqlite:///' + os.path.join(FrameworkSettings.TVB_STORAGE, "tvb-database.db")


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def POSTGRES_URL():
        """Default URL for Postgres DB"""
        default = 'postgresql+psycopg2://postgres:[email protected]:5432/tvb?user=postgres&password=postgres'
        current_url = FrameworkSettings.get_attribute(FrameworkSettings.KEY_DB_URL, default)
        if FrameworkSettings.SELECTED_DB == 'postgres' and current_url.startswith('postgresql'):
            return current_url
        return default


    @ClassProperty
    @staticmethod
    def DB_VERSIONING_REPO():
        """Upgrade/Downgrade repository"""
        return os.path.join(FrameworkSettings.TVB_STORAGE, 'db_repo')


    # IP and Ports
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def SERVER_IP():
        """Web server access IP/name"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_IP, FrameworkSettings.LOCALHOST)


    # The maximum number of threads to allocate in case TVB is ran locally instead
    # of cluster. This represents the maximum number of operations that can be executed
    # in parallel.
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MAX_THREADS_NUMBER():
        """Maximum number of threads in the pool of simulations range."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_MAX_THREAD_NR, 4, int)


    # The maximum number of operations that can be launched with a PSE mechanism.
    # when setting ranges with a bigger number of resulting operations, an exception will be thrown.
    # oarsub on the cluster has a maximum number of entries in the queue also set. 
    # This number should not be bigger than the oar setting, or ops will be lost.
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MAX_RANGE_NUMBER():
        """Maximum number of operations that can be scheduled from UI."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_MAX_RANGE_NR, 2000, int)


    # The maximum number of vertices that are allowed for a surface.
    # System will not allow import of surfaces with more vertices than this value.
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MAX_SURFACE_VERTICES_NUMBER():
        """Maximum number of vertices acceptable o be part of a surface at import time."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_MAX_NR_SURFACE_VERTEX, 300000, int)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def WEB_SERVER_PORT():
        """CherryPy port"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_PORT, 8080, int)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def MPLH5_SERVER_PORT():
        """Post for the Matplotlib HTML5 backend"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_PORT_MPLH5, 9000, int)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def DEPLOY_CLUSTER():
        """
        Only when DEPLOY_CLUSTER, CLUSTER_SCHEDULE_COMMAND is used."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_CLUSTER, False, eval)


    @ClassProperty
    @staticmethod
    def BASE_URL():
        """PUBLIC WEB reference towards the cluster."""
        return 'http://' + FrameworkSettings.SERVER_IP + ':' + str(FrameworkSettings.WEB_SERVER_PORT) + '/'


    @ClassProperty
    @staticmethod
    def URL_TVB_VERSION():
        """URL for reading current available version information."""
        default = "http://www.thevirtualbrain.org/register/version.xml"
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_URL_VERSION, default)


    # ADMINISTRATOR user:
    @ClassProperty
    @staticmethod
    @settings_loaded()
    def ADMINISTRATOR_NAME():
        """Give name for the Admin user, first created."""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_ADMIN_NAME, 'admin')


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def ADMINISTRATOR_PASSWORD():
        """Admin's password used when creating first user"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_ADMIN_PWD, '1a1dc91c907325c69271ddf0c944bc72')
        # MD5 for 'pass'


    @ClassProperty
    @staticmethod
    def ADMINISTRATOR_BLANK_PWD():
        """Unencrypted default password"""
        return 'pass'


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def ADMINISTRATOR_EMAIL():
        """Admin's email used when creating first user"""
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_ADMIN_EMAIL, FrameworkSettings.DEFAULT_ADMIN_EMAIL)


    @ClassProperty
    @staticmethod
    @settings_loaded()
    def TVB_PATH():
        return FrameworkSettings.get_attribute(FrameworkSettings.KEY_TVB_PATH, '')


    # CherryPy settings:
    @ClassProperty
    @staticmethod
    def CHERRYPY_CONFIGURATION():
        """CherryPy startup configuration"""
        return {
            'global': {
                'server.socket_host': '0.0.0.0',
                'server.socket_port': FrameworkSettings.WEB_SERVER_PORT,
                'server.thread_pool': 20,
                'engine.autoreload_on': False,
                'server.max_request_body_size': 1932735283  # 1.8 GB
            },
            '/': {
                'tools.encode.on': True,
                'tools.encode.encoding': 'utf-8',
                'tools.decode.on': True,
                'tools.gzip.on': True,
                'tools.sessions.on': True,
                'tools.sessions.storage_type': 'ram',
                'tools.sessions.timeout': 6000,  # 100 hours
                'tools.sessions.locking': 'explicit',
                'tools.upload.on': True,    # Tool to check upload content size
                'tools.cleanup.on': True    # Tool to clean up files on disk
            },
            '/static': {
                'tools.staticdir.root': FrameworkSettings.CURRENT_DIR,
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.join('interfaces', 'web', 'static')
            },
            '/static_view': {
                'tools.staticdir.root': FrameworkSettings.CURRENT_DIR,
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.join('interfaces', 'web', 'templates', 'genshi', 'visualizers'),
            },
            '/schema': {
                'tools.staticdir.root': FrameworkSettings.CURRENT_DIR,
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.join('core', 'schema'),
            },
        }


    @staticmethod
    def parse_svn_version(version_string):
        try:
            return int(version_string)
        except ValueError:
            if ':' in version_string:
                version_string = version_string.split(':')[1]
                number = ''.join([ch for ch in version_string if ch.isdigit()])
                return int(number)


    @staticmethod
    def read_config_file():
        """
        Get data from the configurations file in the form of a dictionary.
        Return None if file not present.
        """
        if not os.path.exists(FrameworkSettings.TVB_CONFIG_FILE):
            return None
        config_dict = {}
        with open(FrameworkSettings.TVB_CONFIG_FILE, 'r') as cfg_file:
            data = cfg_file.read()
            entries = [line for line in data.split('\n') if not line.startswith('#') and len(line.strip()) > 0]
            for one_entry in entries:
                name, value = one_entry.split('=', 1)
                config_dict[name] = value
            FrameworkSettings.FILE_SETTINGS = config_dict
        return config_dict


    @classmethod
    def add_entries_to_config_file(cls, input_data):
        """
        Set the LAST_CHECKED_FILE_VERSION from the settings file to the current DATA_VERSION.
        
        @param input_data: A dictionary of pairs that need to be added to the config file.
        """
        config_dict = FrameworkSettings.read_config_file()
        if config_dict is None:
            config_dict = {}
        for entry in input_data:
            config_dict[entry] = input_data[entry]
        with open(cls.TVB_CONFIG_FILE, 'w') as file_writer:
            for key in config_dict:
                file_writer.write(key + '=' + str(config_dict[key]) + '\n')


    @classmethod
    def update_config_file(cls, data_dict):
        """
        Update data from configuration file, without restart. Used by
        methods like change password, or change email.
        """
        config_dict = FrameworkSettings.read_config_file()
        if config_dict is None:
            config_dict = data_dict
        else:
            for key in config_dict:
                if key in data_dict:
                    config_dict[key] = data_dict[key]
        with open(cls.TVB_CONFIG_FILE, 'w') as file_writer:
            for key in config_dict:
                file_writer.write(key + '=' + str(config_dict[key]) + '\n')


    @staticmethod
    def get_attribute(attr_name, default=None, dtype=str):
        """
        Get a cfg attribute that could also be found in the settings file.
        """
        try:
            if FrameworkSettings.FILE_SETTINGS and attr_name in FrameworkSettings.FILE_SETTINGS:
                return dtype(FrameworkSettings.FILE_SETTINGS[attr_name])
        except ValueError:
            ## Invalid convert operation.
            return default
        return default


    #File keys
    KEY_ADMIN_NAME = 'ADMINISTRATOR_NAME'
    KEY_ADMIN_PWD = 'ADMINISTRATOR_PASSWORD'
    KEY_ADMIN_EMAIL = 'ADMINISTRATOR_EMAIL'
    KEY_TVB_PATH = 'TVB_PATH'
    KEY_STORAGE = 'TVB_STORAGE'
    KEY_MAX_DISK_SPACE_USR = '******'
    #During the introspection phase, it is checked if either Matlab or
    #octave are installed and available trough the system PATH variable
    #If so, they will be used for some analyzers
    KEY_MATLAB_EXECUTABLE = 'MATLAB_EXECUTABLE'
    KEY_IP = 'SERVER_IP'
    KEY_PORT = 'WEB_SERVER_PORT'
    KEY_PORT_MPLH5 = 'MPLH5_SERVER_PORT'
    KEY_SELECTED_DB = 'SELECTED_DB'
    KEY_DB_URL = 'URL_VALUE'
    KEY_URL_VERSION = 'URL_TVB_VERSION'
    KEY_CLUSTER = 'DEPLOY_CLUSTER'
    KEY_MAX_THREAD_NR = 'MAXIMUM_NR_OF_THREADS'
    KEY_MAX_RANGE_NR = 'MAXIMUM_NR_OF_OPS_IN_RANGE'
    KEY_MAX_NR_SURFACE_VERTEX = 'MAXIMUM_NR_OF_VERTICES_ON_SURFACE'
    KEY_LAST_CHECKED_FILE_VERSION = 'LAST_CHECKED_FILE_VERSION'
    KEY_LAST_CHECKED_CODE_VERSION = 'LAST_CHECKED_CODE_VERSION'
    KEY_FILE_STORAGE_UPDATE_STATUS = 'FILE_STORAGE_UPDATE_STATUS'


    @staticmethod
    def is_development():
        """
        Return True when TVB  is used with Python installed natively.
        """
        tvb_root = os.path.dirname(BaseProfile.CURRENT_DIR)
        return (os.path.exists(os.path.join(tvb_root, 'AUTHORS'))
                and os.path.exists(os.path.join(tvb_root, 'ui_test'))
                and os.path.exists(os.path.join(tvb_root, 'tvb_test')))


    def is_windows(self):
        """
        Return True if current run is not development and is running on Windows.
        """
        return platform.startswith('win') and not self.is_development()


    def is_linux(self):
        """ 
        Return True if current run is not development and is running on Linux.
        """
        return not (platform.startswith('win') or platform == 'darwin' or self.is_development())


    def is_mac(self):
        """
        Return True if current run is not development and is running on Mac OS X
        """
        return platform == 'darwin' and not self.is_development()


    def get_python_path(self):
        """Get Python path, based on running options."""
        if self.is_development():
            return 'python'
        if self.is_windows():
            return os.path.join(os.path.dirname(sys.executable), 'python.exe')
        if self.is_mac():
            return '../MacOS/python'
        if self.is_linux():
            return os.path.join(os.path.dirname(sys.executable), 'python2.7')
        raise Exception("Invalid BUILD type found!!!")