|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
|
|
|
#
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
# You may obtain a copy of the License at
|
|
|
#
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
#
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
|
|
|
import re
|
|
|
import types
|
|
|
import copy
|
|
|
from calculate.lib.cl_xml import xpath, xmlDoc
|
|
|
from calculate.lib.cl_template import blocText
|
|
|
from calculate.lib.format.samba import samba
|
|
|
|
|
|
class PlasmaArea(object):
|
|
|
def __init__(self):
|
|
|
self.header = False
|
|
|
self.start = False
|
|
|
self.fields = []
|
|
|
self.end = ""
|
|
|
|
|
|
|
|
|
class plasmaBlocText(blocText):
|
|
|
def findBloc(self, text, captionTxtBloc, bodyTxtBloc):
|
|
|
""" Делит текст на блоки (с заголовками)
|
|
|
|
|
|
captionTxtBloc - регулярное выражение для заголовка блока
|
|
|
bodyTxtBloc - регулярное выражение для тела блока
|
|
|
возвращает два списка: первый - заголовки, второй - тела блоков
|
|
|
"""
|
|
|
# Заголовки блоков
|
|
|
headersTxt = []
|
|
|
# Тексты блоков
|
|
|
blocsTxt = []
|
|
|
r = captionTxtBloc.search(text)
|
|
|
if r:
|
|
|
headersTxt.append(r.group(0))
|
|
|
txtSpl = text.partition(r.group(0))
|
|
|
blocTxt = txtSpl[0]
|
|
|
txtWr = txtSpl[2]
|
|
|
rb = bodyTxtBloc.search(blocTxt)
|
|
|
if not blocTxt:
|
|
|
blocsTxt.append(blocTxt)
|
|
|
if rb:
|
|
|
blocsTxt.append(rb.group(0))
|
|
|
while r:
|
|
|
r = captionTxtBloc.search(txtWr)
|
|
|
if r:
|
|
|
headersTxt.append(r.group(0))
|
|
|
txtSpl = txtWr.partition(r.group(0))
|
|
|
blocTxt = txtSpl[0]
|
|
|
txtWr = txtSpl[2]
|
|
|
rb = bodyTxtBloc.search(blocTxt)
|
|
|
if rb:
|
|
|
blocsTxt.append(rb.group(0))
|
|
|
else:
|
|
|
blocsTxt.append(txtWr)
|
|
|
if headersTxt and blocsTxt:
|
|
|
if len(headersTxt) > len(blocsTxt):
|
|
|
blocsTxt.insert(0, "")
|
|
|
elif len(headersTxt) < len(blocsTxt):
|
|
|
headersTxt.insert(0, "")
|
|
|
if len(headersTxt) != len(blocsTxt):
|
|
|
return False
|
|
|
return headersTxt, blocsTxt
|
|
|
else:
|
|
|
return False
|
|
|
|
|
|
|
|
|
class xmlDocPlasma(xmlDoc):
|
|
|
"""Класс для замены метода joinArea в xmlDoc для plasma"""
|
|
|
# заменяемый метод для xmlDoc
|
|
|
def joinArea(self, baseNode, xmlNewArea):
|
|
|
"""Объединяет область c областью Body (xmlNewArea c baseNode)"""
|
|
|
|
|
|
def appendArea(baseNode, xmlNewArea):
|
|
|
fieldsRemove = xpath.Evaluate(
|
|
|
"descendant::field[child::action='drop']", xmlNewArea)
|
|
|
for rmNode in fieldsRemove:
|
|
|
parentNode = rmNode.parentNode
|
|
|
parentNode.removeChild(rmNode)
|
|
|
captionAreasRemove = xpath.Evaluate(
|
|
|
"descendant::area/child::caption[child::action='drop']",
|
|
|
xmlNewArea)
|
|
|
for rmNodeCapt in captionAreasRemove:
|
|
|
rmNode = rmNodeCapt.parentNode
|
|
|
parentNode = rmNode.parentNode
|
|
|
parentNode.removeChild(rmNode)
|
|
|
self.setActionArea(xmlNewArea, "append")
|
|
|
# Добавляем разделитель областей во вложенные области
|
|
|
areaNodes = xpath.Evaluate('descendant::area', xmlNewArea)
|
|
|
for areaNode in areaNodes:
|
|
|
self.setActionArea(areaNode, "append")
|
|
|
parentNode = areaNode.parentNode
|
|
|
parentNode.insertBefore(self.sepAreas.cloneNode(True),
|
|
|
areaNode)
|
|
|
baseNode.appendChild(xmlNewArea)
|
|
|
# Добавляем разделитель областей
|
|
|
baseNode.insertBefore(self.sepAreas.cloneNode(True), xmlNewArea)
|
|
|
|
|
|
nodesNames = xpath.Evaluate('child::area/caption/name', baseNode)
|
|
|
nodesNewArea = xpath.Evaluate('child::caption/name', xmlNewArea)
|
|
|
if not nodesNames:
|
|
|
# Добавляем область
|
|
|
if nodesNewArea:
|
|
|
newAreaAction = self.getActionArea(xmlNewArea)
|
|
|
if not (newAreaAction == "drop"):
|
|
|
appendArea(baseNode, xmlNewArea)
|
|
|
return True
|
|
|
if not nodesNames or not nodesNewArea:
|
|
|
return False
|
|
|
nameArea = ""
|
|
|
if nodesNewArea[0].firstChild:
|
|
|
nameArea = nodesNewArea[0].firstChild.nodeValue.strip()
|
|
|
flagFindArea = False
|
|
|
baseNodes = []
|
|
|
newAreaAction = None
|
|
|
for oName in nodesNames:
|
|
|
newAreaAction = self.getActionArea(xmlNewArea)
|
|
|
oArea = oName.parentNode.parentNode
|
|
|
oNameTxt = ""
|
|
|
if oName.firstChild:
|
|
|
oNameTxt = oName.firstChild.nodeValue
|
|
|
if nameArea == oNameTxt:
|
|
|
flagFindArea = True
|
|
|
# При использовании удаления
|
|
|
if newAreaAction == "drop":
|
|
|
prevNode = oName.parentNode.parentNode.previousSibling
|
|
|
removePrevNodes = []
|
|
|
while prevNode and self.getTypeField(prevNode) == "br":
|
|
|
removePrevNodes.append(prevNode)
|
|
|
prevNode = prevNode.previousSibling
|
|
|
for removeNode in removePrevNodes:
|
|
|
baseNode.removeChild(removeNode)
|
|
|
baseNode.removeChild(oName.parentNode.parentNode)
|
|
|
continue
|
|
|
elif newAreaAction == "replace":
|
|
|
oldAreaNode = oName.parentNode.parentNode
|
|
|
newAreaCaption = xpath.Evaluate('child::caption',
|
|
|
xmlNewArea)[0]
|
|
|
oldAreaCaption = xpath.Evaluate('child::caption',
|
|
|
oldAreaNode)[0]
|
|
|
if newAreaCaption and oldAreaCaption:
|
|
|
xmlNewArea.replaceChild(oldAreaCaption, newAreaCaption)
|
|
|
self.setActionArea(xmlNewArea, "replace")
|
|
|
baseNode.replaceChild(xmlNewArea,
|
|
|
oldAreaNode)
|
|
|
continue
|
|
|
baseNodes.append(oName.parentNode.parentNode)
|
|
|
|
|
|
# Заменяем QUOTE
|
|
|
oldAreaNode = oName.parentNode.parentNode
|
|
|
oldAreaQuote = xpath.Evaluate('child::caption/quote',
|
|
|
oldAreaNode)[0]
|
|
|
if oldAreaQuote and not oldAreaQuote.firstChild:
|
|
|
newAreaQuote = xpath.Evaluate('child::caption/quote',
|
|
|
xmlNewArea)[0]
|
|
|
oldAreaCaption = xpath.Evaluate('child::caption',
|
|
|
oldAreaNode)[0]
|
|
|
if newAreaQuote and oldAreaCaption:
|
|
|
oldAreaCaption.replaceChild(newAreaQuote, oldAreaQuote)
|
|
|
|
|
|
newFields = xpath.Evaluate('child::field', xmlNewArea)
|
|
|
|
|
|
joinNewFields = xpath.Evaluate(
|
|
|
"child::field[child::action='join']", xmlNewArea)
|
|
|
self.addNewFielsOldArea(newFields, joinNewFields, oArea)
|
|
|
|
|
|
if not flagFindArea:
|
|
|
# Добавляем область
|
|
|
if not (newAreaAction == "drop"):
|
|
|
appendArea(baseNode, xmlNewArea)
|
|
|
else:
|
|
|
tmpXmlNewAreas = xpath.Evaluate('child::area', xmlNewArea)
|
|
|
for na in tmpXmlNewAreas:
|
|
|
for bn in baseNodes:
|
|
|
self.joinArea(bn, na)
|
|
|
return True
|
|
|
|
|
|
|
|
|
class plasma(samba):
|
|
|
"""Класс для обработки конфигурационного файла типа kde
|
|
|
|
|
|
"""
|
|
|
_comment = "#"
|
|
|
configName = "plasma"
|
|
|
configVersion = "0.1"
|
|
|
reHeader = re.compile("^[\t ]*\[[^\[\]]+\].*\n?", re.M)
|
|
|
reBody = re.compile(".+", re.M | re.S)
|
|
|
reComment = re.compile("^\s*%s.*" % _comment)
|
|
|
reSeparator = re.compile("=")
|
|
|
sepFields = "\n"
|
|
|
reSepFields = re.compile(sepFields)
|
|
|
|
|
|
def prepare(self):
|
|
|
self.blocTextObj = plasmaBlocText()
|
|
|
self._splitToFields = self.splitToFields
|
|
|
# Объект документ
|
|
|
self.docObj = self._textToXML()
|
|
|
# XML документ
|
|
|
self.doc = self.docObj.doc
|
|
|
|
|
|
# Делим текст на области включая вложенные (areas массив областей)
|
|
|
def splitToAllArea(self, text, areas):
|
|
|
"""Делит текст на области включая вложенные
|
|
|
|
|
|
возвращает список объектов областей (переменная areas)
|
|
|
"""
|
|
|
|
|
|
area = PlasmaArea
|
|
|
|
|
|
def findPathArea(listPath, areaF):
|
|
|
"""Ищет путь в области
|
|
|
|
|
|
areaF - объект area
|
|
|
listPath - cписок названий областей
|
|
|
"""
|
|
|
ret = False
|
|
|
if not listPath:
|
|
|
return ret
|
|
|
flagList = False
|
|
|
if type(areaF) == types.ListType:
|
|
|
fields = areaF
|
|
|
flagList = True
|
|
|
else:
|
|
|
fields = areaF.fields
|
|
|
if areaF.header == listPath[0]:
|
|
|
ret = areaF
|
|
|
else:
|
|
|
return ret
|
|
|
for i in fields:
|
|
|
if isinstance(i, PlasmaArea):
|
|
|
add = False
|
|
|
if not flagList:
|
|
|
add = listPath.pop(0)
|
|
|
if not listPath:
|
|
|
break
|
|
|
ret = False
|
|
|
if i.header == listPath[0]:
|
|
|
ret = findPathArea(listPath, i)
|
|
|
break
|
|
|
else:
|
|
|
if add:
|
|
|
listPath.insert(0, add)
|
|
|
if ret == areaF and len(listPath) > 1:
|
|
|
ret = False
|
|
|
return ret
|
|
|
|
|
|
blTmp = self.blocTextObj.findBloc(self.text, self.reHeader, self.reBody)
|
|
|
blocs = self.getFullAreas(blTmp)
|
|
|
if isinstance(blocs, list) and not blocs:
|
|
|
return []
|
|
|
reH = re.compile("\[([^\[\]]+)\]")
|
|
|
# Список имен блоков
|
|
|
namesBlockList = []
|
|
|
# Временные поля
|
|
|
fieldsTmp = []
|
|
|
# Добавляем заголовки
|
|
|
z = 0
|
|
|
for h in blocs[0]:
|
|
|
if not h:
|
|
|
if blocs[1][z] == "":
|
|
|
fieldsTmp.append("")
|
|
|
# fieldsTmp.append("\n")
|
|
|
else:
|
|
|
fieldsTmp.append(blocs[1][z])
|
|
|
z += 1
|
|
|
continue
|
|
|
z += 1
|
|
|
slpNamesBlock = reH.split(h)
|
|
|
# Отступ слева для заголовка
|
|
|
indentionLeft = slpNamesBlock[0]
|
|
|
namesBlock = filter(lambda x: x.strip(), slpNamesBlock)
|
|
|
# namesBlock = map(lambda x: self.removeSymbolTerm(x), namesBlock)
|
|
|
findArea = findPathArea(copy.copy(namesBlock), areas)
|
|
|
findAreaPrev = None
|
|
|
namesBlockList.append(namesBlock)
|
|
|
if findArea:
|
|
|
if len(namesBlock) > 1:
|
|
|
namesBlockView = map(lambda x: self.removeSymbolTerm(x),
|
|
|
namesBlock)
|
|
|
else:
|
|
|
namesBlockView = namesBlock
|
|
|
findArea.start = (indentionLeft + "[" +
|
|
|
"][".join(namesBlockView) + "]")
|
|
|
else:
|
|
|
i = 0
|
|
|
lenNamesBlock = len(namesBlock)
|
|
|
namesBlockTmp = []
|
|
|
for nameB in namesBlock:
|
|
|
namesBlockTmp.append(nameB)
|
|
|
findArea = findPathArea(copy.copy(namesBlockTmp), areas)
|
|
|
i += 1
|
|
|
if not findArea:
|
|
|
areaNew = area()
|
|
|
areaNew.header = nameB
|
|
|
if lenNamesBlock == i:
|
|
|
if len(namesBlock) > 1:
|
|
|
namesBlockView = map(
|
|
|
lambda x: self.removeSymbolTerm(x),
|
|
|
namesBlock)
|
|
|
else:
|
|
|
namesBlockView = namesBlock
|
|
|
areaNew.start = (indentionLeft + "[" +
|
|
|
"][".join(namesBlockView) + "]")
|
|
|
else:
|
|
|
areaNew.start = ""
|
|
|
areaNew.end = ""
|
|
|
if i == 1:
|
|
|
if lenNamesBlock == i:
|
|
|
areas += fieldsTmp
|
|
|
areas.append(areaNew)
|
|
|
findAreaPrev = areas[-1]
|
|
|
else:
|
|
|
if (lenNamesBlock == i and
|
|
|
isinstance(findAreaPrev, area)):
|
|
|
findAreaPrev.fields += fieldsTmp
|
|
|
findAreaPrev.fields.append(areaNew)
|
|
|
findAreaPrev = findAreaPrev.fields[-1]
|
|
|
else:
|
|
|
findAreaPrev = findArea
|
|
|
fieldsTmp = []
|
|
|
i = 0
|
|
|
delt = 0
|
|
|
# Добавляем тела
|
|
|
for body in blocs[1]:
|
|
|
if not blocs[0][i]:
|
|
|
i += 1
|
|
|
delt += 1
|
|
|
continue
|
|
|
## В случае последнего комментария не добавляем перевод строки
|
|
|
# if self.reComment.search(body.splitlines()[-1]):
|
|
|
body = "\n" + body
|
|
|
|
|
|
namesBlock = namesBlockList[i - delt]
|
|
|
findArea = findPathArea(copy.copy(namesBlock), areas)
|
|
|
if isinstance(findArea, area):
|
|
|
# if findArea.fields:
|
|
|
# if type(findArea.fields[0]) == types.StringType:
|
|
|
# findArea.fields.pop(0)
|
|
|
findArea.fields.insert(0, body)
|
|
|
i += 1
|
|
|
return areas
|
|
|
|
|
|
def createCaptionTerm(self, header, start, end, docObj):
|
|
|
"""Создание пустой области с заголовком
|
|
|
|
|
|
при создании области проверяется первый символ заголовка
|
|
|
и добавляется тег action
|
|
|
"!" - <action>drop</action>
|
|
|
"-" - <action>replace</action>
|
|
|
"""
|
|
|
areaAction = False
|
|
|
if header:
|
|
|
if header[0] == "!":
|
|
|
docObj.createCaption(header[1:], [start,
|
|
|
end.replace("\n", "")])
|
|
|
areaAction = "drop"
|
|
|
elif header[0] == "-":
|
|
|
docObj.createCaption(header[1:], [start,
|
|
|
end.replace("\n", "")])
|
|
|
areaAction = "replace"
|
|
|
else:
|
|
|
docObj.createCaption(header, [start,
|
|
|
end.replace("\n", "")])
|
|
|
else:
|
|
|
docObj.createCaption(header, [start,
|
|
|
end.replace("\n", "")])
|
|
|
|
|
|
areaXML = docObj.createArea()
|
|
|
if areaAction:
|
|
|
docObj.setActionArea(areaXML, areaAction)
|
|
|
return areaXML
|
|
|
|
|
|
def createXML(self, areas, rootNode, docObj):
|
|
|
"""Создаем из массивов областей XML"""
|
|
|
for i in areas:
|
|
|
if isinstance(i, PlasmaArea):
|
|
|
if i.header:
|
|
|
areaXML = self.createCaptionTerm(i.header, i.start,
|
|
|
i.end.replace("\n", ""),
|
|
|
docObj)
|
|
|
for f in i.fields:
|
|
|
if isinstance(f, PlasmaArea):
|
|
|
if f.header:
|
|
|
areaXMLChild = self.createCaptionTerm(f.header,
|
|
|
f.start,
|
|
|
f.end.replace(
|
|
|
"\n", ""),
|
|
|
docObj)
|
|
|
|
|
|
self.createXML(f.fields, areaXMLChild, docObj)
|
|
|
|
|
|
areaXML.appendChild(areaXMLChild)
|
|
|
else:
|
|
|
self.createXML(f.fields, areaXML, docObj)
|
|
|
if "\n" in f.end:
|
|
|
fieldXMLBr = docObj.createField("br", [],
|
|
|
"", [],
|
|
|
False, False)
|
|
|
areaXML.appendChild(fieldXMLBr)
|
|
|
else:
|
|
|
if not f:
|
|
|
continue
|
|
|
fields = self.splitToFields(f)
|
|
|
for field in fields:
|
|
|
if field.name is not False:
|
|
|
fieldXML = self.createFieldTerm(
|
|
|
field.name, field.value, field.br, docObj)
|
|
|
areaXML.appendChild(fieldXML)
|
|
|
if field.br[-1] == "\n":
|
|
|
fieldXMLBr = docObj.createField(
|
|
|
"br", [], "", [], False, False)
|
|
|
areaXML.appendChild(fieldXMLBr)
|
|
|
elif field.comment is not False:
|
|
|
fieldXML = docObj.createField(
|
|
|
"comment", [field.comment], "", [],
|
|
|
False, False)
|
|
|
areaXML.appendChild(fieldXML)
|
|
|
elif field.br is not False:
|
|
|
brText = field.br.replace("\n", "")
|
|
|
if brText:
|
|
|
fieldXML = docObj.createField(
|
|
|
'br', [brText], "", [], False, False)
|
|
|
else:
|
|
|
fieldXML = docObj.createField(
|
|
|
'br', [], "", [], False, False)
|
|
|
if areaXML and hasattr(areaXML, "appendChild"):
|
|
|
areaXML.appendChild(fieldXML)
|
|
|
|
|
|
if i.header:
|
|
|
rootNode.appendChild(areaXML)
|
|
|
if "\n" in i.end:
|
|
|
fieldXMLBr = docObj.createField("br", [],
|
|
|
"", [],
|
|
|
False, False)
|
|
|
rootNode.appendChild(fieldXMLBr)
|
|
|
|
|
|
else:
|
|
|
if not i:
|
|
|
continue
|
|
|
fields = self.splitToFields(i)
|
|
|
for field in fields:
|
|
|
if field.name is not False:
|
|
|
fieldXML = self.createFieldTerm(field.name,
|
|
|
field.value,
|
|
|
field.br, docObj)
|
|
|
rootNode.appendChild(fieldXML)
|
|
|
if field.br[-1] == "\n":
|
|
|
fieldXMLBr = docObj.createField("br", [], "", [],
|
|
|
False, False)
|
|
|
rootNode.appendChild(fieldXMLBr)
|
|
|
elif field.comment is not False:
|
|
|
fieldXML = docObj.createField(
|
|
|
"comment", [field.comment], "", [], False, False)
|
|
|
rootNode.appendChild(fieldXML)
|
|
|
elif field.br is not False:
|
|
|
brText = field.br.replace("\n", "")
|
|
|
if brText:
|
|
|
fieldXML = docObj.createField(
|
|
|
'br', [brText], "", [], False, False)
|
|
|
else:
|
|
|
fieldXML = docObj.createField(
|
|
|
'br', [], "", [], False, False)
|
|
|
rootNode.appendChild(fieldXML)
|
|
|
# rootNode.appendChild(areaXML)
|
|
|
|
|
|
def createTxtConfig(self, strHeader, dictVar):
|
|
|
"""Cоздает область с заголовком
|
|
|
|
|
|
создает текст конфигурационного файла в формате samba из
|
|
|
заголовка (строка) и словаря переменных
|
|
|
"""
|
|
|
if not strHeader:
|
|
|
return ""
|
|
|
if type(strHeader) in (tuple, list):
|
|
|
outTxt = "".join(map(lambda x: "[" + x + "]", strHeader))
|
|
|
if not outTxt:
|
|
|
return ""
|
|
|
outTxt += "\n"
|
|
|
else:
|
|
|
outTxt = "[" + strHeader + "]\n"
|
|
|
for key in dictVar.keys():
|
|
|
outTxt += "%s=%s\n" % (key, dictVar[key])
|
|
|
return outTxt
|
|
|
|
|
|
def _textToXML(self):
|
|
|
"""Преобразуем текст в XML"""
|
|
|
areas = []
|
|
|
if self.text.strip():
|
|
|
self.splitToAllArea(self.text, areas)
|
|
|
# docObj = xmlDoc()
|
|
|
# Создаем новый класс xmlDoc с измененным методом joinArea
|
|
|
# Создаем экземпляр нового класса
|
|
|
docObj = xmlDocPlasma()
|
|
|
# Создание объекта документ c пустым разделителем между полями
|
|
|
docObj.createDoc(self.configName, self.configVersion)
|
|
|
if not areas:
|
|
|
return docObj
|
|
|
self.createXML(areas, docObj.getNodeBody(), docObj)
|
|
|
return docObj
|
|
|
|
|
|
def postXML(self):
|
|
|
"""Последующая постобработка XML"""
|
|
|
# Для добавления перевода строки между областями если его нет
|
|
|
def getQuotesArea(xmlArea):
|
|
|
quotes = []
|
|
|
xmlQuotes = xpath.Evaluate('child::caption/quote', xmlArea)
|
|
|
for node in xmlQuotes:
|
|
|
if node.firstChild:
|
|
|
quotes.append(node.firstChild.nodeValue)
|
|
|
if len(quotes) == 0:
|
|
|
quotes.append("")
|
|
|
quotes.append("")
|
|
|
elif len(quotes) == 1:
|
|
|
quotes.append("")
|
|
|
return quotes
|
|
|
|
|
|
xmlAreas = xpath.Evaluate("descendant::area", self.docObj.body)
|
|
|
for xmlArea in xmlAreas:
|
|
|
# Перед пустой областью и после нее удаляем переводы строк
|
|
|
if getQuotesArea(xmlArea) == ["", ""]:
|
|
|
if (xmlArea.previousSibling and
|
|
|
self.docObj.getTypeField(
|
|
|
xmlArea.previousSibling) == "br"):
|
|
|
parentNode = xmlArea.previousSibling.parentNode
|
|
|
prev_prev_sbl = xmlArea.previousSibling.previousSibling
|
|
|
if (prev_prev_sbl and
|
|
|
self.docObj.getTypeField(
|
|
|
prev_prev_sbl) == "br"):
|
|
|
parentNode.removeChild(
|
|
|
xmlArea.previousSibling.previousSibling)
|
|
|
parentNode.removeChild(xmlArea.previousSibling)
|
|
|
if (xmlArea.nextSibling and
|
|
|
self.docObj.getTypeField(
|
|
|
xmlArea.nextSibling) == "br"):
|
|
|
parentNode = xmlArea.nextSibling.parentNode
|
|
|
next_next_sbl = xmlArea.nextSibling.nextSibling
|
|
|
if (next_next_sbl and
|
|
|
self.docObj.getTypeField(
|
|
|
next_next_sbl) == "br"):
|
|
|
parentNode.removeChild(xmlArea.nextSibling.nextSibling)
|
|
|
parentNode.removeChild(xmlArea.nextSibling)
|
|
|
continue
|
|
|
|
|
|
# Собираем поля в кучку
|
|
|
xmlChildAreas = xpath.Evaluate("child::area", xmlArea)
|
|
|
if xmlChildAreas:
|
|
|
childNodes = self.docObj.getFieldsArea(xmlArea)
|
|
|
firstChildArea = xmlChildAreas[0]
|
|
|
|
|
|
if (firstChildArea.previousSibling and
|
|
|
self.docObj.getTypeField(
|
|
|
firstChildArea.previousSibling) == "br"):
|
|
|
prev_prev_sbl = (
|
|
|
firstChildArea.previousSibling.previousSibling)
|
|
|
if prev_prev_sbl:
|
|
|
if self.docObj.getTypeField(prev_prev_sbl) == "br":
|
|
|
firstChildArea = firstChildArea.previousSibling
|
|
|
flagFoundArea = False
|
|
|
it = 0
|
|
|
lenChild = len(childNodes)
|
|
|
for node in childNodes:
|
|
|
it += 1
|
|
|
if node.tagName == "area":
|
|
|
flagFoundArea = True
|
|
|
continue
|
|
|
if flagFoundArea and node.tagName == "field":
|
|
|
if self.docObj.getTypeField(node) == "var":
|
|
|
xmlArea.insertBefore(node, firstChildArea)
|
|
|
if it < lenChild:
|
|
|
node_type = self.docObj.getTypeField(
|
|
|
childNodes[it])
|
|
|
if node_type == "br":
|
|
|
xmlArea.insertBefore(childNodes[it],
|
|
|
firstChildArea)
|
|
|
# Добавление перевода строк в если его нет между полями
|
|
|
if (self.docObj.getTypeField(node) == "var" and
|
|
|
node.previousSibling and
|
|
|
not (self.docObj.getTypeField(
|
|
|
node.previousSibling) in ("br", "comment"))):
|
|
|
xmlArea.insertBefore(self.docObj.createField(
|
|
|
"br", [], "", [], False, False), node)
|
|
|
|
|
|
# Добавляем BR если его нет первым полем
|
|
|
xmlFields = xpath.Evaluate("child::field", xmlArea)
|
|
|
if not (xmlFields and
|
|
|
(self.docObj.getTypeField(xmlFields[0]) == "br" or
|
|
|
self.docObj.getTypeField(
|
|
|
xmlFields[0]) == "comment")):
|
|
|
if xmlFields:
|
|
|
xmlArea.insertBefore(self.docObj.createField("br",
|
|
|
[], "", [],
|
|
|
False, False),
|
|
|
xmlFields[0])
|
|
|
# Добавление переводов строк между полями
|
|
|
if xmlFields:
|
|
|
for node in xmlFields:
|
|
|
# Добавление перевода строк в если его нет между полями
|
|
|
if (self.docObj.getTypeField(node) == "var" and
|
|
|
node.previousSibling and
|
|
|
not (self.docObj.getTypeField(
|
|
|
node.previousSibling) in ("br", "comment"))):
|
|
|
xmlArea.insertBefore(self.docObj.createField("br",
|
|
|
[], "", [],
|
|
|
False,
|
|
|
False),
|
|
|
node)
|
|
|
# Если последним полем BR, удаляем его
|
|
|
if xmlFields and self.docObj.getTypeField(xmlFields[-1]) == "br":
|
|
|
if not xmlFields[-1].nextSibling:
|
|
|
xmlArea.removeChild(xmlFields[-1])
|
|
|
|
|
|
# Если предыдущим полем не (BR или комментарий) - добавляем BR
|
|
|
if (xmlArea.previousSibling and
|
|
|
not (self.docObj.getTypeField(
|
|
|
xmlArea.previousSibling) == "br" or
|
|
|
self.docObj.getTypeField(
|
|
|
xmlArea.previousSibling) == "comment")):
|
|
|
parentNode = xmlArea.parentNode
|
|
|
parentNode.insertBefore(self.docObj.createField(
|
|
|
"br", [], "", [], False, False), xmlArea)
|
|
|
# Если есть предыдущее поле, и поле предыдущеее предыдущему
|
|
|
# не равно BR или комментарий то добавляем BR
|
|
|
if xmlArea.previousSibling:
|
|
|
prPrSibling = xmlArea.previousSibling.previousSibling
|
|
|
if (prPrSibling and
|
|
|
not (self.docObj.getTypeField(
|
|
|
prPrSibling) == "br" or
|
|
|
self.docObj.getTypeField(
|
|
|
prPrSibling) == "comment")):
|
|
|
parentNode = xmlArea.parentNode
|
|
|
parentNode.insertBefore(self.docObj.createField(
|
|
|
"br", [], "", [], False, False), xmlArea)
|
|
|
# Если после есть BR а за ним ничего нет, удаляем BR
|
|
|
if (xmlArea.nextSibling and
|
|
|
self.docObj.getTypeField(xmlArea.nextSibling) == "br"):
|
|
|
if not xmlArea.nextSibling.nextSibling:
|
|
|
parentNode = xmlArea.nextSibling.parentNode
|
|
|
parentNode.removeChild(xmlArea.nextSibling)
|
|
|
|
|
|
def join(self, kdeObj):
|
|
|
"""Объединяем конфигурации"""
|
|
|
if isinstance(kdeObj, plasma):
|
|
|
self.docObj.joinDoc(kdeObj.doc)
|
|
|
self.postXML()
|