;; -*- coding: utf-8 -*- ;; ;; Copyright 2019-2021 Fabien Bourgeois ;; ;; 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 . " 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))))