76 lines
3.2 KiB
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))))
|