hy_odoo/hy_odoo/xml_base.hy

76 lines
3.2 KiB
Hy

;; -*- coding: utf-8 -*-
;;
;; Copyright 2019-2021 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/>.
" XML helpers and macros "
(require [hy-odoo.macros.general [if-python2 ustr-cast]])
(require [hy-odoo.macros.odoo [pdb]])
(import [collections [namedtuple]]
[functools [partial]]
[os [path]]
[xml.etree.ElementTree :as ET])
;; Types
(setv XMLDictElement (namedtuple "XMLDictElement" ["tag" "attrs" "children"]))
;; Helpers
(defn xmlroot [tree]
"Special process for root XML Node"
(setv rootel (.Element ET (get tree "tag") (get tree "attrs")))
(when (in "children" tree)
(xmlchild rootel (get tree "children")))
(return rootel))
(defn xmlchild [parent children]
"Handling of children (ie non root) XML Nodes with/o text and subchildren
(recursive)"
(cond [(string? children) (setv (. parent text) children)]
[(instance? XMLDictElement children)
(do
(setv attrs (dfor [k v] (.items (. children attrs)) [(ustr-cast k) (ustr-cast v)]))
(setv new-parent (.SubElement ET parent (. children tag) attrs)
subchildren (. children children))
(when subchildren) (xmlchild new-parent subchildren))]
[(instance? list children) (list( map (partial xmlchild parent) children))]
[True (raise (TypeError "Invalid arguments for xmlchild"))]))
(defn xmln [&optional [tag ""] [attrs {}] [children []]]
"XMLDictElement building from dict object, with defaults"
(when (instance? list attrs) (setv children attrs attrs {}))
(setv xmldictel (partial XMLDictElement tag attrs)
inst-str? (if-python2 (instance? unicode children) (instance? str children)))
(when inst-str? (return (xmldictel [children])))
(when (instance? list children) (return (xmldictel children)))
(raise (TypeError "Invalid arguments for xmln")))
(defn xml-write [filepath tree]
"Write XML file according to filepath and given tree"
(when (.endswith filepath ".hy")
(if-python2
(do
(import [xml.etree.ElementTree :as ET]
[xml.dom [minidom]])
(setv output-xml (.toprettyxml :indent " "
(.parseString minidom (.tostring ET tree)))))
(setv output-xml (.decode (.tostring ET tree) "utf-8")))
(setv output-path (.split (.abspath path filepath) "/")
(cut output-path -1) [(.replace (last output-path) ".hy" "_views.xml")]
output-path (.join "/" output-path))
(with [output-file (open output-path "w")] (.write output-file output-xml))))