Source code for microdrop.config

"""
Copyright 2011 Ryan Fobel

This file is part of MicroDrop.

MicroDrop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MicroDrop is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MicroDrop.  If not, see <http://www.gnu.org/licenses/>.
"""

import os
import warnings
import logging

from path_helpers import path
from configobj import ConfigObj, Section, flatten_errors
from validate import Validator
from microdrop_utility.user_paths import home_dir, app_data_dir

logger = logging.getLogger(__name__)

[docs]class ValidationError(Exception): pass
[docs]class Config(object): if os.name == 'nt': default_config_directory = home_dir().joinpath('MicroDrop') else: default_config_directory = app_data_dir().joinpath('.microdrop') default_config_path = default_config_directory / path('microdrop.ini') spec = """ [dmf_device] # name of the most recently used DMF device name = string(default=None) [protocol] # name of the most recently used protocol name = string(default=None) [plugins] # directory containing microdrop plugins directory = string(default=None) # list of enabled plugins enabled = string_list(default=list()) """ def __init__(self, filename=None): self.load(filename) def __getitem__(self, i): return self.data[i]
[docs] def load(self, filename=None): """ Load a Config object from a file. Args: filename: path to file. If None, try loading from the default location, and if there's no file, create a Config object with the default options. Raises: IOError: The file does not exist. ConfigObjError: There was a problem parsing the config file. ValidationError: There was a problem validating one or more fields. """ if filename is None: logger.info("Using default configuration.") self.filename = self.default_config_path elif not path(filename).exists(): raise IOError else: self.filename = filename logger.info("Loading config file from %s" % self.filename) self.data = ConfigObj(self.filename, configspec=self.spec.split("\n")) self._validate()
[docs] def save(self, filename=None): if filename == None: filename = self.filename # make sure that the parent directory exists path(filename).realpath().parent.makedirs_p() with open(filename, 'w') as f: self.data.write(outfile=f)
def _validate(self): # set all str values that are 'None' to None def set_str_to_none(d): for k, v in d.items(): if type(v)==Section: set_str_to_none(v) else: if type(v)==str and v=='None': d[k]=None set_str_to_none(self.data) validator = Validator() results = self.data.validate(validator, copy=True) if results != True: logger.error('Config file validation failed!') for (section_list, key, _) in flatten_errors(self.data, results): if key is not None: logger.error('The "%s" key in the section "%s" failed ' 'validation' % (key, ', '.join(section_list))) else: logger.error('The following section was missing:%s ' % ', '.join(section_list)) raise ValidationError self.data.filename = self.filename self._init_data_dir() self._init_plugins_dir() def _init_data_dir(self): # If no user data directory is set in the configuration file, select # default directory based on the operating system. if os.name == 'nt': default_data_dir = home_dir().joinpath('MicroDrop') else: default_data_dir = home_dir().joinpath('.microdrop') if 'data_dir' not in self.data: self.data['data_dir'] = default_data_dir warnings.warn('Using default MicroDrop user data path: %s' % default_data_dir) if not path(self['data_dir']).isdir(): warnings.warn('MicroDrop user data directory does not exist.') path(self['data_dir']).makedirs_p() warnings.warn('Created MicroDrop user data directory: %s' % self['data_dir']) def _init_plugins_dir(self): if self.data['plugins']['directory'] is None: self.data['plugins']['directory'] = (path(self['data_dir']) .joinpath('plugins')) plugins_directory = path(self.data['plugins']['directory']) if not plugins_directory.isdir(): plugins_directory.makedirs_p() if not plugins_directory.joinpath('__init__.py').isfile(): plugins_directory.joinpath('__init__.py').touch()