Source code for cal_nc.nc_conf
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
r"""
Functions for parsing of configuration files.
"""
import datetime, pytz
import netCDF4
import os.path
import configparser
import shutil
import pdb
import cal_proc
from cal_proc import *
__all__ = ['read_config','extract_specials']
# Directory where temporary files are stored
default_tmp_dir = './tmp'
# List of default 'special key strings' in configuration dictionary
default_special_str = ['_group',
'_parsefile']
[docs]def read_config(cfg_file, de_str=True):
"""Read in configuration file and return entries in dictionary.
ConfigParser options used are;
* allow_no_value=True
Args:
cfg_file (:obj:`str` or :obj:`pathlib`): Configuration path/filename
with the required format.
de_str (:obj:`bool`): If True [default] then attempt to de-string string
entries.
Returns:
Dictionary with sub-dictionaries for each section or None if
``cfg_file`` cannot be found.
"""
# Manual configuration converters
def _list_converter(s):
"""
Convert comma-delineated string to list of numbers or strings as
appropriate. 'none' strings are converted to None
"""
assert ',' in s
l = [s_.strip().replace('"','').replace('\'','') for s_ in s.split(',')]
for conv_ in (int,float,str):
try:
l = [None if s_.lower()=='none' else conv_(s_) for s_ in l[:]]
except ValueError as err:
continue
else:
break
return l
def _convert_time(s):
""" Converts a datetime string into a datetime object
"""
from dateutil import parser
try:
return parser.parse(s, dayfirst=True)
except ValueError as err:
raise err
def _ConfigSectionMap(section,rtn_str=False):
# Read each option within the given section
# If rtn_str is False then attempt to inteprete/convert string
if rtn_str == True:
getter = [cfg.get]
else:
getter = [cfg.getlist,
cfg.getint,cfg.getfloat,
cfg.getboolean, # after get numbers so 0/1 are ints
cfg.get]
cfg_d = {}
options = cfg.options(section)
for option in options:
if option.lower() in ['time']:
# Make sure time entries stay as strings
cfg_d[option] = cfg.get(section, option)
continue
for getter_ in getter:
try:
cfg_d[option] = getter_(section, option)
except ValueError as err:
continue
except AssertionError as err:
# String does not include comma so not a list
# Raised by list_converter()
continue
except (TypeError,AttributeError) as err:
# Generally attempting to convert a None
# If None then loop through to cfg.get()
continue
except Exception as err:
print('exception on {}!'.format(option))
print(err)
pdb.set_trace()
break
else:
break
# Attempt to convert 'none' strings to None
if cfg_d[option] in ['none', 'None', 'NONE']:
cfg_d[option] = None
return cfg_d
# Check file validity
if not os.path.exists(cfg_file):
# If file as named doesn't exist then add an extension if possible
if os.path.exists(os.path.splitext(cfg_file)[0] + '.cfg'):
cfg_file = os.path.splitext(cfg_file)[0] + '.cfg'
else:
print('filename {} does not exist.'.format(cfg_file))
return None
cfg = configparser.ConfigParser(allow_no_value=True,
converters={'list': _list_converter,
'datetime': _convert_time})
cfg.read(cfg_file)
cfg_dict = {}
for l in cfg.sections():
cfg_dict[l] = _ConfigSectionMap(l,not(de_str))
if cfg_dict == {}:
print('\ncfg_dict is empty but ' +\
'{0} exists.'.format(os.path.basename(cfg)))
print(' This usually occurs when the eol is set incorrectly. '+\
'Unix eol characters are known to work.\n')
cfg_dict = None
return cfg_dict