00001 '''
00002 Created on Jun 27, 2011
00003
00004 @author: mplajner
00005 '''
00006 import xmlModule
00007 import os
00008 import platform
00009 from time import gmtime, strftime
00010 import Variable
00011
00012 class Environment():
00013 '''object to hold settings of environment'''
00014
00015 def __init__(self, loadFromSystem = True, useAsWriter=False, reportLevel = 1):
00016 '''Initial variables to be pushed and setup
00017
00018 append switch between append and prepend for initial variables.
00019 loadFromSystem causes variable`s system value to be loaded on first encounter.
00020 If useAsWriter == True than every change to variables is recorded to XML file.
00021 reportLevel sets the level of messaging.
00022 **kwargs contain initial variables.
00023 '''
00024 self.report = xmlModule.Report(reportLevel)
00025
00026 if platform.system() != 'Linux':
00027 self.sysSeparator = ';'
00028 else:
00029 self.sysSeparator = ':'
00030 self.separator = ':'
00031
00032 self.posActions = ['append','prepend','set','unset','remove', 'remove-regexp', 'declare']
00033 self.variables = {}
00034 self.loadFromSystem = loadFromSystem
00035 self.asWriter = useAsWriter
00036 if useAsWriter:
00037 self.writer = xmlModule.XMLFile()
00038 self.startXMLinput()
00039
00040
00041 def vars(self, strings=True):
00042 '''returns dictionary of all variables optionally converted to string'''
00043 if strings:
00044 vars = self.variables.copy()
00045 for item in vars:
00046 vars[item] = self.var(item).value(True)
00047 return vars
00048 else:
00049 return self.variables
00050
00051
00052 def var(self, name):
00053 '''Gets a single variable. If not available then tries to load from system.'''
00054 if name in self.variables.keys():
00055 return self.variables[name]
00056 else:
00057 self._loadFromSystem(name, '', 'append')
00058 return self.variables[name]
00059
00060
00061 def search(self, varName, expr, regExp = False):
00062 '''Searches in a variable for a value.'''
00063 return self.variables[varName].search(expr, regExp)
00064
00065
00066 def append(self, name, value):
00067 '''Appends to an existing variable.'''
00068 if self.asWriter:
00069 self._writeVarToXML(name, 'append', value)
00070 else:
00071 if name in self.variables.keys():
00072 self.variables[name].append(value, self.separator, self.variables)
00073 else:
00074 self.declare(name, 'list', False)
00075 self.append(name, value)
00076
00077
00078 def prepend(self, name, value):
00079 '''Prepends to an existing variable, or create a new one.'''
00080 if self.asWriter:
00081 self._writeVarToXML(name, 'prepend', value)
00082 else:
00083 if name in self.variables.keys():
00084 self.variables[name].prepend(value, self.separator, self.variables)
00085 else:
00086 self.declare(name, 'list', False)
00087 self.prepend(name, value)
00088
00089 def declare(self, name, type, local):
00090 '''Creates an instance of new variable. It loads values from the OS if the variable is not local.'''
00091 if self.asWriter:
00092 self._writeVarToXML(name, 'declare', '', type, local)
00093
00094 if not isinstance(local, bool):
00095 if str(local).lower() == 'true':
00096 local = True
00097 else:
00098 local = False
00099
00100 if name in self.variables.keys():
00101 if self.variables[name].local != local:
00102 raise Variable.EnvironmentError(name, 'redeclaration')
00103 else:
00104 if type.lower() == "list":
00105 if not isinstance(self.variables[name],Variable.List):
00106 raise Variable.EnvironmentError(name, 'redeclaration')
00107 else:
00108 if not isinstance(self.variables[name],Variable.Scalar):
00109 raise Variable.EnvironmentError(name, 'redeclaration')
00110
00111 if type.lower() == "list":
00112 a = Variable.List(name, local, report=self.report)
00113 else:
00114 a = Variable.Scalar(name, local, report=self.report)
00115
00116 if self.loadFromSystem and not local:
00117 if name in os.environ.keys():
00118 a.set(os.environ[name], self.sysSeparator, environment=self.variables, resolve=False)
00119 self.variables[name] = a
00120
00121 def set(self, name, value):
00122 '''Sets a single variable - overrides any previous value!'''
00123 name = str(name)
00124 if self.asWriter:
00125 self._writeVarToXML(name, 'set', value)
00126 else:
00127 if name in self.variables:
00128 self.variables[name].set(value, self.separator, self.variables)
00129 else:
00130 self.declare(name, 'list', False)
00131 self.set(name, value)
00132
00133
00134 def searchFile(self, file, varName):
00135 '''Searches for appearance of variable in a file.'''
00136 XMLFile = xmlModule.XMLFile()
00137 variable = XMLFile.variable(file, name=varName)
00138 return variable
00139
00140
00141 def unset(self, name, value=None):
00142 '''Unsets a single variable to an empty value - overrides any previous value!'''
00143 if self.asWriter:
00144 self._writeVarToXML(name, 'unset', '')
00145 else:
00146 if name in self.variables:
00147 self.variables[name].set([], self.separator)
00148 else:
00149 a = Variable.List(name, report=self.report)
00150 self.variables[name] = a
00151
00152
00153 def remove(self, name, value, regexp=False):
00154 '''Remove value from variable.'''
00155 if self.asWriter:
00156 self._writeVarToXML(name, 'remove', value)
00157 else:
00158 if name in self.variables:
00159 self.variables[name].remove(value, self.separator, regexp)
00160 elif self.loadFromSystem:
00161 self.declare(name, 'list', False)
00162
00163
00164 def remove_regexp(self, name, value):
00165 self.remove(name, value, True)
00166
00167 def loadXML(self, fileName = None, namespace = 'EnvSchema'):
00168 '''Loads XML file for input variables.'''
00169 XMLfile = xmlModule.XMLFile()
00170 variables = XMLfile.variable(fileName, namespace = namespace)
00171 i = 0
00172 for variable in variables:
00173 i += 1
00174 if variable[1] not in self.posActions:
00175 self.report.addError('Node '+str(i)+': No action taken with var "' + variable[0] + '". Probably wrong action argument: "'+variable[1]+'".')
00176 elif variable[1] == 'declare':
00177 self.declare(str(variable[0]), str(variable[2]), variable[3])
00178 else:
00179 if variable[1] == 'remove-regexp':
00180 variable[1] = 'remove_regexp'
00181 eval('self.'+variable[1]+'(str(variable[0]), str(variable[2]))')
00182
00183
00184 def startXMLinput(self):
00185 '''Renew writer for new input.'''
00186 self.writer.resetWriter()
00187
00188
00189 def finishXMLinput(self, outputFile = ''):
00190 '''Finishes input of XML file and closes the file.'''
00191 self.writer.writeToFile(outputFile)
00192
00193
00194 def writeToFile(self, fileName, shell='sh'):
00195 '''Creates an output file with a specified name to be used for setting variables by sourcing this file'''
00196 f = open(fileName, 'w')
00197 if shell == 'sh':
00198 f.write('#!/bin/bash\n')
00199 for variable in self.variables:
00200 if not self[variable].local:
00201 f.write('export ' +variable+'='+self[variable].value(True, self.sysSeparator)+'\n')
00202 elif shell == 'csh':
00203 f.write('#!/bin/csh\n')
00204 for variable in self.variables:
00205 if not self[variable].local:
00206 f.write('setenv ' +variable+' '+self[variable].value(True, self.sysSeparator)+'\n')
00207 else:
00208 f.write('')
00209 f.write('REM This is an enviroment settings file generated on '+strftime("%a, %d %b %Y %H:%M:%S\n", gmtime()))
00210 for variable in self.variables:
00211 if not self[variable].local:
00212 f.write('set '+variable+'='+self[variable].value(True, self.sysSeparator)+'\n')
00213
00214 f.close()
00215
00216
00217 def writeToXMLFile(self, fileName):
00218 '''Writes the current state of environment to a XML file.
00219
00220 NOTE: There is no trace of actions taken, variables are written with a set action only.
00221 '''
00222 writer = xmlModule.XMLFile()
00223 for var in self.variables.keys():
00224 writer.writeVar(var, 'set', self.variables[var].value(True, self.separator))
00225 writer.writeToFile(fileName)
00226
00227
00228 def loadAllSystemVariables(self):
00229 '''Loads all variables from the current system settings.'''
00230 for val in os.environ.keys():
00231 if not val in self.variables.keys():
00232 self.declare(val, 'list', False)
00233
00234
00235 def _concatenate(self, value):
00236 '''Returns a variable string with separator separator from the values list'''
00237 stri = ""
00238 for it in value:
00239 stri += it + self.separator
00240 stri = stri[0:len(stri)-1]
00241 return stri
00242
00243
00244 def _writeVarToXML(self, name, action, value, type='list', local='false'):
00245 '''Writes single variable to XML file.'''
00246 if isinstance(value, list):
00247 value = self._concatenate(value)
00248 self.writer.writeVar(name, action, value, type, local)
00249
00250
00251 def __getitem__(self, key):
00252 return self.variables[key]
00253
00254 def __setitem__(self, key, value):
00255 if value in self.variables.keys():
00256 self.report.addWarn('Addition canceled because of duplicate entry. Var: "' + self.varName + '" value: "' + value + '".')
00257 else:
00258 self.append(key, value)
00259
00260 def __delitem__(self, key):
00261 del self.variables[key]
00262
00263 def __iter__(self):
00264 for i in self.variables:
00265 yield i
00266
00267 def __contains__(self, item):
00268 return item in self.variables.keys()
00269
00270 def __len__(self):
00271 return len(self.variables.keys())
00272