Source code for laf.settings

import os, collections
import configparser
from .timestamp import Timestamp

NAME = 'LAF-Fabric'
VERSION = '4.8.3'
APIREF = 'http://laf-fabric.readthedocs.org/en/latest/texts/API-reference.html'
FEATDOC = 'https://shebanq.ancient-data.org/static/docs/featuredoc/texts/welcome.html'
MAIN_CFG = 'laf-fabric.cfg'
DEFAULT_DATA_DIR = 'laf-fabric-data'

[docs]class Settings(object): '''Manage the configuration. The directory structure is built as a set of names in an environment dictionary. The method ``setenv`` builds a new structure based on user choices. Local settings can be passed as arguments to object creation, or in a config file in the current directory, or in a config file in the user's home directory. It is possible to save these settings in the latter config file. ''' _myconfig = { 'data_dir': None, # data directory (possibly containing compiled laf) 'output_dir': None, # output directory (containing task results) 'm_source_dir': None, # directory containing original, uncompiled laf resource 'm_source_subdir': 'laf', # subdirectory of main laf resource 'a_source_subdir': 'annotations', # subdirectory of annotation add-ons 'bin_subdir': 'bin', # subdirectory of compiled data 'bin_ext': 'bin', # file extension for binary files 'text_ext': 'txt', # file extension for text files 'log_name': '__log__', # base name for log files 'compile_name': 'compile__', # extension name for log files of compile process 'primary_data': 'primary_data', # name of the primary data file in the compiled data 'empty': '--', # name of empty annox 'header': '_header_.xml', # name of laf header file in annox } _env_def = { 'source': '{source}', 'task': '{task}', 'zspace': '{zspace}', 'empty': '{empty}', 'data_dir': '{data_dir}', 'output_dir': '{output_dir}', 'source_data': '{data_dir}/{source}/mql/{source}', 'source_xdata': '{data_dir}/{source}/mql/x_{source}', 'bin_dir': '{data_dir}/{source}/{bin_subdir}', 'm_source_dir': '{m_source_dir}/{source}/{m_source_subdir}', 'm_source_path': '{m_source_dir}/{source}/{m_source_subdir}/{source}.txt.hdr', 'm_compiled_dir': '{data_dir}/{source}/{bin_subdir}', 'm_compiled_path': '{data_dir}/{source}/{bin_subdir}/{log_name}{compile_name}.{text_ext}', 'primary_compiled_path': '{data_dir}/{source}/{bin_subdir}/{primary_data}', 'z_compiled_dir': '{data_dir}/{source}/{bin_subdir}/Z/{zspace}', 'task_dir': '{output_dir}/{source}/{task}', 'log_path': '{output_dir}/{source}/{task}/{log_name}{task}.{text_ext}', } # here are config settings per annox _env_def_a = { 'a_source_dir': '{m_source_dir}/{source}/{a_source_subdir}/{annox}', 'a_source_path': '{m_source_dir}/{source}/{a_source_subdir}/{annox}/{header}', 'a_compiled_dir': '{data_dir}/{source}/{bin_subdir}/A/{annox}', 'a_compiled_path': '{data_dir}/{source}/{bin_subdir}/A/{annox}/{log_name}{compile_name}.{text_ext}', } def __init__(self, data_dir, laf_dir, output_dir, save, verbose): stamp = Timestamp(verbose=verbose) self.stamp = stamp stamp.Nmsg('This is {} {}\nAPI reference: {}\nFeature doc: {}\n'.format(NAME, VERSION, APIREF, FEATDOC)) strings = configparser.ConfigParser(inline_comment_prefixes=('#')) cw_dir = os.getcwd().replace('\\', '/') home_dir = os.path.expanduser('~').replace('\\', '/') global_config_dir = "{}/{}".format(home_dir, DEFAULT_DATA_DIR) global_config_path = "{}/{}".format(global_config_dir, MAIN_CFG) local_config_path = MAIN_CFG default_data_dir = global_config_dir default_laf_dir = global_config_dir config_data_dir = None config_laf_dir = None config_output_dir = None the_config_path = None for config_path in (local_config_path, global_config_path): if os.path.exists(config_path): the_config_path = config_path break if the_config_path != None: with open(the_config_path, "r", encoding="utf-8") as f: strings.read_file(f) if 'locations' in strings: if 'data_dir' in strings['locations']: config_data_dir = strings['locations']['data_dir'] if 'laf_dir' in strings['locations']: config_laf_dir = strings['locations']['laf_dir'] if 'output_dir' in strings['locations']: config_output_dir = strings['locations']['output_dir'] else: stamp.Wmsg('No config file found in locations {} and {}'.format(local_config_path, global_config_path)) the_data_dir = data_dir or config_data_dir or default_data_dir if the_data_dir == None: stamp.Emsg('No valid data dir. data_dir={}; config_data_dir={}; default_data_dir={}'.format(data_dir, config_data_dir, default_data_dir)) return False the_laf_dir = laf_dir or config_laf_dir or the_data_dir if the_laf_dir == None: stamp.Emsg('No valid laf dir. laf_dir={}; config_laf_dir={}'.format(laf_dir, config_laf_dir)) return False the_output_dir = output_dir or config_output_dir if the_output_dir == None: stamp.Emsg('No valid output dir. output_dir={}; config_output_dir={}'.format(output_dir, config_output_dir)) return False the_data_dir = \ the_data_dir.replace('.', cw_dir, 1) if the_data_dir.startswith('.') else the_data_dir.replace('~', home_dir, 1) if the_data_dir.startswith('~') else the_data_dir stamp.Dmsg('Data dir = {}'.format(the_data_dir)) the_laf_dir = \ the_laf_dir.replace('.', cw_dir, 1) if the_laf_dir.startswith('.') else the_laf_dir.replace('~', home_dir, 1) if the_laf_dir.startswith('~') else the_laf_dir stamp.Dmsg('Laf dir = {}'.format(the_laf_dir)) the_output_dir = \ the_output_dir.replace('.', cw_dir, 1) if the_output_dir.startswith('.') else the_output_dir.replace('~', home_dir, 1) if the_output_dir.startswith('~') else the_output_dir stamp.Dmsg('Output dir = {}'.format(the_output_dir)) if not os.path.exists(the_data_dir): stamp.Imsg("CREATING new DATA_DIR {}".format(the_data_dir)) try: if not os.path.exists(the_data_dir): os.makedirs(the_data_dir) except os.error as e: stamp.Emsg('could not create data directory {}'.format(the_data_dir)) return False if not os.path.exists(the_output_dir): stamp.Imsg("CREATING new OUTPUT_DIR {}".format(the_output_dir)) try: if not os.path.exists(the_output_dir): os.makedirs(the_output_dir) except os.error as e: stamp.Emsg('could not create output directory {}'.format(the_output_dir)) return False self._myconfig.update({'data_dir': the_data_dir, 'm_source_dir': the_laf_dir, 'output_dir': the_output_dir}) if save: strings['locations'] = {'data_dir': the_data_dir, 'laf_dir': the_laf_dir, 'output_dir': the_output_dir} if not os.path.exists(global_config_path): stamp.Imsg("CREATING new GLOBAL CONFIG FILE {}".format(global_config_path)) try: if not os.path.exists(global_config_dir): os.makedirs(global_config_dir) except os.error as e: stamp.Emsg('could not create global config directory {}'.format(global_config_dir)) return False with open(global_config_path, "w", encoding="utf-8") as f: strings.write(f) self.env = {} self.zspace = '' return True
[docs] def setenv(self, source=None, annox=None, task=None, zspace=None): '''all relevant config settings will be stored in self.env Most settings are just key - string value pairs. But the setting 'annox' will be a dict, keyed by the annox names passed through the annox param, and valued by dicts with annox-specific paths. The annox parameter may be None, [], '--' (meaning no annox), a list of annoxes, or a string with a comma-separated series of annoxes. ''' if source == None: source = self.env.get('source') if task == None: task = self.env.get('task') if zspace == None: zspace = self.env.get('zspace') for e in self._env_def: self.env[e] = self._env_def[e].format(source=source, task=task, zspace=zspace, **self._myconfig) if annox == None: annox = self.env.get('annox') if annox == None or annox == '' or annox == self._myconfig['empty']: annox = [] elif type(annox) is str: annox = annox.split(',') self.env['annox'] = collections.OrderedDict() for anx in annox: self.env['annox'][anx] = {} for e in self._env_def_a: self.env['annox'][anx][e] = self._env_def_a[e].format(source=source, annox=anx, task=task, zspace=zspace, **self._myconfig)