diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 5603b27..0bb3aff 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -82,12 +82,13 @@ class _terms(_error): elemA[i] = "0" + elemA[i] return (".".join(elemA), ".".join(elemB)) - def _equalTerm(self, term, textError): + def _equalTerm(self, term, textError, function=False): """Вычисление логических выражений для условий Для корректной работы в классе который наследует этот класс должен быть объявлен аттрибут self.objVar (объект для работы с переменными) + function - функция для для обработки функций в заголовке блока """ trm = {"&":" and ","||":" or "} rule = ["==", "!=", ">=", "<=", ">", "<"] @@ -118,25 +119,46 @@ class _terms(_error): listEqual.append(k) else: #проверка на допустимость названия переменной - reDenyName = re.compile("[^a-zA-Z0-9_-]") + reDenyName = re.compile("[^a-zA-Z0-9\_\-]") + flagFunction = False if reDenyName.search(vals[0]): - self.setError("'%s'"%term + " " + _("incorrect")) - self.setError(textError) - return False - #проверка на допустимость значения значения + #проверка на допустимость функции + flagError = True + if function: + reFunction = re.compile(\ + "([a-zA-Z0-9\_\-]+)\([a-zA-Z0-9_\-\+\,\*\/\.]+\)") + searchFunct = reFunction.search(vals[0]) + if searchFunct: + flagError = False + flagFunction = True + if flagError: + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError(textError) + return False + #проверка на допустимость значения reDenyValue = re.compile("[^0-9a-zA-Z_\.-]") if reDenyValue.search(vals[1]): self.setError("'%s'"%term + " " + _("incorrect")) self.setError(textError) return False - try: - valVars = self.objVar.Get(vals[0]) - except self.objVar.DataVarsError, e: - print textError - print e - exit(1) + if flagFunction: + valVars = function("#-%s-#"%vals[0]) + if valVars == "": + flagFunction = False + if valVars == False: + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError(textError) + return False + else: + try: + valVars = self.objVar.Get(vals[0]) + except self.objVar.DataVarsError, e: + print textError + print e + exit(1) # Cравниваем номера версий - if "_ver" in vals[0]: + if "_ver" in vals[0] or \ + (flagFunction and "pkg" == searchFunct.group(1)): verFile, verVar = self._convertVers(vals[1],valVars) exec("res=("+"'"+verVar+"'"+sepF+"'"+verFile+"'"+")") if res: @@ -177,9 +199,13 @@ class _terms(_error): else: listEqual.append("0") else: - self.setError("'%s'"%term + " " + _("incorrect")) - self.setError (textError) - return False + if valVars == "": + listEqual.append("0") + else: + self.setError("'%s'"%term + " "\ + + _("incorrect")) + self.setError (textError) + return False exec("res=(%s)"%("".join(listEqual))) return res @@ -2051,8 +2077,9 @@ class profile(_file, _terms): self._deltVarEnd = len(varEnd) # Условия self._reTermBloc = re.compile("#\?(?P[a-zA-Z0-9\-_]+)\ +(?P\([a-zA-Z0-9_\-\+\,\*\/\.]+\))?\ (?P[\>\<\=\!\&\|]+\ -[a-zA-Z0-9\>\<\=\!\|\&\-_\.]*)#\ +[a-zA-Z0-9\>\<\=\!\|\&\-\+\*\/_\.\,\(\)]*)#\ \n*(?P.+?)\n*#(?P=rTerm)#(?P[ ,\t]*\n?)",re.M|re.S) # Объект с переменными self.objVar = objVar @@ -2064,6 +2091,11 @@ class profile(_file, _terms): self._baseDir = "" # Последняя часть директории профиля (имя сервиса: samba, mail) self._servDir = servDir + # Имена установленных программ + self.installProg = [] + # Версии установленных программ + self.installProgVersions = [] + if self._servDir: if self._servDir[0] != "/": self._servDir = "/" + self._servDir @@ -2219,6 +2251,62 @@ class profile(_file, _terms): textProfileTmp[resS.end():] return textProfileTmp + def getInstallPkgGentoo(): + """Выдает два списка, инсталлированные программы и номера версий""" + baseDir = "/var/db/pkg" + pkgs = [] + reVer = re.compile("(?<=\-)\d+\.?\d*\.?\d*") + def getFilesDir(pkgs, dirname, names): + for nameFile in names: + absNameFile = os.path.join(dirname,nameFile) + if os.path.isdir(absNameFile): + tail = absNameFile.split(baseDir) + if len(tail)==2: + tail = tail[1].split('/') + if len(tail)==3 and tail[1]!='virtual': + pkgs.append(tail[2]) + return True + os.path.walk(baseDir,getFilesDir, pkgs) + pkgs.sort() + names = [] + versions = [] + for pkg in pkgs: + findVer = reVer.search(pkg) + if findVer: + ver = findVer.group() + versions.append(ver) + names.append(pkg.split(ver)[0][:-1]) + #return pkgs + return names, versions + + def pkg(nameProg, names, versions): + """Выдает установленные версии по имени программы""" + i = 0 + vers = [] + for name in names: + if nameProg == name: + while nameProg == names[i]: + vers.append(versions[i]) + i += 1 + break + i += 1 + if vers: + return vers[-1] + else: + return "" + + def funcPkg(funTxt,resS,textProfileTmp): + """локальная функция выдает номер версии программы""" + terms = funTxt[4:-1].replace(" ","") + # Название программы + nameProg = terms + if not self.installProg: + self.installProg,self.installProgVersions=getInstallPkgGentoo() + replace = pkg(nameProg,self.installProg,self.installProgVersions) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + # Локальные переменные localVars = {} # Локальные переменные для функции load @@ -2240,27 +2328,50 @@ class profile(_file, _terms): elif funTxt[:5] == "load(": textProfileTmp = funcLoad(resS,localVarsLoad,textProfileTmp) resS = self._reFunc.search(textProfileTmp) + elif funTxt[:4] == "pkg(": + textProfileTmp = funcPkg(funTxt,resS,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) else: resS = False return textProfileTmp - def applyTermsProfile(self, textProfile, nameProfile): + def applyTermsProfile(self, textProfile, nameProfile, nameSystemFile=False): """ Применяет условия, к условным блокам текста """ textTerm = "" resS = self._reTermBloc.search(textProfile) textProfileTmp = textProfile - while resS: - mark = resS.group(0) - body = resS.group("body") - end = resS.group("end") - term = resS.group("rTerm") + resS.group("lTerm") - if self._equalTerm(term, _("content profile not valid: ")+\ - nameProfile): - textProfileTmp = textProfileTmp.replace(mark, body+end) - else: - textProfileTmp = textProfileTmp.replace(mark, "") - resS = self._reTermBloc.search(textProfileTmp) + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, nameProfile, nameSystemFile) + if nameSystemFile: + while resS: + mark = resS.group(0) + body = resS.group("body") + end = resS.group("end") + parent = resS.group("func") + if not parent: + parent = "" + term = resS.group("rTerm") + parent +\ + resS.group("lTerm") + if self._equalTerm(term, _("content profile not valid: ")+\ + nameProfile, function): + textProfileTmp = textProfileTmp.replace(mark, body+end) + else: + textProfileTmp = textProfileTmp.replace(mark, "") + resS = self._reTermBloc.search(textProfileTmp) + else: + while resS: + mark = resS.group(0) + body = resS.group("body") + end = resS.group("end") + term = resS.group("rTerm") + resS.group("lTerm") + if self._equalTerm(term, _("content profile not valid: ")+\ + nameProfile): + textProfileTmp = textProfileTmp.replace(mark, body+end) + else: + textProfileTmp = textProfileTmp.replace(mark, "") + resS = self._reTermBloc.search(textProfileTmp) return textProfileTmp def getNeedProfile(self, fileProfile): @@ -2586,7 +2697,7 @@ class profile(_file, _terms): if self.getFileType() != "bin": # Вычисляем условные блоки self.newProfile = self.applyTermsProfile(self.newProfile, - newFile) + newFile, oldFile) #print "|%s|" %(self.newProfile) # Заменяем переменные на их значения self.newProfile = self.applyVarsProfile(self.newProfile, @@ -4285,7 +4396,8 @@ class plasma(samba): for h in blocs[0]: if not h: if blocs[1][z] == "": - fieldsTmp.append("\n") + fieldsTmp.append("") + #fieldsTmp.append("\n") else: fieldsTmp.append(blocs[1][z]) #print '"' + blocs[1][z] + '"' @@ -4502,8 +4614,8 @@ class plasma(samba): rootNode.appendChild(fieldXMLBr) else: - #if not i: - #continue + if not i: + continue fields = self.splitToFields(i) for field in fields: if field.name != False: