summaryrefslogtreecommitdiff
path: root/src/python/app/settings.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/app/settings.py')
-rw-r--r--src/python/app/settings.py277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/python/app/settings.py b/src/python/app/settings.py
new file mode 100644
index 0000000..a25eece
--- /dev/null
+++ b/src/python/app/settings.py
@@ -0,0 +1,277 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import sys
+import re
+import optparse
+
+import libavg
+
+
+class Option(object):
+ def __init__(self, key, value, help=None):
+ if not isinstance(key, str):
+ raise ValueError('The type of %s key is not string (value=%s)' % (key, value))
+
+ self.__key = key
+ self.value = value
+ self.__help = help
+
+ def __repr__(self):
+ return '<%s key=%s value=%s help=%s>' % (self.__class__.__name__,
+ self.key, self.value, self.help)
+
+ @property
+ def key(self):
+ return self.__key
+
+ @property
+ def value(self):
+ return self.__value
+
+ @value.setter
+ def value(self, value):
+ if not isinstance(value, str):
+ raise ValueError('The type of %s value (%s) '
+ 'must be string instead of %s' % (self.__key, value, type(value)))
+
+ self.__value = value
+
+ @property
+ def group(self):
+ components = self.__getComponents()
+ if len(components) == 1:
+ return 'DEFAULT'
+ else:
+ return components[0]
+
+ @property
+ def tail(self):
+ components = self.__getComponents()
+ if len(components) == 1:
+ return self.key
+ else:
+ return components[1]
+
+ @property
+ def help(self):
+ return self.__help
+
+ def __getComponents(self):
+ return self.key.split('_', 1)
+
+
+class KargsExtender(object):
+ def __init__(self, optionsKargs):
+ self.__optionsKargs = optionsKargs
+
+ def __call__(self, optionsList):
+ optionsKeyset = set([option.key for option in optionsList])
+ kaKeyset = set(self.__optionsKargs.keys())
+
+ if not optionsKeyset.issuperset(kaKeyset):
+ raise RuntimeError('No such option/s: %s' % list(kaKeyset - optionsKeyset))
+
+ for option in optionsList:
+ if option.key in self.__optionsKargs:
+ option.value = self.__optionsKargs[option.key]
+
+ return optionsList
+
+
+class HelpPrintingOptionParser(optparse.OptionParser):
+ def error(self, *args, **kargs):
+ self.print_help()
+ optparse.OptionParser.error(self, *args, **kargs)
+
+
+class ArgvExtender(object):
+ def __init__(self, appVersionInfo, args=None):
+ self.__appVersionInfo = appVersionInfo
+ self.__parser = HelpPrintingOptionParser()
+ self.__args = args
+ self.__parsedArgs = None
+
+ def __call__(self, optionsList):
+ self.__parser.add_option('-v', '--version', dest='version', action='store_true',
+ help='print libavg and application version information')
+
+ groups = self.__groupOptionsKeys(optionsList)
+
+ for group in sorted(groups):
+ parserGroup = optparse.OptionGroup(self.__parser,
+ '%s section' % group.title())
+
+ keys = sorted(groups[group])
+
+ for option in [option for option in optionsList if option.key in keys]:
+ cliKey = '--%s' % option.key.replace('_', '-').lower()
+ currentValue = option.value if option.value else '<undefined>'
+
+ help = '[Default: %s]' % currentValue
+
+ if option.help:
+ help = '%s %s' % (option.help, help)
+
+ parserGroup.add_option(cliKey, help=help)
+
+ self.__parser.add_option_group(parserGroup)
+
+ if self.__args is None:
+ self.__args = sys.argv[1:]
+
+ self.__parsedArgs = self.__parser.parse_args(args=self.__args)
+
+ parsedOptions = self.__parsedArgs[0]
+
+ if parsedOptions.version:
+ print 'libavg'
+ vi = libavg.VersionInfo()
+ print ' version : %s' % vi.full
+ print ' builder : %s (%s)' % (vi.builder, vi.buildtime)
+ print ' branchurl: %s' % vi.branchurl
+ print
+ print 'application'
+ print ' version: %s' % self.__appVersionInfo
+ sys.exit(0)
+
+ for key, value in parsedOptions.__dict__.iteritems():
+ if value is not None:
+ for option in optionsList:
+ if option.key == key:
+ option.value = value
+
+ return optionsList
+
+ @property
+ def parsedArgs(self):
+ if self.__parsedArgs is None:
+ raise RuntimeError('Cannot provide parsedArgs before applying the extender')
+
+ return self.__parsedArgs
+
+ @property
+ def parser(self):
+ return self.__parser
+
+ def __groupOptionsKeys(self, optionsList):
+ groups = {}
+ for option in optionsList:
+ if not option.group in groups:
+ groups[option.group] = []
+
+ groups[option.group].append(option.key)
+
+ return groups
+
+
+class Settings(object):
+ def __init__(self, defaults=[]):
+ if (type(defaults) not in (tuple, list) or
+ not all([isinstance(opt, Option) for opt in defaults])):
+ raise ValueError('Settings must be initialized with a list '
+ 'of Option instances')
+
+ self.__options = []
+
+ for option in defaults:
+ self.addOption(option)
+
+ def __iter__(self):
+ return self.__options.__iter__()
+
+ def applyExtender(self, extender):
+ self.__options = extender(self.__options)
+
+ def hasOption(self, key):
+ return self.__getOptionOrNone(key) is not None
+
+ def getOption(self, key):
+ option = self.__getOptionOrNone(key)
+
+ if option is None:
+ raise RuntimeError('Cannot find key %s in the settings' % key)
+
+ return option
+
+ def get(self, key, convertFunc=lambda v: v):
+ option = self.getOption(key)
+
+ try:
+ return convertFunc(option.value)
+ except (TypeError, ValueError), e:
+ raise ValueError('%s (option=%s)' % (e, option))
+
+ def getJson(self, key):
+ import json
+
+ return self.get(key, json.loads)
+
+ def getPoint2D(self, key):
+ value = self.get(key)
+ maybeTuple = re.split(r'\s*[,xX]\s*', value)
+
+ if len(maybeTuple) != 2:
+ raise ValueError('Cannot convert key %s value %s to Point2D' % (key, value))
+
+ return libavg.Point2D(map(float, maybeTuple))
+
+ def getInt(self, key):
+ return self.get(key, int)
+
+ def getFloat(self, key):
+ return self.get(key, float)
+
+ def getBoolean(self, key):
+ value = self.get(key).lower()
+
+ if value in ('yes', 'true'):
+ return True
+ elif value in ('no', 'false'):
+ return False
+ else:
+ raise ValueError('Cannot convert %s to boolean' % value)
+
+ def set(self, key, value):
+ option = self.getOption(key)
+ option.value = value
+
+ def addOption(self, option):
+ if not isinstance(option, Option):
+ raise TypeError('Must be an instance of Option')
+
+ if self.__getOptionOrNone(option.key):
+ raise RuntimeError('Option %s has been already defined' % option.key)
+
+ self.__options.append(option)
+
+ def __getOptionOrNone(self, key):
+ for option in self.__options:
+ if option.key == key:
+ return option
+
+ return None
+
+