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
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
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
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!!!")