rcPreferencesManager.py

Go to the documentation of this file.
00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2005
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__ = "Script Engine Preferences manager GUI module"
00012 __author__   = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "2005/07/23 00:08:27"
00014 __updated__  = "$Date: 2006/04/11 20:10:07 $"
00015 __version__  = "$Revision: 1.9 $"
00016 __release__  = "$Name: HEAD $"
00017 __credits__  = "SLAC"
00018 
00019 import LICOS.copyright_SLAC
00020 
00021 import                sys
00022 import                os
00023 import                types
00024 import                re
00025 import                string
00026 import logging     as log
00027 import                logging.handlers
00028 from ConfigParser     import *
00029 from rcUsers          import rcUser, rcUsers
00030 
00031 class rcPreferencesManager(object):
00032   """!\brief Class for managing the preferences.
00033 
00034   """
00035   def __init__(self, configFile):
00036     """!\brief rcPreferencesManager constructor
00037 
00038     \param configFile Configuration file name
00039     """
00040     self.__prefs = Preferences()
00041     self.__configFile = configFile
00042     self.__pythonPath = sys.path
00043     self.__configFile = os.path.abspath(configFile)
00044     confParser = self.loadDefaults(os.getcwd())
00045     self.__defPrefs = self.parserToPrefs(confParser)
00046 
00047   def loadConfig(self):
00048     """!\brief Parse and load the configuration file
00049 
00050     \return 1
00051     """
00052     confParser = ConfigParser()
00053     if os.path.exists(self.__configFile):
00054       confParser.read(self.__configFile)
00055     else:
00056       return None
00057 
00058     self.parserToPrefs(confParser, self.__prefs)
00059 
00060     # Do not override the paths with default values anymore since the paths
00061     # may point to disconnected network drives.
00062     #
00063     #for dirname in Preferences.DIR_LIST:
00064     #  if not self.__prefs.has_key(dirname) or not os.path.isdir(self.__prefs[dirname]):
00065     #    self.__prefs[dirname] = self.__defPrefs[dirname]
00066 
00067     for choice in (Preferences.CHOICE_LIST +
00068                    Preferences.LOGGING_LIST +
00069                    Preferences.SYSTEM_LIST):
00070       if not self.__prefs.has_key(choice):
00071         self.__prefs[choice] = self.__defPrefs[choice]
00072 
00073     return 1
00074 
00075   def writeConfig(self):
00076     """!\brief Write the configuration back to the file.
00077 
00078     """
00079     confParser = self.prefsToParser()
00080     try:
00081       confParser.write(file(self.getConfigFile(), "w+"))
00082     except IOError, (errno, errdetail):
00083       log.error("*** rcPreferencesGUIImpl cannot save preferences to \'%s\': %s" \
00084             %(self.getConfigFile(), errdetail))
00085 
00086   def preferences(self):
00087     """!\brief Retrieve the preferences.
00088 
00089     \return Preferences instance.
00090     """
00091     return self.__prefs
00092 
00093   def defPrefs(self):
00094     """!\brief Retrive the default preferences.
00095 
00096     \return Default preferences
00097     """
00098     return self.__defPrefs
00099 
00100   def getConfigFile(self):
00101     """!\brief Retrieve the configuration file name.
00102 
00103     \return Configuration file name
00104     """
00105     return self.__configFile
00106 
00107   def refreshPrefs(self, newPrefs):
00108     """!\brief Refresh the preferences from \a newPrefs.
00109 
00110     """
00111     for (key, val) in newPrefs.items():
00112       self.__prefs[key] = val
00113 
00114   def setPref(self, keyword, value):
00115     """!\brief Set a preference value.
00116 
00117     \param keyword Preference keyword
00118     \param value   Preference value
00119     """
00120     self.__prefs[keyword] = value
00121 
00122   def parserToPrefs(self, confParser, prefs={}):
00123     """!\brief Populate preferences from the parser.
00124 
00125     \param confParser ConfigParser instance
00126     \param prefs      Preferences instance
00127 
00128     \return Preferences instance
00129     """
00130     # don't overwrite existing users when loading prefs
00131     lastuser = None
00132     if 'users' in prefs:
00133       userList = prefs['users']
00134     else:
00135       userList = rcUsers()
00136     sections = confParser.sections()
00137     for section in sections:
00138       if section in ('paths', 'choices', 'logging', 'system'):
00139         options = confParser.options(section)
00140         for option in options:
00141           prefs[option] = confParser.get(section, option)
00142       elif section == 'users':
00143         options = confParser.options(section)
00144         for option in options:
00145           value = confParser.get(section, option).split(',',1)
00146           if len(value) == 2:
00147             # Must be login id and user name separated by comma.
00148             user = rcUser(option, value[0].strip(), value[1].strip())
00149           else:
00150             # No login id, set the login id to be the same as user name.
00151             user = rcUser(option, value[0].strip(), value[0].strip())
00152           if option == 'lastuser':
00153             lastuser = user
00154           else:
00155             userList.addUser(user)
00156       else:
00157         # again don't overwrite existing lists
00158         if section in prefs:
00159           optionList = prefs[section]
00160         else:
00161           optionList = {}
00162         options = confParser.options(section)
00163         for option in options:
00164           if option in Preferences.LAST_ITEMS:
00165             prefs[option] = confParser.get(section, option)
00166           else:
00167             optionList[confParser.get(section, option)] = option
00168         prefs[section] = optionList
00169     prefs['users'] = userList
00170     if lastuser is None:
00171       # Last user hasn't been set yet, use the first id available.
00172       userIds = prefs["users"].getUsers().keys()
00173       userIds.sort()
00174       if len(userIds) > 0:
00175         lastuser = userList.getUser(userIds[0])
00176     if lastuser is not None:
00177       # Get the real user object that contains the id.
00178       lastuser = userList.getUserByName(lastuser.getName())
00179       prefs["operatorobj"] = lastuser
00180       prefs["operator"] = lastuser.getName()
00181       prefs["userid"] = lastuser.getId()
00182 
00183     # add _ROOT env vars to path: revisit
00184     if prefs.has_key('pythonpath'):
00185       additionalpaths = os.path.expandvars(prefs['pythonpath']).split(';')
00186       if prefs['pythonpath'].strip() != '':
00187         sys.path = map(string.strip, additionalpaths) + self.__pythonPath
00188     return prefs
00189 
00190   def prefsToParser(self):
00191     """!\brief Populate the parser from the preferences.
00192 
00193     \return ConfigParser instance
00194     """
00195     prefs = self.__prefs
00196     confParser = ConfigParser()
00197     confParser.add_section("paths")
00198     confParser.add_section("choices")
00199     confParser.add_section("logging")
00200     confParser.add_section("users")
00201     confParser.add_section("system")
00202     for (option, value) in prefs.items():
00203       if option in Preferences.DIR_LIST:
00204         confParser.set("paths", option, prefs.get(option))
00205       elif option in Preferences.CHOICE_LIST:
00206         confParser.set("choices", option, str(prefs[option]))
00207       elif option in Preferences.LOGGING_LIST:
00208         confParser.set("logging", option, str(prefs[option]))
00209       elif option in Preferences.SYSTEM_LIST:
00210         confParser.set("system", option, prefs[option])
00211       elif option == 'users':
00212         for (userId, user) in value.getUsers().items():
00213           confParser.set("users", "%03d" % int(userId), "%s,%s" % (user.getLoginId(), user.getName()))
00214       elif option == 'operatorobj':
00215         confParser.set("users", "lastuser", "%s,%s" % (value.getLoginId(), value.getName()))
00216       elif type(value) == types.DictType:
00217         if option in Preferences.EXCLUDED_DICTS:
00218           continue
00219         confParser.add_section(option)
00220         for (key, val) in value.items():
00221           confParser.set(option, val, key)
00222         if option == 'instrument type':
00223           self.processLastItem(option, 'lastinstrumenttype', confParser)
00224         elif option == 'phase':
00225           self.processLastItem(option, 'lastphase', confParser)
00226         elif option == 'site':
00227           self.processLastItem(option, 'lastsite', confParser)
00228         elif option == 'orientation':
00229           self.processLastItem(option, 'lastorientation', confParser)
00230         elif option == 'particle type':
00231           self.processLastItem(option, 'lastparticletype', confParser)
00232     return confParser
00233 
00234 
00235   def processLastItem(self, option, item, confParser):
00236     """!\brief Retrieve the last item of a preference and update the parser.
00237 
00238     \param option     Preference option name
00239     \param item       Preference name for the last item
00240     \param confParser ConfigParser instance
00241     """
00242     prefs = self.__prefs
00243     if prefs.has_key(item):
00244       last = prefs[item]
00245       if last == 'NOT-DEFINED':
00246         last = prefs.getLastItem(item)
00247       confParser.set(option, item, last)
00248 
00249 
00250   def loadDefaults(self, currentDir):
00251     """!\brief Load default preferences in to the parser.
00252 
00253     \return ConfigParser instance
00254     """
00255     cp = ConfigParser()
00256     cp.add_section("paths")
00257     cp.add_section("choices")
00258     cp.add_section("logging")
00259     cp.add_section("system")
00260     cp.set("paths","reposdir",currentDir)
00261     cp.set("paths","appdir",currentDir)
00262     cp.set("paths","datadir",currentDir)
00263     cp.set("paths","logdir",currentDir)
00264     cp.set("paths","reportdir",currentDir)
00265     cp.set("paths","snapshotdir",currentDir)
00266     cp.set("paths","exportdir",currentDir)
00267     cp.set("paths","runiddir",currentDir)
00268     cp.set("choices","datasave","1")
00269     cp.set("choices","dataexport","1")
00270     cp.set("choices","snapnbl","1")
00271     cp.set("choices","versionnbl","1")
00272     cp.set("choices","elognbl","0")
00273     cp.set("logging","lognbl","1")
00274     cp.set("logging","loglevel","INFO")
00275     cp.set("logging","loghost","localhost")
00276     cp.set("logging","logport",str(logging.handlers.DEFAULT_TCP_LOGGING_PORT))
00277     cp.set("system","pythonpath","")
00278     cp.set("system","elogurl","")
00279     cp.set("system","server","1")
00280     cp.set("system","servernbl","0")
00281     cp.set("system","dontreload","")
00282     cp.set("system","preload","")
00283     cp.set("system","disablereload","0")
00284     cp.set("system","showunloaded","0")
00285     cp.set("system","disableverification","0")
00286 
00287     return cp
00288 
00289   def isnumeric(self, str):
00290     """!\brief Determine whether the passed string is numeric.
00291 
00292     \return False if \a str is not numeric.
00293             True  if \a str is numeric.
00294     """
00295     return re.match('^[0-9]+$', str) is not None
00296 
00297 
00298   def setOperator(self, operator):
00299     """!\brief Set the current operator and update the configuration file.
00300 
00301     \param operator Operator name
00302     """
00303     operator = str(operator).strip()
00304     if operator == 'NOT-DEFINED':
00305       self.setPref("operator", operator)
00306       self.setPref("userid", '000')
00307     else:
00308       user = self.__prefs["users"].getUserByName(operator)
00309       self.setPref("operator", user.getName())
00310       self.setPref("operatorobj", user)
00311       self.setPref("userid", user.getId())
00312       self.writeConfig()
00313 
00314   def setParticleType(self, particleType):
00315     """!\brief Set the particle type and update the configuration file.
00316 
00317     \param particleType Particle type
00318     """
00319     self.setPref("lastparticletype", str(particleType))
00320     if particleType != 'NOT-DEFINED':
00321       self.writeConfig()
00322 
00323   def setOrientation(self, orientation):
00324     """!\brief Set the orientatino and update the configuration file.
00325 
00326     \param orientation Orientation
00327     """
00328     self.setPref("lastorientation", str(orientation))
00329     if orientation != 'NOT-DEFINED':
00330       self.writeConfig()
00331 
00332   def setSite(self, site):
00333     """!\brief Set the site and update the configuration file.
00334 
00335     \param site Site
00336     """
00337     self.setPref("lastsite", str(site))
00338     if site != 'NOT-DEFINED':
00339       self.writeConfig()
00340 
00341   def setPhase(self, phase):
00342     """!\brief Set the phase and update the configuration file.
00343 
00344     \param phase Phase
00345     """
00346     self.setPref("lastphase", str(phase))
00347     if phase != 'NOT-DEFINED':
00348       self.writeConfig()
00349 
00350   def setInstrumentType(self, instrumentType):
00351     """!\brief Set the instrument type and update the configuration file.
00352 
00353     \param instrumentType Instrument type
00354     """
00355     self.setPref("lastinstrumenttype", str(instrumentType))
00356     if instrumentType != 'NOT-DEFINED':
00357       self.writeConfig()
00358 
00359 
00360   def userId(self):
00361     """!\brief Get the user id.
00362 
00363     """
00364     if self.__prefs.has_key("userid"):
00365       return int(self.__prefs["userid"])
00366     else:
00367       return 1234
00368 
00369 
00370 class Preferences(dict):
00371   """!\brief Preferences dictionary.
00372 
00373   Preferences needs a special dictionary class since the data it stores
00374   may have macros and environment variables in it.
00375 
00376   In order to read the values unprocessed use the self.__prefs.get(item)
00377   method. If you need to resolve all the macros and environment variables
00378   then access it like any other dictionary (self.__prefs[item])
00379 
00380   """
00381   ROOT_DIR_ENVS = ['ONLINE_ROOT']
00382 
00383   DIR_LIST = ("reposdir", "appdir", "datadir",
00384                 "logdir", "reportdir",
00385                 "snapshotdir", "exportdir", "runiddir")
00386 
00387   CHOICE_LIST = ("datasave", "dataexport",
00388                  "snapnbl", "versionnbl", "elognbl")
00389 
00390   LOGGING_LIST = ("lognbl", "loglevel", "loghost", "logport")
00391 
00392   SYSTEM_LIST = ("pythonpath", "elogurl", "server", "servernbl",
00393                  "fontfamily", "fontsize", "fontweight", "fontitalic",
00394                  "style", "preload", "dontreload", "disablereload",
00395                  "showunloaded", "disableverification")
00396 
00397   LAST_ITEMS = ("lastuser", "lastsite", "lastorientation", "lastparticletype",
00398                 "lastinstrumenttype", "lastphase")
00399 
00400   TREAT_AS_INT = ("datasave", "dataexport",
00401                  "snapnbl", "versionnbl", "elognbl", "lognbl", "servernbl",
00402                  "disablereload", "showunloaded", "logport", "disableverification")
00403 
00404   EXCLUDED_DICTS = ("hwConfig")
00405 
00406   def __init__(self):
00407     """!\brief Preferences constructor.
00408 
00409     """
00410     dict.__init__(self)
00411     self.__saveLastItem = {}
00412 
00413   def __getitem__(self, item):
00414     """!\brief Overridden method to process the item before returning it.
00415 
00416     \param item Preference item
00417     """
00418     value = dict.__getitem__(self, item)
00419     if self.isDir(item):
00420       return self.expandVars(value)
00421     elif self.isNumber(item):
00422       return int(value)
00423     else:
00424       return value
00425 
00426   def __setitem__(self, item, value):
00427     """!\brief Overridden method to set the last item.
00428 
00429     \param item  Preference item
00430     \param value Preference value
00431     """
00432     if self.isLastItem(item) and value != 'NOT-DEFINED':
00433       self.__saveLastItem[item] = value
00434     dict.__setitem__(self, item, value)
00435 
00436   def isDir(self, item):
00437     """!\brief Is the item a path preference?
00438 
00439     \param item Preference item
00440     """
00441     return item in Preferences.DIR_LIST
00442 
00443   def isNumber(self, item):
00444     """!\brief Is the item a numeric preference?
00445 
00446     \param item Preference item
00447     """
00448     return item in Preferences.TREAT_AS_INT
00449 
00450   def isLastItem(self, item):
00451     """!\brief Is the preference item a last item?
00452 
00453     \param item Preference item
00454     """
00455     return item in Preferences.LAST_ITEMS
00456 
00457   def expandVars(self, path):
00458     """!\brief Expand the environment variables and macros in path.
00459 
00460     \param path Path preference value
00461     """
00462     p = os.path.expandvars(path)
00463     dirs = os.path.normpath(p).split(os.sep)
00464     i = 0
00465     for d in dirs:
00466       if d.startswith('@') and d[1:] in dict.keys(self):
00467         dirs[i] = dict.get(self,d[1:])
00468 
00469       if d.startswith('@') and d[1:] in dict.keys(self):
00470         if d[1:] == 'lastinstrumenttype':
00471           dirs[i] = dict.get(self,'instrument type')[dict.get(self,d[1:])]
00472         else:
00473           dirs[i] = dict.get(self,d[1:])
00474 
00475       i+=1
00476     if not dirs[0].endswith(os.sep):
00477       dirs[0]+=os.sep
00478     return reduce(os.path.join, dirs)
00479 
00480   def composePath(self, path):
00481     """!\brief Convert the path value back to its macro form.
00482 
00483     \param path Path preference value
00484     """
00485     for env in Preferences.ROOT_DIR_ENVS:
00486       if env in os.environ:
00487         if os.path.normpath(path).lower().startswith(os.path.normpath(os.environ[env]).lower() + os.sep):
00488           return '$' + env + path[len(os.environ[env]):]
00489     return path
00490 
00491   def getLastItem(self, item):
00492     """!\brief Retrieve the last item for the preference.
00493 
00494     \param item Preference item
00495     """
00496     if item in self.__saveLastItem:
00497       return self.__saveLastItem[item]

Generated on Thu Apr 27 20:52:43 2006 for LICOS L02-01-00 by doxygen 1.4.6-NO