;; Copyright 2019-2022 Fabien Bourgeois ;; ;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at https://mozilla.org/MPL/2.0/. " XML helpers and macros " (require odoo.addons.hy-odoo.mgeneral [instance?] odoo.addons.hy-odoo.modoo [pdb]) (import collections [namedtuple] functools [partial] os [path] xml.dom [minidom] 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 (instance? str children) (setv (. parent text) children) (instance? XMLDictElement children) (do (setv attrs (dfor [k v] (.items (. children attrs)) (str k) (str 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 [[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? (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 [pretty True] [suffix "_views"]] "Write XML file according to filepath and given tree" (when (.endswith filepath ".hy") (setv output-xml (.decode (.tostring ET tree :xml_declaration True :encoding "utf-8") "utf-8") output-path (.split (.abspath path filepath) "/") (get output-path -1) (.replace (get output-path -1) ".hy" (% "%s.xml" suffix)) output-path (.join "/" output-path)) (when pretty (setv output-xml (.toprettyxml (.parseString minidom output-xml) :indent " "))) (with [output-file (open output-path "w")] (.write output-file output-xml))))