config.py 8.6 KB

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