Salome HOME
bug fix for jobs command with multiple users
[tools/sat.git] / src / xmlManager.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 try: # For python2
21     import sys
22     reload(sys)  
23     sys.setdefaultencoding('utf8')
24 except:
25     pass
26
27 import src
28 from . import ElementTree as etree
29
30 class XmlLogFile(object):
31     '''Class to manage writing in salomeTools xml log file
32     '''
33     def __init__(self, filePath, rootname, attrib = {}):
34         '''Initialization
35         
36         :param filePath str: The path to the file where to write the log file
37         :param rootname str: The name of the root node of the xml file
38         :param attrib dict: the dictionary that contains the attributes 
39                             and value of the root node
40         '''
41         # Initialize the filePath and ensure that the directory 
42         # that contain the file exists (make it if necessary)
43         self.logFile = filePath
44         src.ensure_path_exists(os.path.dirname(filePath))
45         # Initialize the field that contain the xml in memory
46         self.xmlroot = etree.Element(rootname, attrib = attrib)
47     
48     def write_tree(self, stylesheet=None, file_path = None):
49         '''Write the xml tree in the log file path. Add the stylesheet if asked.
50         
51         :param stylesheet str: The stylesheet to apply to the xml file
52         '''
53         log_file_path = self.logFile
54         if file_path:
55             log_file_path = file_path
56         try:
57             f = open(log_file_path, 'w')
58             f.write("<?xml version='1.0' encoding='utf-8'?>\n")
59             if stylesheet:
60                 f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\n" % 
61                         stylesheet)    
62             f.write(etree.tostring(self.xmlroot, encoding='utf-8'))
63             f.close()
64         except IOError:
65             pass  
66         
67     def add_simple_node(self, node_name, text=None, attrib={}):
68         '''Add a node with some attibutes and text to the root node.
69         
70         :param node_name str: the name of the node to add
71         :param text str: the text of the node
72         :param attrib dict: the dictionary containing the 
73                             attribute of the new node
74         '''
75         n = etree.Element(node_name, attrib=attrib)
76         n.text = text
77         self.xmlroot.append(n)
78         return n
79     
80     def append_node_text(self, node_name, text):
81         '''Append a new text to the node that has node_name as name
82         
83         :param node_name str: The name of the node on which append text
84         :param text str: The text to append
85         '''
86         # find the corresponding node
87         for field in self.xmlroot:
88             if field.tag == node_name:
89                 # append the text
90                 field.text += text
91
92     def append_node_attrib(self, node_name, attrib):
93         '''Append a new attributes to the node that has node_name as name
94         
95         :param node_name str: The name of the node on which append text
96         :param attrib dixt: The attrib to append
97         '''
98         self.xmlroot.find(node_name).attrib.update(attrib)
99
100 class ReadXmlFile(object):
101     '''Class to manage reading of an xml log file
102     '''
103     def __init__(self, filePath):
104         '''Initialization
105         
106         :param filePath str: The xml file to be read
107         '''
108         self.filePath = filePath
109         etree_inst = etree.parse(filePath)
110         self.xmlroot = etree_inst.parse(filePath)
111
112     def getRootAttrib(self):
113         '''Get the attibutes of the self.xmlroot
114         
115         :return: The attributes of the root node
116         :rtype: dict
117         '''
118         return self.xmlroot.attrib
119     
120     def get_attrib(self, node_name):
121         '''Get the attibutes of the node node_name in self.xmlroot
122         
123         :param node_name str: the name of the node
124         :return: the attibutes of the node node_name in self.xmlroot
125         :rtype: dict
126         '''
127         attrib = self.xmlroot.find(node_name).attrib
128         # To be python 3 compatible, convert bytes to str if there are any
129         fixedAttrib = {}
130         for k in attrib.keys():
131             if isinstance(k, bytes):
132                 key = k.decode()
133             else:
134                 key = k
135             if isinstance(attrib[k], bytes):
136                 value = attrib[k].decode()
137             else:
138                 value = attrib[k]
139             fixedAttrib[key] = value
140         return fixedAttrib
141     
142     def get_node_text(self, node):
143         '''Get the text of the first node that has name 
144            that corresponds to the parameter node
145         
146         :param node str: the name of the node from which get the text
147         :return: the text of the first node that has name 
148                  that corresponds to the parameter node
149         :rtype: str
150         '''
151         return self.xmlroot.find(node).text
152     
153 def add_simple_node(root_node, node_name, text=None, attrib={}):
154     '''Add a node with some attibutes and text to the root node.
155
156     :param root_node etree.Element: the Etree element where to add the new node    
157     :param node_name str: the name of the node to add
158     :param text str: the text of the node
159     :param attrib dict: the dictionary containing the 
160                         attribute of the new node
161     '''
162     n = etree.Element(node_name, attrib=attrib)
163     n.text = text
164     root_node.append(n)
165     return n
166
167 def append_node_attrib(root_node, attrib):
168     '''Append a new attributes to the node that has node_name as name
169     
170     :param root_node etree.Element: the Etree element 
171                                     where to append the new attibutes
172     :param attrib dixt: The attrib to append
173     '''
174     root_node.attrib.update(attrib)
175
176 def find_node_by_attrib(xmlroot, name_node, key, value):
177     '''Find the nfirst ode from xmlroot that has name name_node and that has in 
178        its attributes {key : value}. Return the node
179     
180     :param xmlroot etree.Element: the Etree element where to search
181     :param name_node str: the name of node to search
182     :param key str: the key to search
183     :param value str: the value to search
184     :return: the found node
185     :rtype: xmlroot etree.Element
186     '''
187     l_nodes =  xmlroot.findall(name_node)
188     for node in l_nodes:
189         if key not in node.attrib.keys():
190             continue
191         if node.attrib[key] == value:
192             return node
193     return None
194     
195
196 def write_report(filename, xmlroot, stylesheet):
197     """Writes a report file from a XML tree.
198     
199     :param filename str: The path to the file to create
200     :param xmlroot etree.Element: the Etree element to write to the file
201     :param stylesheet str: The stylesheet to add to the begin of the file
202     """
203     if not os.path.exists(os.path.dirname(filename)):
204         os.makedirs(os.path.dirname(filename))
205
206     f = open(filename, "w")
207     f.write("<?xml version='1.0' encoding='utf-8'?>\n")
208     if len(stylesheet) > 0:
209         f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\n" % stylesheet)
210     f.write(etree.tostring(xmlroot, encoding='utf-8'))
211     f.close()   
212