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.actions = {}
00033 self.actions['append'] = lambda n, v, _: self.append(n, v)
00034 self.actions['prepend'] = lambda n, v, _: self.prepend(n, v)
00035 self.actions['set'] = lambda n, v, _: self.set(n, v)
00036 self.actions['unset'] = lambda n, v, _: self.unset(n, v)
00037 self.actions['remove'] = lambda n, v, _: self.remove(n, v)
00038 self.actions['remove-regexp'] = lambda n, v, _: self.remove_regexp(n, v)
00039 self.actions['declare'] = self.declare
00040
00041 self.variables = {}
00042 self.loadFromSystem = loadFromSystem
00043 self.asWriter = useAsWriter
00044 if useAsWriter:
00045 self.writer = xmlModule.XMLFile()
00046 self.startXMLinput()
00047
00048
00049 def vars(self, strings=True):
00050 '''returns dictionary of all variables optionally converted to string'''
00051 if strings:
00052 vars = self.variables.copy()
00053 for item in vars:
00054 vars[item] = self.var(item).value(True)
00055 return vars
00056 else:
00057 return self.variables
00058
00059
00060 def var(self, name):
00061 '''Gets a single variable. If not available then tries to load from system.'''
00062 if name in self.variables.keys():
00063 return self.variables[name]
00064 else:
00065 self._loadFromSystem(name, '', 'append')
00066 return self.variables[name]
00067
00068
00069 def search(self, varName, expr, regExp = False):
00070 '''Searches in a variable for a value.'''
00071 return self.variables[varName].search(expr, regExp)
00072
00073
00074 def append(self, name, value):
00075 '''Appends to an existing variable.'''
00076 if self.asWriter:
00077 self._writeVarToXML(name, 'append', value)
00078 else:
00079 if name in self.variables.keys():
00080 self.variables[name].append(value, self.separator, self.variables)
00081 else:
00082 self.declare(name, 'list', False)
00083 self.append(name, value)
00084
00085
00086 def prepend(self, name, value):
00087 '''Prepends to an existing variable, or create a new one.'''
00088 if self.asWriter:
00089 self._writeVarToXML(name, 'prepend', value)
00090 else:
00091 if name in self.variables.keys():
00092 self.variables[name].prepend(value, self.separator, self.variables)
00093 else:
00094 self.declare(name, 'list', False)
00095 self.prepend(name, value)
00096
00097 def declare(self, name, type, local):
00098 '''Creates an instance of new variable. It loads values from the OS if the variable is not local.'''
00099 if self.asWriter:
00100 self._writeVarToXML(name, 'declare', '', type, local)
00101
00102 if not isinstance(local, bool):
00103 if str(local).lower() == 'true':
00104 local = True
00105 else:
00106 local = False
00107
00108 if name in self.variables.keys():
00109 if self.variables[name].local != local:
00110 raise Variable.EnvironmentError(name, 'redeclaration')
00111 else:
00112 if type.lower() == "list":
00113 if not isinstance(self.variables[name],Variable.List):
00114 raise Variable.EnvironmentError(name, 'redeclaration')
00115 else:
00116 if not isinstance(self.variables[name],Variable.Scalar):
00117 raise Variable.EnvironmentError(name, 'redeclaration')
00118
00119 if type.lower() == "list":
00120 a = Variable.List(name, local, report=self.report)
00121 else:
00122 a = Variable.Scalar(name, local, report=self.report)
00123
00124 if self.loadFromSystem and not local:
00125 if name in os.environ.keys():
00126 a.set(os.environ[name], self.sysSeparator, environment=self.variables, resolve=False)
00127 self.variables[name] = a
00128
00129 def set(self, name, value):
00130 '''Sets a single variable - overrides any previous value!'''
00131 name = str(name)
00132 if self.asWriter:
00133 self._writeVarToXML(name, 'set', value)
00134 else:
00135 if name in self.variables:
00136 self.variables[name].set(value, self.separator, self.variables)
00137 else:
00138 self.declare(name, 'list', False)
00139 self.set(name, value)
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
00168 def searchFile(self, file, varName):
00169 '''Searches for appearance of variable in a file.'''
00170 XMLFile = xmlModule.XMLFile()
00171 variable = XMLFile.variable(file, name=varName)
00172 return variable
00173
00174 def loadXML(self, fileName = None, namespace = 'EnvSchema'):
00175 '''Loads XML file for input variables.'''
00176 XMLfile = xmlModule.XMLFile()
00177 variables = XMLfile.variable(fileName, namespace = namespace)
00178 for i, (action, args) in enumerate(variables):
00179 if action not in self.actions:
00180 self.report.addError('Node {0}: No action taken with var "{1}". Probably wrong action argument: "{2}".'.format(i, args[0], action))
00181 else:
00182 self.actions[action](*args)
00183
00184
00185 def startXMLinput(self):
00186 '''Renew writer for new input.'''
00187 self.writer.resetWriter()
00188
00189
00190 def finishXMLinput(self, outputFile = ''):
00191 '''Finishes input of XML file and closes the file.'''
00192 self.writer.writeToFile(outputFile)
00193
00194
00195 def writeToFile(self, fileName, shell='sh'):
00196 '''Creates an output file with a specified name to be used for setting variables by sourcing this file'''
00197 f = open(fileName, 'w')
00198 if shell == 'sh':
00199 f.write('#!/bin/bash\n')
00200 for variable in self.variables:
00201 if not self[variable].local:
00202 f.write('export ' +variable+'='+self[variable].value(True, self.sysSeparator)+'\n')
00203 elif shell == 'csh':
00204 f.write('#!/bin/csh\n')
00205 for variable in self.variables:
00206 if not self[variable].local:
00207 f.write('setenv ' +variable+' '+self[variable].value(True, self.sysSeparator)+'\n')
00208 else:
00209 f.write('')
00210 f.write('REM This is an enviroment settings file generated on '+strftime("%a, %d %b %Y %H:%M:%S\n", gmtime()))
00211 for variable in self.variables:
00212 if not self[variable].local:
00213 f.write('set '+variable+'='+self[variable].value(True, self.sysSeparator)+'\n')
00214
00215 f.close()
00216
00217
00218 def writeToXMLFile(self, fileName):
00219 '''Writes the current state of environment to a XML file.
00220
00221 NOTE: There is no trace of actions taken, variables are written with a set action only.
00222 '''
00223 writer = xmlModule.XMLFile()
00224 for var in self.variables.keys():
00225 writer.writeVar(var, 'set', self.variables[var].value(True, self.separator))
00226 writer.writeToFile(fileName)
00227
00228
00229 def loadAllSystemVariables(self):
00230 '''Loads all variables from the current system settings.'''
00231 for val in os.environ.keys():
00232 if not val in self.variables.keys():
00233 self.declare(val, 'list', False)
00234
00235
00236 def _concatenate(self, value):
00237 '''Returns a variable string with separator separator from the values list'''
00238 stri = ""
00239 for it in value:
00240 stri += it + self.separator
00241 stri = stri[0:len(stri)-1]
00242 return stri
00243
00244
00245 def _writeVarToXML(self, name, action, value, type='list', local='false'):
00246 '''Writes single variable to XML file.'''
00247 if isinstance(value, list):
00248 value = self._concatenate(value)
00249 self.writer.writeVar(name, action, value, type, local)
00250
00251
00252 def __getitem__(self, key):
00253 return self.variables[key]
00254
00255 def __setitem__(self, key, value):
00256 if value in self.variables.keys():
00257 self.report.addWarn('Addition canceled because of duplicate entry. Var: "' + self.varName + '" value: "' + value + '".')
00258 else:
00259 self.append(key, value)
00260
00261 def __delitem__(self, key):
00262 del self.variables[key]
00263
00264 def __iter__(self):
00265 for i in self.variables:
00266 yield i
00267
00268 def __contains__(self, item):
00269 return item in self.variables.keys()
00270
00271 def __len__(self):
00272 return len(self.variables.keys())
00273