diff --git a/pym/cl_api.py b/pym/cl_api.py index 6374c5a..9354b7b 100644 --- a/pym/cl_api.py +++ b/pym/cl_api.py @@ -29,7 +29,6 @@ from cl_datavars import DataVars class APIError(Exception): """Класс ошибок""" - pass class libVars: diff --git a/pym/format/xml_gconf_tree.py b/pym/format/xml_gconf_tree.py new file mode 100644 index 0000000..f1d522e --- /dev/null +++ b/pym/format/xml_gconf_tree.py @@ -0,0 +1,191 @@ +#-*- coding: utf-8 -*- + +# Copyright 2010 Calculate Ltd. 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 sys +import time +import re +from xml import xpath +import xml.dom.minidom +from format.xml_gconf import xml_gconf +# Перевод cообщений модуля +from cl_lang import lang +tr = lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) + +class xml_gconf_tree(xml_gconf): + """Класс для объединения gconf_tree-xml файлов""" + + def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True): + """Объединение корневой ноды шаблона и корневой ноды файла""" + xmlNode = xmlNewNode + childNodes = xmlNode.childNodes + nextOldNode = xmlOldNode + flagError = False + if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + n = xmlNode + tagName = n.tagName + tagNameStr = tagName.encode("UTF-8") + nAction = u'' + nName = u'' + nType = u'' + nValue = u'' + nSchema = u'' + attrName = '' + 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 in ("dir", "entry"): + self.setError(_("The text is not a valid gconf-XML format \ +(found '<%(tag)s>..'")%{'tag':tagNameStr}) + return False + if not n.hasAttribute("name"): + self.setError(\ + _('Not found arrtibute "name" in %(tag)s')\ + %{'tag':tagNameStr}) + return False + nName = n.getAttribute("name") + attrName = u"attribute::name='%s'"%nName + if n.hasAttribute("action"): + nAction = n.getAttribute("action") + if not nAction in ("join","replace","drop"): + textError = _('''In the text, XML template, 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: + findAttrStr = "" + if attrName: + findAttrStr = "[%s]"%attrName + findPath = u"child::%s%s"%(tagName,findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.parentNode + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + # По умолчанию - объединение аттрибутов + flagJoin = True + flagReplace = False + flagDrop = False + if nAction=="replace": + flagReplace = True + flagJoin = False + # Удаляем ноду + if nAction == "drop": + flagDrop = True + flagJoin = False + 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 template are \ +the same nodes at one level") + self.setError(textError) + return False + nextOldNode = oldNodes[0] + # Объединение аттрибутов нод + if flagJoin: + listOldAttributes = nextOldNode.attributes.items() + if listOldAttributes: + listOldAttributes = filter(lambda x:\ + x[0] != "mtime", listOldAttributes) + # Замена содержимого + if xmlNode.tagName == "entry": + 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 + listNewAttributes = xmlNode.attributes.items() + if listNewAttributes: + listNewAttributes = filter(lambda x:\ + not x[0] in ("action", "mtime"), + listNewAttributes) + if set(listNewAttributes)!= set(listOldAttributes): + # Объединение аттрибутов + for attrName, attrValue in listNewAttributes: + nextOldNode.setAttribute(attrName, attrValue) + if nextOldNode.tagName == "entry": + nextOldNode.setAttribute("mtime", + self.currentTime) + # Замещение ноды + elif flagReplace: + replaceXmlNode = xmlNode.cloneNode(True) + # Сравнение содержимого нод + if not self.cmpListsNodesEntry([replaceXmlNode], + [nextOldNode]): + if replaceXmlNode.tagName == "entry": + 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) + if appendXmlNode.tagName == "entry": + appendXmlNode.setAttribute("mtime", + self.currentTime) + if not\ + self._removeDropNodesAndAttrAction(appendXmlNode): + return False + workNode.appendChild(appendXmlNode) + if childNodes: + for node in childNodes: + if not self._join(node, nextOldNode, False): + flagError = True + break + if flagError: + return False + return True + + def join(self, xml_gconfObj): + """Объединяем конфигурации""" + # Получаем текущее время + self.currentTime = self.getCurrentTime() + if isinstance(xml_gconfObj, xml_gconf_tree): + try: + self.joinDoc(xml_gconfObj.doc) + except: + self.setError(_("Can not join template")) + return False + return True \ No newline at end of file