config.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. """
  2. Configuration Module.
  3. This reads the configuration file and conveniently makes the settings available to KCG
  4. """
  5. import ConfigParser
  6. import ast
  7. import os
  8. import sys
  9. import logging
  10. class NoValueException(Exception):
  11. """
  12. Simple Exception that gets thrown when no Value was given in the configuration file
  13. """
  14. pass
  15. class MisconfigurationError(Exception):
  16. """
  17. Simple Exception to indicate that a misconfiguration was found.
  18. """
  19. pass
  20. def leval(string):
  21. """
  22. Wrapper arount ast.literal_eval that throws NoValueException if the value was empty
  23. :param string:
  24. :return:
  25. """
  26. if string == "":
  27. raise NoValueException("No value given for option")
  28. else:
  29. return ast.literal_eval(string)
  30. class ConfSection(object):
  31. """
  32. Class to handle a section in the configuration.
  33. """
  34. def __init__(self, section, settings, config_object, default_config_object=None, log_level=logging.ERROR):
  35. self._section = section
  36. self._settings = settings
  37. self._conf_obj = config_object
  38. self._def_conf_obj = default_config_object
  39. self._arg_dict = {}
  40. self._log_level = log_level
  41. def feed_arguments(self, arg_dict):
  42. """
  43. Feed this section with commandline arguments for this section. The given arguments will
  44. override the ones in configuration files.
  45. :param arg_dict: the dictionary for all sections
  46. :return:
  47. """
  48. if self._section in arg_dict:
  49. self._arg_dict = arg_dict[self._section]
  50. else:
  51. self._arg_dict = {}
  52. def read(self):
  53. """
  54. Read and evaluate configuration settings.
  55. :return:
  56. """
  57. error = False
  58. for conf in self._settings:
  59. if conf in self._arg_dict:
  60. try:
  61. globals()[conf] = leval(self._arg_dict[conf])
  62. continue
  63. except Exception:
  64. if self._log_level <= logging.ERROR:
  65. print "Error in parsing commandline configuration using configuration in config file."
  66. if self._conf_obj.has_option(self._section, conf):
  67. try:
  68. globals()[conf] = leval(self._conf_obj.get(self._section, conf))
  69. except NoValueException:
  70. error = True
  71. elif self._def_conf_obj is not None:
  72. if self._log_level <= logging.DEBUG:
  73. print "Using default configuration value for " + conf
  74. globals()[conf] = leval(self._def_conf_obj.get(self._section, conf))
  75. else:
  76. error = True
  77. return not error
  78. class Configuration(object):
  79. """
  80. Class to handle configuration
  81. """
  82. def __init__(self, args=None, log_level=logging.INFO):
  83. self._args = args
  84. self._parsed_args = {}
  85. self.error = False
  86. self._log_level = log_level
  87. globals()['config_object'] = self
  88. globals()['log_level'] = log_level
  89. if args:
  90. self.parse_command_line()
  91. def parse_command_line(self):
  92. """
  93. Parses the command line configuration arguments
  94. :return:
  95. """
  96. if ';' in self._args:
  97. self._args = self._args.split(';')
  98. else:
  99. self._args = [self._args]
  100. for setting in self._args:
  101. if setting == '':
  102. continue
  103. try:
  104. sec, set = setting.strip().split('->')
  105. sets, setv = set.split('=')
  106. section = self._parsed_args.setdefault(sec, {})
  107. section[sets.strip()] = setv.strip()
  108. except:
  109. print "Format of commandline configuration is wrong. Using config file version"
  110. def read(self):
  111. """
  112. This function reads the configuration file and the default config fille (in case the
  113. user config file does not contain all values) and adds them as parameters to this module
  114. :return:
  115. """
  116. config = ConfigParser.ConfigParser()
  117. config.optionxform = str
  118. config.read(os.path.expanduser("~")+"/.kcg/config.cfg")
  119. defaultConfig = ConfigParser.ConfigParser()
  120. defaultConfig.optionxform = str
  121. defaultConfig.read(os.path.join(os.path.dirname(__file__), "config.cfg"))
  122. Machine_conf = ["bunches_per_turn", "save_header", "tRev"]
  123. Ui_conf = ["language", "default_save_location", "default_subdirectory_name", "force_ask", "show_advanced_control", "integrate_single_read"]
  124. Logging_conf = ["epics_test_pv", "epics_base_path", "epics_log_entry_pvs", "default_log_entries"]
  125. Misc_conf = ['newPlotLiveIcon', 'newPlotDataIcon', 'timingIcon', 'singleReadIcon',
  126. 'acquireSettingsIcon', 'startIcon', 'stopIcon', 'logIcon', 'logCommentIcon', 'guiIcon', 'style',
  127. 'board_detection_method', 'device_list', 'device_names',
  128. 'num_dummy_boards']
  129. try:
  130. machine_c = ConfSection('Machine', Machine_conf, config, log_level=self._log_level)
  131. machine_c.feed_arguments(self._parsed_args)
  132. self.error = True if not machine_c.read() else self.error
  133. ui_c = ConfSection('Ui', Ui_conf, config, defaultConfig, self._log_level)
  134. ui_c.feed_arguments(self._parsed_args)
  135. self.error = True if not ui_c.read() else self.error
  136. logging_c = ConfSection('Logging', Logging_conf, config, defaultConfig, self._log_level)
  137. logging_c.feed_arguments(self._parsed_args)
  138. self.error = True if not logging_c.read() else self.error
  139. misc_c = ConfSection('Misc', Misc_conf, config, defaultConfig, self._log_level)
  140. misc_c.feed_arguments(self._parsed_args)
  141. self.error = True if not misc_c.read() else self.error
  142. # if config.has_section('Misc'):
  143. # for conf, val in config.items("Misc"):
  144. # globals()[conf] = leval(val)
  145. # for conf, val in defaultConfig.items("Misc"):
  146. # if not conf in globals().keys():
  147. # globals()[conf] = leval(val)
  148. except (ConfigParser.NoOptionError, ConfigParser.NoSectionError) as e:
  149. self.error = True
  150. print "There was an error parsing configuration: " + str(e)
  151. def setup(self):
  152. """
  153. Check for the user config file and if not exists calls doSetup
  154. :return:
  155. """
  156. if not os.path.isfile(os.path.expanduser("~")+"/.kcg/config.cfg"):
  157. self.doSetup()
  158. else:
  159. self.read()
  160. def doSetup(self, rerun=False, parent=None):
  161. """
  162. Shows the initial config dialog
  163. :return:
  164. """
  165. from widgets.initialconfig import ConfigSetup
  166. from PyQt4 import QtGui, QtCore
  167. if not rerun:
  168. setupConfigApp = QtGui.QApplication([])
  169. self.setupConfig = ConfigSetup()
  170. self.setupConfig.show()
  171. setupConfigApp.exec_()
  172. if not self.setupConfig.result:
  173. sys.exit(122)
  174. else:
  175. self.setupConfig = ConfigSetup(restart=True)
  176. self.setupConfig.setWindowModality(QtCore.Qt.ApplicationModal)
  177. self.setupConfig.show()
  178. self.error = False
  179. self.read()