|
|
|
@ -37,7 +37,7 @@ from operator import lt, le, eq, ne, ge, gt
|
|
|
|
|
|
|
|
|
|
from utils.common import _error, _warning
|
|
|
|
|
from utils.text import _toUNICODE, convertStrListDict
|
|
|
|
|
from utils.portage import isPkgInstalled
|
|
|
|
|
from utils.portage import isPkgInstalled,reVerSplitToPV
|
|
|
|
|
from utils.content import PkgContents
|
|
|
|
|
from utils.files import (getModeFile, listDirectory,removeDir, typeFile,
|
|
|
|
|
scanDirectory,
|
|
|
|
@ -47,7 +47,28 @@ from datavars import DataVarsError
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
|
|
|
setLocalTranslate('cl_lib3',sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
class TemplatesError(Exception):
|
|
|
|
|
class TemplatesInterrupt(Exception):
|
|
|
|
|
"""
|
|
|
|
|
Interrupt templates appling
|
|
|
|
|
"""
|
|
|
|
|
EXIT,ABORT=1,2
|
|
|
|
|
|
|
|
|
|
def __init__(self,*args):
|
|
|
|
|
self.message = args[0]
|
|
|
|
|
self.args = args
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return str(self.message)
|
|
|
|
|
|
|
|
|
|
def isExit(self): return self.isInterrupt() and self.args[1] == self.EXIT
|
|
|
|
|
|
|
|
|
|
def isAbort(self): return self.isInterrupt() and self.args[1] == self.ABORT
|
|
|
|
|
|
|
|
|
|
def status(self): return self.args[1] if self.isInterrupt() else 0
|
|
|
|
|
|
|
|
|
|
def isInterrupt(self): return len(self.args)>1
|
|
|
|
|
|
|
|
|
|
class TemplatesError(TemplatesInterrupt):
|
|
|
|
|
"""
|
|
|
|
|
Error on templates appling
|
|
|
|
|
"""
|
|
|
|
@ -2186,7 +2207,7 @@ class _file(_error):
|
|
|
|
|
except:
|
|
|
|
|
try:
|
|
|
|
|
if os.path.isdir(nameFileConfig):
|
|
|
|
|
self.setWarning(_("unable to open the directory as file:")
|
|
|
|
|
self.printWARNING(_("unable to open the directory as file:")
|
|
|
|
|
+ nameFileConfig)
|
|
|
|
|
return False
|
|
|
|
|
F_CONF = open(nameFileConfig, "w+")
|
|
|
|
@ -3016,6 +3037,101 @@ class templateFunction(_error, _warning, _shareTemplate, _shareTermsFunction):
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcPrint(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""
|
|
|
|
|
Вывод успешного сообщения
|
|
|
|
|
"""
|
|
|
|
|
self.printSUCCESS(_(funArgv))
|
|
|
|
|
textTemplateTmp = textTemplateTmp[:resS.start()] + \
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcWarning(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения с предупреждением
|
|
|
|
|
"""
|
|
|
|
|
self.printWARNING(_(funArgv))
|
|
|
|
|
textTemplateTmp = textTemplateTmp[:resS.start()] + \
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcError(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения с ошибкой
|
|
|
|
|
"""
|
|
|
|
|
self.printERROR(_(funArgv))
|
|
|
|
|
textTemplateTmp = textTemplateTmp[:resS.start()] + \
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcExit(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения с ошибкой
|
|
|
|
|
"""
|
|
|
|
|
self.printSUCCESS(_(funArgv))
|
|
|
|
|
raise TemplatesInterrupt(_("Applying was stop"),TemplatesInterrupt.EXIT)
|
|
|
|
|
|
|
|
|
|
def funcBreak(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения с ошибкой
|
|
|
|
|
"""
|
|
|
|
|
self.printERROR(_(funArgv))
|
|
|
|
|
raise TemplatesInterrupt(_("Applying was interrupted"),
|
|
|
|
|
TemplatesInterrupt.ABORT)
|
|
|
|
|
|
|
|
|
|
def getElogTimestamp(self):
|
|
|
|
|
# Получаем время модификации конфигурационного файла
|
|
|
|
|
curTime = self.getTimeFile(self.fileConfigIni)
|
|
|
|
|
nameLocVar = "update.timestamp"
|
|
|
|
|
if self.timeIni != curTime:
|
|
|
|
|
# читаем переменные из файла
|
|
|
|
|
self.prevDictIni = self.loadVarsIni(self.fileConfigIni)
|
|
|
|
|
self.currDictIni= {}
|
|
|
|
|
self.currDictIni.update(self.prevDictIni)
|
|
|
|
|
self.timeIni = self.getTimeFile(self.fileConfigIni)
|
|
|
|
|
if nameLocVar in self.currDictIni.keys():
|
|
|
|
|
if self.currDictIni[nameLocVar] is None:
|
|
|
|
|
return 0
|
|
|
|
|
else:
|
|
|
|
|
val = self.currDictIni[nameLocVar].encode("UTF-8")
|
|
|
|
|
if val.isdigit():
|
|
|
|
|
return int(val)
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def funcElog(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
"""Function for work with emerge.log"""
|
|
|
|
|
funArgv = funArgv.strip()
|
|
|
|
|
rePkg = re.compile(r'completed emerge \(\d+ of \d+\) (\S+)\s',re.S)
|
|
|
|
|
logFile = '/var/log/emerge.log'
|
|
|
|
|
replace = ""
|
|
|
|
|
if funArgv:
|
|
|
|
|
lastTimestamp = self.getElogTimestamp()
|
|
|
|
|
skip = True
|
|
|
|
|
for line in reversed(list(readLinesFile(logFile))):
|
|
|
|
|
timestamp,op,info = line.partition(':')
|
|
|
|
|
if timestamp.isdigit() and lastTimestamp and \
|
|
|
|
|
int(timestamp) < lastTimestamp:
|
|
|
|
|
break
|
|
|
|
|
match = rePkg.search(info)
|
|
|
|
|
if match and match.group(1).startswith(funArgv):
|
|
|
|
|
pkgInfo = reVerSplitToPV(match.group(1))
|
|
|
|
|
if "{CATEGORY}/{PN}".format(**pkgInfo) == funArgv:
|
|
|
|
|
replace = pkgInfo['PVR']
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
# get last timestamp
|
|
|
|
|
replace = readFile(logFile).rpartition(
|
|
|
|
|
'\n')[2].lpartition(':')[0]
|
|
|
|
|
textTemplateTmp = textTemplateTmp[:resS.start()] + replace + \
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcConfirm(self,funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
res = self.askConfirm(_(funArgv))
|
|
|
|
|
textTemplateTmp = textTemplateTmp[:resS.start()] + res + \
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def loadVarsIni(self, iniFileName):
|
|
|
|
|
""" Читает файл fileName
|
|
|
|
|
создает и заполняет переменные на основе этого файла
|
|
|
|
@ -3274,9 +3390,9 @@ class templateFunction(_error, _warning, _shareTemplate, _shareTermsFunction):
|
|
|
|
|
return textTemplateTmp
|
|
|
|
|
|
|
|
|
|
def funcBelong(self, funArgv, resS, localVars, textTemplateTmp, nameTemp):
|
|
|
|
|
self.setWarning(
|
|
|
|
|
_("Function '{funcname}' used by {template} is deprecated and will be removed in the future").format(
|
|
|
|
|
funcname="belong",template=nameTemp))
|
|
|
|
|
self.printWARNING(_("Function '{funcname}' used by {template} "
|
|
|
|
|
"is deprecated and will be removed in the future"
|
|
|
|
|
).format(funcname="belong",template=nameTemp))
|
|
|
|
|
replace = ""
|
|
|
|
|
return textTemplateTmp[:resS.start()] + replace +\
|
|
|
|
|
textTemplateTmp[resS.end():]
|
|
|
|
@ -3664,11 +3780,13 @@ class Template(_file,_terms,_warning,xmlShare,templateFormat,_shareTemplate):
|
|
|
|
|
def __init__(self, objVar, servDir=False, dirsFilter=[], filesFilter=[],
|
|
|
|
|
cltObj=True, cltFilter=True, printWarning=True,
|
|
|
|
|
printSUCCESS=lambda x:x,printWARNING=lambda x:x,
|
|
|
|
|
printERROR=lambda x:x):
|
|
|
|
|
printERROR=lambda x:x,askConfirm=lambda x:x):
|
|
|
|
|
self.changedFiles = ChangedFiles()
|
|
|
|
|
self.printSUCCESS = printSUCCESS
|
|
|
|
|
self.printERROR = printERROR
|
|
|
|
|
self.printWARNING = printWARNING
|
|
|
|
|
self.askConfirm = askConfirm
|
|
|
|
|
self.stop = 0
|
|
|
|
|
self.cltObj = None
|
|
|
|
|
self.functObj = None
|
|
|
|
|
# Предупреждения
|
|
|
|
@ -3730,6 +3848,7 @@ re.M|re.S)
|
|
|
|
|
self.functObj.printSUCCESS = self.printSUCCESS
|
|
|
|
|
self.functObj.printWARNING = self.printWARNING
|
|
|
|
|
self.functObj.printERROR = self.printERROR
|
|
|
|
|
self.functObj.askConfirm = self.askConfirm
|
|
|
|
|
# Метод применения функций к шаблонам
|
|
|
|
|
self.applyFuncTemplate = self.functObj.applyFuncTemplate
|
|
|
|
|
# Объект для определения типа файла шаблона
|
|
|
|
@ -3741,7 +3860,8 @@ re.M|re.S)
|
|
|
|
|
# Объект templateClt
|
|
|
|
|
self.cltObj = templateClt(self.objVar,printSUCCESS=self.printSUCCESS,
|
|
|
|
|
printERROR=self.printERROR,
|
|
|
|
|
printWARNING=self.printWARNING)
|
|
|
|
|
printWARNING=self.printWARNING,
|
|
|
|
|
askConfirm=self.askConfirm)
|
|
|
|
|
elif cltObj:
|
|
|
|
|
# Объект templateClt
|
|
|
|
|
self.cltObj = cltObj
|
|
|
|
@ -3797,18 +3917,18 @@ gettext -d cl_template "$*"
|
|
|
|
|
p.write(code)
|
|
|
|
|
p.pipe.stdin.close()
|
|
|
|
|
for line in p.readByLine():
|
|
|
|
|
self.printSUCCESS(line)
|
|
|
|
|
self.printSUCCESS(line.strip())
|
|
|
|
|
p.pipe.wait()
|
|
|
|
|
if p.success():
|
|
|
|
|
self.executedFiles.append((code,execPath))
|
|
|
|
|
if p.readerr():
|
|
|
|
|
for line in p.readerr().split('\n'):
|
|
|
|
|
self.printWARNING(line)
|
|
|
|
|
self.printWARNING(line.strip())
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
if p.readerr():
|
|
|
|
|
for line in p.readerr().split('\n'):
|
|
|
|
|
self.printERROR(line)
|
|
|
|
|
self.printERROR(line.strip())
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def __octToInt(self, strOct):
|
|
|
|
@ -4129,11 +4249,7 @@ gettext -d cl_template "$*"
|
|
|
|
|
if skipDirs or skipTemplates:
|
|
|
|
|
# print warning
|
|
|
|
|
from cl_print import color_print
|
|
|
|
|
printObj = color_print()
|
|
|
|
|
setWARNING = lambda x: self.setWarning(x) and\
|
|
|
|
|
self.printWarning and\
|
|
|
|
|
printObj.printWARNING(x)
|
|
|
|
|
setWARNING(_("No conditions for checking the value of variable"
|
|
|
|
|
self.printWARNING(_("No conditions for checking the value of variable"
|
|
|
|
|
" 'cl_name'"))
|
|
|
|
|
skipDirTemplates = []
|
|
|
|
|
for skipDir in skipDirs:
|
|
|
|
@ -4156,7 +4272,7 @@ gettext -d cl_template "$*"
|
|
|
|
|
setWARNING("# Calculate cl_name==calculate-install")
|
|
|
|
|
return skipDirs + skipTemplates
|
|
|
|
|
|
|
|
|
|
def applyTemplates(self,progress=True,execute=True):
|
|
|
|
|
def applyTemplates(self,progress=True,rerun=True):
|
|
|
|
|
"""Применяет шаблоны к конфигурационным файлам"""
|
|
|
|
|
|
|
|
|
|
def createDictTemplates(path, prefix, dictTemplates):
|
|
|
|
@ -4245,8 +4361,8 @@ gettext -d cl_template "$*"
|
|
|
|
|
for dirTemplate in dirsTemplatesExists:
|
|
|
|
|
if self.scanningTemplates(dirTemplate,
|
|
|
|
|
skipTemplates=skipTemplates) is False:
|
|
|
|
|
return False
|
|
|
|
|
if self.cltObj:
|
|
|
|
|
break
|
|
|
|
|
if self.cltObj and not self.stop:
|
|
|
|
|
# Созданные директории
|
|
|
|
|
self.cltObj.createdDirs = self.createdDirs
|
|
|
|
|
# Примененные файлы
|
|
|
|
@ -4279,11 +4395,19 @@ gettext -d cl_template "$*"
|
|
|
|
|
if not filename in self.cltObj.filterApplyTemplates:
|
|
|
|
|
self.cltObj.filterApplyTemplates[filename] = []
|
|
|
|
|
self.cltObj.filterApplyTemplates[filename].append(pkg)
|
|
|
|
|
if not self.cltObj.applyTemplates():
|
|
|
|
|
return False
|
|
|
|
|
if (self.objVar.Get('cl_merge_pkg') or \
|
|
|
|
|
for filename,pkgs in self.changedFiles.data.items():
|
|
|
|
|
if not filename in self.cltObj.filterApplyTemplates:
|
|
|
|
|
self.cltObj.filterApplyTemplates[filename] = []
|
|
|
|
|
pkgs = filter(lambda x:not x in \
|
|
|
|
|
self.cltObj.filterApplyTemplates[filename],
|
|
|
|
|
map(lambda x:x[0],pkgs))
|
|
|
|
|
self.cltObj.filterApplyTemplates[filename].extend(pkgs)
|
|
|
|
|
|
|
|
|
|
self.cltObj.applyTemplates()
|
|
|
|
|
self.stop = self.stop or self.cltObj.stop
|
|
|
|
|
if not self.stop and ((self.objVar.Get('cl_merge_pkg') or \
|
|
|
|
|
self.objVar.Get('cl_action') == "sync") and \
|
|
|
|
|
self.objVar.Get('cl_merge_pkg_new'):
|
|
|
|
|
self.objVar.Get('cl_merge_pkg_new')):
|
|
|
|
|
self.objVar.Set('cl_root_path',
|
|
|
|
|
self.objVar.Get('cl_root_path_next'),force=True)
|
|
|
|
|
self.recalculateBaseDir()
|
|
|
|
@ -4297,12 +4421,12 @@ gettext -d cl_template "$*"
|
|
|
|
|
createdDirs = self.createdDirs
|
|
|
|
|
filesApply = self.filesApply
|
|
|
|
|
self.changeMergePackage(self.objVar.Get('cl_merge_pkg'))
|
|
|
|
|
self.applyTemplates(execute=False)
|
|
|
|
|
self.applyTemplates(rerun=False)
|
|
|
|
|
createdDirs.extend(self.createdDirs)
|
|
|
|
|
filesApply.extend(self.filesApply)
|
|
|
|
|
self.filesApply = filesApply
|
|
|
|
|
self.createdDirs = createdDirs
|
|
|
|
|
if execute:
|
|
|
|
|
if rerun and self.stop != TemplatesInterrupt.ABORT:
|
|
|
|
|
if self.cltObj:
|
|
|
|
|
self.queueExecute.extend(self.cltObj.queueExecute)
|
|
|
|
|
for processor,text,nameTemplate in self.queueExecute:
|
|
|
|
@ -4372,8 +4496,12 @@ gettext -d cl_template "$*"
|
|
|
|
|
optNextDir)
|
|
|
|
|
if ret is False:
|
|
|
|
|
break
|
|
|
|
|
except TemplatesError as e:
|
|
|
|
|
self.printWARNING(str(e))
|
|
|
|
|
except TemplatesInterrupt as e:
|
|
|
|
|
if e.isInterrupt():
|
|
|
|
|
self.stop = e.status()
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.printWARNING(str(e))
|
|
|
|
|
finally:
|
|
|
|
|
self.objVar.defaultModule = prevModule
|
|
|
|
|
self.functObj.currentBelong = prevBelong
|
|
|
|
@ -4428,8 +4556,8 @@ gettext -d cl_template "$*"
|
|
|
|
|
if createdDirs:
|
|
|
|
|
self.createdDirs += createdDirs
|
|
|
|
|
if os.path.isfile(pathDir):
|
|
|
|
|
self.setWarning(_("{dirpath} is a file").format(dirpath=pathDir))
|
|
|
|
|
self.setWarning(_("templates in {tempath} are skipped"
|
|
|
|
|
self.printWARNING(_("{dirpath} is a file").format(dirpath=pathDir))
|
|
|
|
|
self.printWARNING(_("templates in {tempath} are skipped"
|
|
|
|
|
).format(tempath=path))
|
|
|
|
|
return None
|
|
|
|
|
if objHeadDir:
|
|
|
|
@ -5636,12 +5764,17 @@ class scanDirectoryClt:
|
|
|
|
|
self.filterApplyTemplates.keys() or self.hasBelong(absPath):
|
|
|
|
|
prevDefault = self.objVar.defaultModule
|
|
|
|
|
if not self.processingFile(absPath, prefix):
|
|
|
|
|
ret = False
|
|
|
|
|
return False
|
|
|
|
|
self.objVar.defaultModule = prevDefault
|
|
|
|
|
elif stat.S_ISDIR(statInfo):
|
|
|
|
|
ret = self.scanningTemplates(absPath, prefix, True)
|
|
|
|
|
except TemplatesError as e:
|
|
|
|
|
self.printWARNING(str(e))
|
|
|
|
|
if not self.scanningTemplates(absPath, prefix, True):
|
|
|
|
|
return False
|
|
|
|
|
except TemplatesInterrupt as e:
|
|
|
|
|
if e.isInterrupt():
|
|
|
|
|
self.stop = e.status()
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.printWARNING(str(e))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class templateClt(scanDirectoryClt, Template):
|
|
|
|
@ -5780,7 +5913,7 @@ class templateClt(scanDirectoryClt, Template):
|
|
|
|
|
# Обрабатываем шаблоны
|
|
|
|
|
for dirTemplate in dirsTemplates:
|
|
|
|
|
if self.scanningTemplates(dirTemplate, self._chrootDir) is False:
|
|
|
|
|
return False
|
|
|
|
|
break
|
|
|
|
|
return (self.createdDirs, self.filesApply)
|
|
|
|
|
|
|
|
|
|
class iniParser(_error, templateFormat):
|
|
|
|
|