yaltik_odoo_custom/yaltik_dsl/xml_base.py

138 lines
5.8 KiB
Python

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# __coconut_hash__ = 0xeb6b4b07
# Compiled with Coconut version 1.4.3 [Ernest Scribbler]
""" XML helpers and macros """
# Coconut Header: -------------------------------------------------------------
from __future__ import print_function, absolute_import, unicode_literals, division
import sys as _coconut_sys, os.path as _coconut_os_path
_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__))
_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__")
if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path:
del _coconut_sys.modules[b"__coconut__"]
_coconut_sys.path.insert(0, _coconut_file_path)
from __coconut__ import *
from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match
# Compiled Coconut: -----------------------------------------------------------
# -*- coding: utf-8 -*-
#
# Copyright 2019-2020 Fabien Bourgeois <fabien@yaltik.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from os import path
import xml.etree.ElementTree as ET
from xml.dom import minidom
from typing import Dict
from typing import List
from typing import Union
from typing import Text
from typing import Any
# TODO: fix MyPy / typing
class XMLDictElement(_coconut.typing.NamedTuple("XMLDictElement", [("tag", 'Text'), ("attrs", 'XMLAttrs'), ("children", 'List[Any]')]), _coconut.object):
__slots__ = ()
__ne__ = _coconut.object.__ne__
def __eq__(self, other):
return self.__class__ is other.__class__ and _coconut.tuple.__eq__(self, other)
def __hash__(self):
return _coconut.tuple.__hash__(self) ^ hash(self.__class__)
XMLAttrs = Dict[Text, Text]
XMLChild = Union[XMLDictElement, Text, List]
def xmlroot(tree # type: Dict[str, Any]
):
# type: (...) -> ET.Element
""" Special process for root XML Node """
rootel = (ET.Element)(*(tree['tag'], tree['attrs']))
if 'children' in tree:
(xmlchild)(*(rootel, tree['children']))
return rootel
def xmlchild(parent, # type: ET.Element
children # type: XMLDictElement
):
# type: (...) -> None
""" Handling of children (ie non root) XML Nodes with/o text and
subchildren (recursive) """
_coconut_match_to = children
_coconut_case_check_0 = False
if _coconut.isinstance(_coconut_match_to, Text):
_coconut_case_check_0 = True
if _coconut_case_check_0:
parent.text = children
if not _coconut_case_check_0:
if _coconut.isinstance(_coconut_match_to, XMLDictElement):
_coconut_case_check_0 = True
if _coconut_case_check_0:
attrs = dict(((unicode(k)), (unicode(v))) for [k, v] in children.attrs.items())
new_parent = (ET.SubElement)(*(parent, children.tag, attrs))
subchildren = children.children
if subchildren:
(xmlchild)(*(new_parent, subchildren))
if not _coconut_case_check_0:
if _coconut.isinstance(_coconut_match_to, List):
_coconut_case_check_0 = True
if _coconut_case_check_0:
(consume)((map)(*(((_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent)), children)))
if not _coconut_case_check_0:
raise TypeError('Invalid arguments for xmlchild')
def xmln(tag='', # type: Text
attrs={}, # type: XMLAttrs
children=[] # type: Union[Text, List]
):
# type: (...) -> XMLDictElement
""" XMLDictElement building from dict object, with defaults """
xmldictel = (_coconut.functools.partial(_coconut.functools.partial, XMLDictElement))(*(tag, attrs))
_coconut_match_to = children
_coconut_case_check_1 = False
if _coconut.isinstance(_coconut_match_to, Text):
c = _coconut_match_to
_coconut_case_check_1 = True
if _coconut_case_check_1:
return (xmldictel)([c])
if not _coconut_case_check_1:
if _coconut.isinstance(_coconut_match_to, list):
c = _coconut_match_to
_coconut_case_check_1 = True
if _coconut_case_check_1:
return (xmldictel)(c)
if not _coconut_case_check_1:
raise TypeError('Invalid arguments for xmln')
def xml_write(filepath, tree):
""" Write XML file according to filename and given tree """
if (filepath.endswith)('.py'): # if .pyc, no need to generate XML
output_xml = ((minidom.parseString)((ET.tostring)(tree))).toprettyxml(indent=' ')
output_path = (path.dirname)((path.abspath)(filepath))
fpath = (('/'.join)([output_path, (path.basename)(filepath)])).replace('.py', '_views.xml')
with open(fpath, 'w') as output_file:
output_file.write(output_xml)