00001
00002
00003 import xml.dom.minidom
00004 import datetime
00005
00006
00007
00008
00009
00010
00011
00012
00013 class XMLValueException(Exception):
00014 def __init__(self, error_msg):
00015 super(XMLValueException, self).__init__(error_msg)
00016
00017
00018
00019
00020
00021
00022
00023 class XMLImageInformationDatabase:
00024
00025
00026
00027 def __init__(self, max_size=None):
00028 self.images = []
00029 self.max_size = max_size
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 def load(self, doc):
00049 text_node_type = xml.dom.minidom.Node.TEXT_NODE
00050 root = doc.documentElement
00051 if root.tagName != "imageInformationDatabase":
00052 raise XMLValueException("Expected imageInformationDatabase as root of document not " + root.tagName)
00053 images = root.getElementsByTagName("image")
00054 for image in images:
00055 if self.max_reached():
00056 break
00057 image_information = {}
00058 information_entries = image.getElementsByTagName("entry")
00059 for entry in information_entries:
00060 entry_type = entry.getAttribute("type")
00061 translate_function = None
00062 if entry_type == "int":
00063 translate_function = int
00064 elif entry_type == "float":
00065 translate_function = float
00066 elif entry_type == "string":
00067 translate_function = lambda x: x
00068 else:
00069 raise XMLValueException("Only 'int', 'float' and 'string' are allowed values for entries in image information. Got " + entry_type)
00070 name_node = entry.getElementsByTagName("name")[0]
00071 value_node = entry.getElementsByTagName("content")[0]
00072 name = ""
00073 value = ""
00074 for n in name_node.childNodes:
00075 if n.nodeType == text_node_type:
00076 name += n.data
00077 for n in value_node.childNodes:
00078 if n.nodeType == text_node_type:
00079 value += n.data
00080 image_information[name] = translate_function(value.strip()), entry_type
00081 self.images.append(image_information)
00082
00083 @staticmethod
00084
00085 def __information_entry_to_node(doc, type_name, name, content):
00086 root = doc.createElement("entry")
00087 attr = doc.createAttribute("type")
00088 attr.value = type_name
00089 root.setAttributeNode(attr)
00090
00091 name_node = doc.createElement("name")
00092 name_text_node = doc.createTextNode(name)
00093 name_node.appendChild(name_text_node)
00094 root.appendChild(name_node)
00095
00096 content_node = doc.createElement("content")
00097 content_text_node = doc.createTextNode(str(content))
00098 content_node.appendChild(content_text_node)
00099 root.appendChild(content_node)
00100
00101 return root
00102
00103 @staticmethod
00104
00105 def __create_image_node(doc, entries):
00106 root = doc.createElement("image")
00107 for entry_name, (value, type_name) in entries.items():
00108 root.appendChild( XMLImageInformationDatabase.__information_entry_to_node(doc, type_name, entry_name, value) )
00109 return root
00110
00111 @staticmethod
00112
00113 def __pretty_write_entry(typename, name, content, writer, indent, addindent, newl):
00114 writer.write(indent)
00115 writer.write('<entry type="')
00116 xml.dom.minidom._write_data(writer, typename)
00117 writer.write('">')
00118 writer.write(newl)
00119
00120 next_indent = indent + addindent
00121
00122 writer.write(next_indent)
00123 writer.write("<name>")
00124 xml.dom.minidom._write_data(writer, name)
00125 writer.write("</name>")
00126 writer.write(newl)
00127
00128 writer.write(next_indent)
00129 writer.write("<content>")
00130 xml.dom.minidom._write_data(writer, str(content))
00131 writer.write("</content>")
00132 writer.write(newl)
00133
00134 writer.write(indent)
00135 writer.write("</entry>")
00136 writer.write(newl)
00137
00138 @staticmethod
00139
00140 def __pretty_write_image(entries, writer, indent, addindent, newl):
00141 writer.write(indent)
00142 writer.write("<image>")
00143 writer.write(newl)
00144 for entry_name, (value, type_name) in entries.items():
00145 XMLImageInformationDatabase.__pretty_write_entry(type_name, entry_name, value, writer, indent + addindent, addindent, newl)
00146 writer.write(indent)
00147 writer.write("</image>")
00148 writer.write(newl)
00149
00150
00151
00152
00153
00154
00155
00156
00157 def write_pretty_xml(self, writer, addindent="\t", newl="\n"):
00158 writer.write('<?xml version="1.0" encoding="UTF-8"?>')
00159 writer.write(newl)
00160 writer.write(newl)
00161 writer.write("<!-- automatically generated on ")
00162 writer.write(str(datetime.date.today()))
00163 writer.write(" -->")
00164 writer.write(newl)
00165 writer.write("<!-- This file contains information about images used for the PR2 Drawing Faces module. Just technically stuff - no personal data! -->")
00166 writer.write(newl)
00167 writer.write(newl)
00168
00169 writer.write("<imageInformationDatabase>")
00170 writer.write(newl)
00171 for image in self.images:
00172 XMLImageInformationDatabase.__pretty_write_image(image, writer, addindent, addindent, newl)
00173 writer.write(newl)
00174 writer.write("</imageInformationDatabase>")
00175
00176
00177
00178
00179
00180
00181 def write_file(self, path):
00182 with open(path, "w") as f:
00183 self.write_pretty_xml(f)
00184
00185
00186
00187
00188
00189
00190 def load_file(self, path):
00191 self.load( xml.dom.minidom.parse(path) )
00192
00193
00194
00195 def max_reached(self):
00196 if self.max_size is None:
00197 return False
00198 return len(self.images) >= self.max_size
00199
00200
00201
00202
00203
00204
00205 def append(self, entry):
00206 if self.max_reached():
00207 self.images[0] = entry
00208 else:
00209 self.images.append(entry)