diff --git a/pym/cl_profile.py b/pym/cl_profile.py
index c5137c7..98d41f9 100644
--- a/pym/cl_profile.py
+++ b/pym/cl_profile.py
@@ -26,6 +26,7 @@ import types
import copy
import random
import string
+import time
tr = cl_base.lang()
tr.setLocalDomain('cl_lib')
@@ -5864,7 +5865,7 @@ Valid values attribute 'action': \
self._removeDropNodesAndAttrAction(self.bodyNode)
def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True):
- """Объединение корневой ноды профиля и корненвой ноды файла"""
+ """Объединение корневой ноды профиля и корневой ноды файла"""
xmlNode = xmlNewNode
childNodes = xmlNode.childNodes
nextOldNode = xmlOldNode
@@ -5995,7 +5996,7 @@ the same nodes at one level")
return False
# Импортируем корневую ноду нового документа в текущий документ
#newImportBodyNode = self.doc.importNode(doc.documentElement, True)
- # Объединение корневой ноды профиля и корненвой ноды файла
+ # Объединение корневой ноды профиля и корневой ноды файла
if not self._join(doc.documentElement, self.bodyNode):
return False
return True
@@ -6103,7 +6104,7 @@ class xml_xfcepanel(xml_xfce):
return True
def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0):
- """Объединение корневой ноды профиля и корненвой ноды файла"""
+ """Объединение корневой ноды профиля и корневой ноды файла"""
xmlNode = xmlNewNode
childNodes = xmlNode.childNodes
nextOldNode = xmlOldNode
@@ -6329,3 +6330,239 @@ class dhcp(bind):
"""Объединяем конфигурации"""
if isinstance(dhcpObj, dhcp):
self.docObj.joinDoc(dhcpObj.doc)
+
+
+class xml_gconf(xml_xfce):
+ """Класс для объединения gconf-xml файлов"""
+ # root нода
+ rootNode = False
+ # body нода
+ bodyNode = False
+ # Документ
+ doc = False
+ # Текст профиля
+ text = ""
+ # Текущее время в секундах
+ currentTime = ""
+ # Комментарий
+ _comment = ("")
+ # поддерживаемые аттрибуты тега entry. Пример
+ supportEntryTypes = ("int", "bool", "float", "string", "list")
+
+ def __init__(self, text):
+ self.text = text
+ # Создаем пустой объект
+ self.docObj = type("_empty_class", (object,), {})()
+ # Названия аттрибутов для пустого объекта
+ emptyMethods = ["getNodeBody","removeComment","insertBRtoBody",
+ "insertBeforeSepAreas"]
+ # Добавляем необходимые аттрибуты пустому объекту
+ for method in emptyMethods:
+ setattr(self.docObj, method, self.emptyMethod)
+ # Пустой метод (не нужно имя файла для корневой ноды)
+ setattr(self, "setNameBodyNode", self.emptyMethod)
+ # Создаем XML документ
+ self.doc = self.textToXML()
+
+ def getCurrentTime(self):
+ """Получение текущего времени в секундах"""
+ return str(int(time.time()))
+
+ def textToXML(self):
+ """Создание из текста XML документа
+ Храним xml в своем формате
+ """
+ if not self.text.strip():
+ self.text = ''''''
+ try:
+ self.doc = xml.dom.minidom.parseString(self.text)
+ except:
+ self.setError(_("Can not text profile is XML"))
+ return False
+ self.rootNode = self.doc.documentElement
+ self.bodyNode = self.rootNode
+ return self.doc
+
+ def cmpListsNodesEntry(self, listXmlA, listXmlB):
+ """Сравнение содержимого двух списков XML нод"""
+ getTextsNodes = lambda y: map(lambda x:\
+ x.toxml().replace(" ","").replace("\t","").replace("\n",""),
+ map(lambda x: x.removeAttribute("mtime") or x,
+ map(lambda x: x.cloneNode(True),
+ filter(lambda x: x.nodeType==x.ELEMENT_NODE, y))))
+ if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)):
+ return True
+ return False
+
+ def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0):
+ """Объединение корневой ноды профиля и корневой ноды файла"""
+ if levelNumber>1:
+ return True
+ xmlNode = xmlNewNode
+ childNodes = xmlNode.childNodes
+ nextOldNode = xmlOldNode
+ flagError = False
+ if xmlNode.nodeType == xmlNode.ELEMENT_NODE:
+ n = xmlNode
+ tagName = n.tagName
+ nAction = u''
+ nName = u''
+ nType = u''
+ nValue = u''
+ attrName = ''
+ attrType = ''
+ if flagRootNode:
+ if not tagName == "gconf":
+ self.setError(_("The text is not a valid gconf-XML format \
+(not found '...')"))
+ return False
+ else:
+ if not tagName == "entry":
+ self.setError(_("The text is not a valid gconf-XML format \
+(found '<%s>..%s>'")%(tagName,tagName))
+ return False
+ if not n.hasAttribute("name"):
+ self.setError(_('Not found arrtibute "name" in tag entry'))
+ return False
+ if not n.hasAttribute("type"):
+ self.setError(_('Not found arrtibute "type" in tag entry'))
+ return False
+ nName = n.getAttribute("name")
+ attrName = u"attribute::name='%s'"%nName
+ nType = n.getAttribute("type")
+ # Проверка правильности аттрибута type
+ if not nType in self.supportEntryTypes:
+ self.setError(\
+ _('Incorrect arrtibute "type" - ')%nType)
+ return False
+ attrType = u"attribute::type='%s'"%nType
+ if n.hasAttribute("value"):
+ nValue = n.getAttribute("value")
+ if n.hasAttribute("action"):
+ nAction = n.getAttribute("action")
+ if not nAction in ("join","replace","drop"):
+ textError = _('''In the text, XML profile, look \
+for a reserved attribute 'action' with the incorrect value.\n\
+Valid values attribute 'action': \
+(action="join", action="replace", action="drop")''')
+ self.setError(textError)
+ return False
+ if xmlOldNode.parentNode:
+ findStr = u"child::%s"%tagName
+ strAttr = [attrName, attrType]
+ findAttr = filter(lambda x: x, strAttr)
+ findAttrStr = ''
+ if findAttr:
+ strAttr = u' and '.join(findAttr)
+ findAttrStr = "[%s]"%strAttr
+ findPath = u"child::%s%s"%(tagName,findAttrStr)
+ # Рабочая нода
+ if flagRootNode:
+ workNode = xmlOldNode.parentNode
+ else:
+ workNode = xmlOldNode
+ oldNodes = xpath.Evaluate(findPath, workNode)
+ # Новая нода список
+ flagArray = False
+ if nType == "list":
+ flagArray = True
+ flagDrop = False
+ flagJoin = True
+ flagReplace = False
+ if nType=="string" or nAction=="replace":
+ flagJoin = False
+ flagReplace = True
+ elif nAction == "drop":
+ flagJoin = False
+ flagDrop = True
+ if flagRootNode:
+ textError = _('Incorrect action="drop" in root node')
+ self.setError(textError)
+ return False
+ if oldNodes:
+ if len(oldNodes)>1:
+ textError = _("The uncertainty in this profile are \
+the same nodes at one level")
+ self.setError(textError)
+ return False
+ nextOldNode = oldNodes[0]
+ # Замещаем ноду в случае массива
+ if flagArray and not flagDrop:
+ replaceXmlNode = xmlNode.cloneNode(True)
+ # Сравнение содержимого нод
+ if not self.cmpListsNodesEntry([replaceXmlNode],
+ [nextOldNode]):
+ replaceXmlNode.setAttribute("mtime",
+ self.currentTime)
+ if nAction:
+ replaceXmlNode.removeAttribute("action")
+ workNode.replaceChild(replaceXmlNode,
+ nextOldNode)
+ flagJoin = False
+ flagReplace = False
+ childNodes = False
+ # Объединение нод
+ if flagJoin:
+ if nextOldNode.hasAttribute("value"):
+ oValue = nextOldNode.getAttribute("value")
+ if nValue != oValue:
+ nextOldNode.setAttribute("mtime",
+ self.currentTime)
+ nextOldNode.setAttribute("value",nValue)
+ # Замещение ноды
+ elif flagReplace:
+ replaceXmlNode = xmlNode.cloneNode(True)
+ # Сравнение содержимого нод
+ if not self.cmpListsNodesEntry([replaceXmlNode],
+ [nextOldNode]):
+ replaceXmlNode.setAttribute("mtime",
+ self.currentTime)
+ if not\
+ self._removeDropNodesAndAttrAction(\
+ replaceXmlNode):
+ return False
+ workNode.replaceChild(replaceXmlNode,
+ nextOldNode)
+ childNodes = False
+ # Удаление ноды
+ elif flagDrop:
+ workNode.removeChild(nextOldNode)
+ childNodes = False
+ else:
+ # Добавление ноды
+ childNodes = False
+ if not flagDrop:
+ appendXmlNode = xmlNode.cloneNode(True)
+ appendXmlNode.setAttribute("mtime", self.currentTime)
+ if not\
+ self._removeDropNodesAndAttrAction(appendXmlNode):
+ return False
+ workNode.appendChild(appendXmlNode)
+ if childNodes:
+ for node in childNodes:
+ levelNumber +=1
+ if not self._join(node, nextOldNode, False, levelNumber):
+ flagError = True
+ break
+ levelNumber -= 1
+ if flagError:
+ return False
+ return True
+
+ def join(self, xml_gconfObj):
+ """Объединяем конфигурации"""
+ # Получаем текущее время
+ self.currentTime = self.getCurrentTime()
+ if isinstance(xml_gconfObj, xml_gconf):
+ try:
+ self.joinDoc(xml_gconfObj.doc)
+ except:
+ self.setError(_("Can not join profile"))
+ return False
+ return True
+
+ def getConfig(self):
+ """Получение текстового файла из XML документа"""
+ data = self.doc.toprettyxml().split("\n")
+ data = filter(lambda x: x.strip(), data)
+ return "\n".join(data).replace("\t"," ")