00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2002 00004 # by 00005 # The Board of Trustees of the 00006 # Leland Stanford Junior University. 00007 # All rights reserved. 00008 # 00009 00010 __facility__ = "Online" 00011 __abstract__ = "Run Control Preferences manager GUI module" 00012 __author__ = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = ("$Date: 2005/12/22 03:31:28 $").split(' ')[1] 00014 __version__ = "$Revision: 2.19 $" 00015 __release__ = "$Name: R04-12-00 $" 00016 __credits__ = "SLAC" 00017 00018 import LATTE.copyright_SLAC 00019 00020 import sys 00021 import os 00022 import types 00023 import re 00024 import string 00025 import logging.handlers 00026 from ConfigParser import * 00027 from rcUsers import rcUser, rcUsers 00028 00029 class rcPreferencesManager(object): 00030 def __init__(self, configFile): 00031 self.__prefs = Preferences() 00032 self.__configFile = configFile 00033 self.__pythonPath = sys.path 00034 self.__configFile = os.path.abspath(configFile) 00035 confParser = self.loadDefaults(os.getcwd()) 00036 self.__defPrefs = self.parserToPrefs(confParser) 00037 00038 def loadConfig(self): 00039 confParser = ConfigParser() 00040 if os.path.exists(self.__configFile): 00041 confParser.read(self.__configFile) 00042 else: 00043 return None 00044 00045 self.parserToPrefs(confParser, self.__prefs) 00046 self.__prefs['fitsnbl'] = 0 00047 self.__prefs['fitscompress'] = 0 00048 00049 # Do not override the paths with default values anymore since the paths 00050 # may point to disconnected network drives. 00051 # 00052 #for dirname in Preferences.DIR_LIST: 00053 # if not self.__prefs.has_key(dirname) or not os.path.isdir(self.__prefs[dirname]): 00054 # self.__prefs[dirname] = self.__defPrefs[dirname] 00055 00056 for choice in (Preferences.CHOICE_LIST + 00057 Preferences.LOGGING_LIST + 00058 Preferences.SYSTEM_LIST): 00059 if not self.__prefs.has_key(choice): 00060 self.__prefs[choice] = self.__defPrefs[choice] 00061 00062 return 1 00063 00064 def writeConfig(self): 00065 confParser = self.prefsToParser() 00066 try: 00067 confParser.write(file(self.getConfigFile(), "w+")) 00068 except IOError, (errno, errdetail): 00069 print "*** rcPreferencesGUIImpl cannot save preferences to \'%s\': %s" \ 00070 %(self.getConfigFile(), errdetail) 00071 00072 def preferences(self): 00073 return self.__prefs 00074 00075 def defPrefs(self): 00076 return self.__defPrefs 00077 00078 def getConfigFile(self): 00079 return self.__configFile 00080 00081 def refreshPrefs(self, newPrefs): 00082 for (key, val) in newPrefs.items(): 00083 self.__prefs[key] = val 00084 00085 def setPref(self, keyword, value): 00086 self.__prefs[keyword] = value 00087 00088 def parserToPrefs(self, confParser, prefs={}): 00089 # don't overwrite existing users when loading prefs 00090 lastuser = None 00091 if 'users' in prefs: 00092 userList = prefs['users'] 00093 else: 00094 userList = rcUsers() 00095 sections = confParser.sections() 00096 for section in sections: 00097 if section in ('paths', 'choices', 'logging', 'system'): 00098 options = confParser.options(section) 00099 for option in options: 00100 prefs[option] = confParser.get(section, option) 00101 elif section == 'users': 00102 options = confParser.options(section) 00103 for option in options: 00104 value = confParser.get(section, option).split(',',1) 00105 if len(value) == 2: 00106 # Must be login id and user name separated by comma. 00107 user = rcUser(option, value[0].strip(), value[1].strip()) 00108 else: 00109 # No login id, set the login id to be the same as user name. 00110 user = rcUser(option, value[0].strip(), value[0].strip()) 00111 if option == 'lastuser': 00112 lastuser = user 00113 else: 00114 userList.addUser(user) 00115 else: 00116 # again don't overwrite existing lists 00117 if section in prefs: 00118 optionList = prefs[section] 00119 else: 00120 optionList = {} 00121 options = confParser.options(section) 00122 for option in options: 00123 if option in Preferences.LAST_ITEMS: 00124 prefs[option] = confParser.get(section, option) 00125 else: 00126 optionList[confParser.get(section, option)] = option 00127 prefs[section] = optionList 00128 prefs['users'] = userList 00129 if lastuser is None: 00130 # Last user hasn't been set yet, use the first id available. 00131 userIds = prefs["users"].getUsers().keys() 00132 userIds.sort() 00133 if len(userIds) > 0: 00134 lastuser = userList.getUser(userIds[0]) 00135 if lastuser is not None: 00136 # Get the real user object that contains the id. 00137 lastuser = userList.getUserByName(lastuser.getName()) 00138 prefs["operatorobj"] = lastuser 00139 prefs["operator"] = lastuser.getName() 00140 prefs["userid"] = lastuser.getId() 00141 00142 # add _ROOT env vars to path: revisit 00143 if prefs.has_key('pythonpath'): 00144 additionalpaths = os.path.expandvars(prefs['pythonpath']).split(';') 00145 if prefs['pythonpath'].strip() != '': 00146 sys.path = map(string.strip, additionalpaths) + self.__pythonPath 00147 return prefs 00148 00149 def prefsToParser(self): 00150 prefs = self.__prefs 00151 confParser = ConfigParser() 00152 confParser.add_section("paths") 00153 confParser.add_section("choices") 00154 confParser.add_section("logging") 00155 confParser.add_section("users") 00156 confParser.add_section("system") 00157 for (option, value) in prefs.items(): 00158 if option in Preferences.DIR_LIST: 00159 confParser.set("paths", option, prefs.get(option)) 00160 elif option in Preferences.CHOICE_LIST: 00161 confParser.set("choices", option, str(prefs[option])) 00162 elif option in Preferences.LOGGING_LIST: 00163 confParser.set("logging", option, str(prefs[option])) 00164 elif option in Preferences.SYSTEM_LIST: 00165 confParser.set("system", option, prefs[option]) 00166 elif option == 'users': 00167 for (userId, user) in value.getUsers().items(): 00168 confParser.set("users", "%03d" % int(userId), "%s,%s" % (user.getLoginId(), user.getName())) 00169 elif option == 'operatorobj': 00170 confParser.set("users", "lastuser", "%s,%s" % (value.getLoginId(), value.getName())) 00171 elif type(value) == types.DictType: 00172 confParser.add_section(option) 00173 for (key, val) in value.items(): 00174 confParser.set(option, val, key) 00175 if option == 'instrument type': 00176 self.processLastItem(option, 'lastinstrumenttype', confParser) 00177 elif option == 'phase': 00178 self.processLastItem(option, 'lastphase', confParser) 00179 elif option == 'site': 00180 self.processLastItem(option, 'lastsite', confParser) 00181 elif option == 'orientation': 00182 self.processLastItem(option, 'lastorientation', confParser) 00183 elif option == 'particle type': 00184 self.processLastItem(option, 'lastparticletype', confParser) 00185 return confParser 00186 00187 00188 def processLastItem(self, option, item, confParser): 00189 prefs = self.__prefs 00190 if prefs.has_key(item): 00191 last = prefs[item] 00192 if last == 'NOT-DEFINED': 00193 last = prefs.getLastItem(item) 00194 confParser.set(option, item, last) 00195 00196 00197 def loadDefaults(self, currentDir): 00198 cp = ConfigParser() 00199 cp.add_section("paths") 00200 cp.add_section("choices") 00201 cp.add_section("logging") 00202 cp.add_section("system") 00203 cp.set("paths","reposdir",currentDir) 00204 cp.set("paths","appdir",currentDir) 00205 cp.set("paths","datadir",currentDir) 00206 cp.set("paths","logdir",currentDir) 00207 cp.set("paths","reportdir",currentDir) 00208 cp.set("paths","fitsdir",currentDir) 00209 cp.set("paths","snapshotdir",currentDir) 00210 cp.set("paths","exportdir",currentDir) 00211 cp.set("paths","runiddir",currentDir) 00212 cp.set("choices","datasave","1") 00213 cp.set("choices","dataexport","1") 00214 cp.set("choices","fitsnbl","0") 00215 cp.set("choices","fitscompress","0") 00216 cp.set("choices","snapnbl","1") 00217 cp.set("choices","versionnbl","1") 00218 cp.set("choices","elognbl","0") 00219 cp.set("logging","lognbl","1") 00220 cp.set("logging","loglevel","INFO") 00221 cp.set("logging","loghost","localhost") 00222 cp.set("logging","logport",str(logging.handlers.DEFAULT_TCP_LOGGING_PORT)) 00223 cp.set("system","pythonpath","") 00224 cp.set("system","elogurl","") 00225 cp.set("system","server","1") 00226 cp.set("system","servernbl","0") 00227 cp.set("system","dontreload","") 00228 cp.set("system","preload","") 00229 cp.set("system","disablereload","0") 00230 cp.set("system","showunloaded","0") 00231 cp.set("system","disableverification","0") 00232 00233 return cp 00234 00235 def isnumeric(self, str): 00236 return re.match('^[0-9]+$', str) is not None 00237 00238 00239 def setOperator(self, operator): 00240 operator = str(operator).strip() 00241 if operator == 'NOT-DEFINED': 00242 self.setPref("operator", operator) 00243 self.setPref("userid", '000') 00244 else: 00245 user = self.__prefs["users"].getUserByName(operator) 00246 self.setPref("operator", user.getName()) 00247 self.setPref("operatorobj", user) 00248 self.setPref("userid", user.getId()) 00249 self.writeConfig() 00250 00251 def setParticleType(self, particleType): 00252 self.setPref("lastparticletype", str(particleType)) 00253 if particleType != 'NOT-DEFINED': 00254 self.writeConfig() 00255 00256 def setOrientation(self, orientation): 00257 self.setPref("lastorientation", str(orientation)) 00258 if orientation != 'NOT-DEFINED': 00259 self.writeConfig() 00260 00261 def setSite(self, site): 00262 self.setPref("lastsite", str(site)) 00263 if site != 'NOT-DEFINED': 00264 self.writeConfig() 00265 00266 def setPhase(self, phase): 00267 self.setPref("lastphase", str(phase)) 00268 if phase != 'NOT-DEFINED': 00269 self.writeConfig() 00270 00271 def setInstrumentType(self, instrumentType): 00272 self.setPref("lastinstrumenttype", str(instrumentType)) 00273 if instrumentType != 'NOT-DEFINED': 00274 self.writeConfig() 00275 00276 00277 def userId(self): 00278 if self.__prefs.has_key("userid"): 00279 return int(self.__prefs["userid"]) 00280 else: 00281 return 1234 00282 00283 00284 class Preferences(dict): 00285 """\brief Preferences dictionary 00286 Preferences needs a special dictionary class since the data it stores 00287 may have macros and environment variables in it. 00288 00289 In order to read the values unprocessed use the self.__prefs.get(item) 00290 method. If you need to resolve all the macros and environment variables 00291 then access it like any other dictionary (self.__prefs[item]) 00292 00293 """ 00294 ROOT_DIR_ENVS = ['ONLINE_ROOT','INT_ROOT','ACD_ROOT','CAL_ROOT','TKR_ROOT','ELX_ROOT','LAT_ROOT','TRG_ROOT'] 00295 00296 DIR_LIST = ("reposdir", "appdir", "datadir", 00297 "logdir", "reportdir", "fitsdir", 00298 "snapshotdir", "exportdir", "runiddir") 00299 00300 CHOICE_LIST = ("datasave", "dataexport", "fitsnbl", "fitscompress", 00301 "snapnbl", "versionnbl", "elognbl") 00302 00303 LOGGING_LIST = ("lognbl", "loglevel", "loghost", "logport") 00304 00305 SYSTEM_LIST = ("pythonpath", "elogurl", "server", "servernbl", 00306 "fontfamily", "fontsize", "fontweight", "fontitalic", 00307 "style", "preload", "dontreload", "disablereload", 00308 "showunloaded", "disableverification") 00309 00310 LAST_ITEMS = ("lastuser", "lastsite", "lastorientation", "lastparticletype", 00311 "lastinstrumenttype", "lastphase") 00312 00313 TREAT_AS_INT = ("datasave", "dataexport", "fitsnbl", "fitscompress", 00314 "snapnbl", "versionnbl", "elognbl", "lognbl", "servernbl", 00315 "disablereload", "showunloaded", "logport", "disableverification") 00316 00317 def __init__(self): 00318 dict.__init__(self) 00319 self.__saveLastItem = {} 00320 00321 def __getitem__(self, item): 00322 value = dict.__getitem__(self, item) 00323 if self.isDir(item): 00324 return self.expandVars(value) 00325 elif self.isNumber(item): 00326 return int(value) 00327 else: 00328 return value 00329 00330 def __setitem__(self, item, value): 00331 if self.isLastItem(item) and value != 'NOT-DEFINED': 00332 self.__saveLastItem[item] = value 00333 dict.__setitem__(self, item, value) 00334 00335 def isDir(self, item): 00336 return item in Preferences.DIR_LIST 00337 00338 def isNumber(self, item): 00339 return item in Preferences.TREAT_AS_INT 00340 00341 def isLastItem(self, item): 00342 return item in Preferences.LAST_ITEMS 00343 00344 def expandVars(self, path): 00345 p = os.path.expandvars(path) 00346 dirs = os.path.normpath(p).split(os.sep) 00347 i = 0 00348 for d in dirs: 00349 if d.startswith('@') and d[1:] in dict.keys(self): 00350 dirs[i] = dict.get(self,d[1:]) 00351 00352 if d.startswith('@') and d[1:] in dict.keys(self): 00353 if d[1:] == 'lastinstrumenttype': 00354 dirs[i] = dict.get(self,'instrument type')[dict.get(self,d[1:])] 00355 else: 00356 dirs[i] = dict.get(self,d[1:]) 00357 00358 i+=1 00359 if not dirs[0].endswith(os.sep): 00360 dirs[0]+=os.sep 00361 return reduce(os.path.join, dirs) 00362 00363 def composePath(self, path): 00364 for env in Preferences.ROOT_DIR_ENVS: 00365 if env in os.environ: 00366 if os.path.normpath(path).lower().startswith(os.path.normpath(os.environ[env]).lower()): 00367 return '$' + env + path[len(os.environ[env]):] 00368 return path 00369 00370 def getLastItem(self, item): 00371 if item in self.__saveLastItem: 00372 return self.__saveLastItem[item]