the big merge
[nepi.git] / src / nepi / util / parsers / xml_parser.py
index ca68be1..d82ea69 100644 (file)
@@ -3,9 +3,8 @@
 #    Copyright (C) 2013 INRIA
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU General Public License version 2 as
+#    published by the Free Software Foundation;
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -17,6 +16,8 @@
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
+from __future__ import print_function
+
 from nepi.util.netgraph import NetGraph, TopologyType 
 from nepi.util.timefuncs import stformat, tsformat
 
@@ -31,22 +32,44 @@ BOOL = "bool"
 INTEGER = "integer"
 DOUBLE = "float"
 
-def xmlencode(s):
-    if isinstance(s, str):
-        rv = s.decode("latin1")
-    if isinstance(s, datetime.datetime):
-        rv = tsformat(s)
-    elif not isinstance(s, unicode):
-        rv = unicode(s)
-    else:
-        rv = s
-    return rv.replace(u'\x00',u'&#0000;')
-
+from six import PY2
+
+if PY2:
+    # xxx old py2 code had a hack, that had 'latin1' hardcoded
+    # as the encoding for 8-byte strings
+    # this is very wrong; I keep it for now
+    # but will probably remove it altogether some day
+    def xmlencode(s):
+        """xml encoder for python2"""
+        if isinstance(s, str):
+            rv = s.decode("latin1")
+        if isinstance(s, datetime.datetime):
+            rv = tsformat(s)
+        elif not isinstance(s, unicode):
+            rv = unicode(s)
+        else:
+            rv = s
+        return rv.replace(u'\x00',u'&#0000;')
+else:
+    # use sys.getdefaultencoding() to decode bytes into string
+    def xmlencode(s):
+        """xml encoder for python3"""
+        if isinstance(s, datetime.datetime):
+            rv = tsformat(s)
+        elif isinstance(s, bytes):
+            rv = s.decode(sys.getdefaultencoding())
+        else:
+            rv = s
+        return rv.replace('\x00', '&#0000;')
+        
 def xmldecode(s, cast = str):
-    ret = s.replace(u'&#0000',u'\x00').encode("ascii")
-    ret = cast(ret)
-    if s == "None":
+    if s is None:
         return None
+    if PY2:
+        ret = s.replace(u'&#0000', u'\x00').encode("ascii")
+    else:
+        ret = s.replace('&#0000', '\x00')
+    ret = cast(ret)
     return ret
 
 def from_type(value):
@@ -82,7 +105,7 @@ class ECXMLParser(object):
         try:
             xml = doc.toprettyxml(indent="    ", encoding="UTF-8")
         except:
-            print >>sys.stderr, "Oops: generating XML from %s" % (data,)
+            print("Oops: generating XML from %s" % (data,), file=sys.stderr)
             raise
         
         return xml
@@ -101,7 +124,7 @@ class ECXMLParser(object):
         rmsnode = doc.createElement("rms")
         ecnode.appendChild(rmsnode)
 
-        for guid, rm in ec._resources.iteritems():
+        for guid, rm in ec._resources.items():
             self._rm_to_xml(doc, rmsnode, ec, guid, rm)
 
         return doc
@@ -121,6 +144,7 @@ class ECXMLParser(object):
         for nid in ec.netgraph.nodes():
             ngnnode = doc.createElement("node")
             ngnnode.setAttribute("nid", xmlencode(nid))
+            ngnnode.setAttribute("nid-type", from_type(nid))
             ngnsnode.appendChild(ngnnode)
 
             # Mark ources and targets
@@ -152,7 +176,9 @@ class ECXMLParser(object):
         for nid1, nid2 in ec.netgraph.edges():
             ngenode = doc.createElement("edge")
             ngenode.setAttribute("nid1", xmlencode(nid1))
+            ngenode.setAttribute("nid1-type", from_type(nid1))
             ngenode.setAttribute("nid2", xmlencode(nid2))
+            ngenode.setAttribute("nid2-type", from_type(nid2))
             ngesnode.appendChild(ngenode)
 
             # Edge annotations
@@ -221,7 +247,7 @@ class ECXMLParser(object):
         cnnode = doc.createElement("conditions")
         conditions = False
 
-        for action, conds in rm._conditions.iteritems():
+        for action, conds in rm._conditions.items():
             conditions = True
             for (group, state, time) in conds:
                 ccnnode = doc.createElement("condition")
@@ -267,12 +293,18 @@ class ECXMLParser(object):
                 os.environ["NEPI_NTHREADS"] = nthreads
 
                 # Deserialize netgraph
+                topology = None
+                topo_type = None
+
                 netgraph = self._netgraph_from_xml(doc, ecnode)
-                topo_type = netgraph.topo_type if netgraph else None
+                
+                if netgraph:
+                    topo_type = netgraph.topo_type
+                    topology = netgraph.topology
 
                 # Instantiate EC
                 ec = ExperimentController(exp_id = exp_id, local_dir = local_dir, 
-                        topology = netgraph.topology, topo_type = topo_type)
+                        topology = topology, topo_type = topo_type)
 
                 connections = set()
 
@@ -305,6 +337,8 @@ class ECXMLParser(object):
                 ngnsnode = ngnsnode_list[0].getElementsByTagName("node") 
                 for ngnnode in ngnsnode:
                     nid = xmldecode(ngnnode.getAttribute("nid"))
+                    tipe = xmldecode(ngnnode.getAttribute("nid-type"))
+                    nid = to_type(tipe, nid)
                     netgraph.add_node(nid)
 
                     if ngnnode.hasAttribute("source"):
@@ -334,7 +368,13 @@ class ECXMLParser(object):
                 ngesnode = ngesnode_list[0].getElementsByTagName("edge") 
                 for ngenode in ngesnode:
                     nid1 = xmldecode(ngenode.getAttribute("nid1"))
+                    tipe1 = xmldecode(ngenode.getAttribute("nid1-type"))
+                    nid1 = to_type(tipe1, nid1)
+
                     nid2 = xmldecode(ngenode.getAttribute("nid2"))
+                    tipe2 = xmldecode(ngenode.getAttribute("nid2-type"))
+                    nid2 = to_type(tipe2, nid2)
+
                     netgraph.add_edge(nid1, nid2)
 
                     annosnode_list = ngenode.getElementsByTagName("edge-annotations")