0

overhaul to configParser. Parsing config works now.

This commit is contained in:
Andrew Brown
2012-02-04 21:23:44 -05:00
parent ceb98c4441
commit 6d95d80a73
8 changed files with 321 additions and 245 deletions

View File

@@ -4,103 +4,72 @@ import os.path
import logging
import settingsDefinition
import settingsValidators
class MultiWorldParser(object):
"""A class that is used to parse a settings.py file. It should replace
ConfigOptionParser class above."""
"""A class that is used to parse a settings.py file.
This class's job is to compile and validate the configuration settings for
a set of renders. It can read in configuration from the given file with the
parse() method, and one can set configuration options directly with the
set_config_item() method.
def __init__(self, settings):
"""Settings is a path to a settings.py file"""
if not os.path.exists(settings) and not os.path.isfile(settings):
get_validated_config() validates and returns the validated config
"""
def __init__(self):
"""Initialize this parser object"""
# This maps config names to their values
self._config_state = {}
# Scan the settings definition and build the config state heirarchy.
# Also go ahead and set default values for non-required settings.
# This maps setting names to their values as given in
# settingsDefinition.py
self._settings = {}
for settingname in settingsDefinition.__all__:
setting = getattr(settingsDefinition, settingname)
assert isinstance(setting, settingsValidators.Setting)
self._settings[settingname] = setting
if not setting.required:
self._config_state[settingname] = setting.default
def set_config_item(self, itemname, itemvalue):
self._config_state[itemname] = itemvalue
def parse(self, settings_file):
"""Reads in the named file and parses it, storing the results in an
internal state awating to be validated and returned upon call to
get_render_settings()
"""
if not os.path.exists(settings_file) and not os.path.isfile(settings_file):
raise ValueError("bad settings file")
self.settings_file = settings
def parse(self):
# settingsDefinition.py defines what types of things you can put in a configfile
# anything in settingsDefinitino that is a dict with a "type" key is a definiton
defDicts = [x for x in dir(settingsDefinition) if type(getattr(settingsDefinition,x)) == dict and getattr(settingsDefinition,x).has_key("type") and x != "__builtins__"]
glob = dict()
for name in defDicts:
d = getattr(settingsDefinition, name)
glob[name] = d['type']()
# The global environment should be the rendermode module, so the config
# file has access to those resources.
import rendermodes
loc=dict()
for thing in dir(rendermodes):
thething = getattr(rendermodes, thing)
if isinstance(thething, type) and issubclass(thething, rendermodes.RenderPrimitive):
loc[thing] = thething
try:
execfile(self.settings_file, glob, loc)
# delete the builtins, we don't need it
del glob['__builtins__']
execfile(settings_file, rendermodes.__dict__, self._config_state)
except NameError, ex:
import traceback
traceback.print_exc()
logging.error("Error parsing %s. Please check the trackback above" % self.settings_file)
logging.exception("Error parsing %s. Please check the trackback for more info" % settings_file)
sys.exit(1)
except SyntaxError, ex:
import traceback
traceback.print_exc()
tb = sys.exc_info()[2]
#print tb.tb_frame.f_code.co_filename
logging.error("Error parsing %s. Please check the trackback above" % self.settings_file)
logging.exception("Error parsing %s. Please check the trackback for more info" % self.settings_file)
sys.exit(1)
for name in defDicts:
setattr(self, name, glob[name])
del glob[name]
# seed with the Overviewer defaults, then update with the user defaults
self.defaults = dict()
for name in defDicts:
d = getattr(settingsDefinition, name)
if d['type'] == dict and d['valuetype'] == dict:
for key in d['values']:
option = d['values'][key]
if option.has_key("default"):
self.defaults[key] = option["default"]
self.defaults.update(glob)
def validate(self):
origs = dict()
for worldname in self.render:
world = dict()
world.update(self.defaults)
world.update(self.render[worldname])
for key in world:
if key not in settingsDefinition.render['values']:
logging.warning("%r is not a known setting", key)
continue
definition = settingsDefinition.render['values'][key]
try:
val = definition['validator'](world[key], world = self.world)
if definition.get('save_orig', False):
origs[key + "_orig"] = world[key]
world[key] = val
except Exception as e:
logging.error("Error validating '%s' option in render definition for '%s':", key, worldname)
logging.error(e)
raise e
world['name'] = worldname
world.update(origs)
self.render[worldname] = world
def get_render_things(self):
return self.render
def get_validated_config(self):
"""Validate and return the configuration"""
# Okay, this is okay, isn't it? We're going to create the validation
# routine right here, right now. I hope this works!
validator = settingsValidators.make_configdictvalidator(self._settings)
# Woah. What just happened? No. WAIT, WHAT ARE YOU...
validated_config = validator(self._config_state)
# WHAT HAVE YOU DONE?
return validated_config
# WHAT HAVE YOU DOOOOOOOOOOONE????