From b841a0f57bc80d214eab6ea4878e1b5ca4bb4216 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 13 Jul 2016 16:37:05 +0200 Subject: [PATCH] Support image in conversion from old topologies --- gns3server/controller/topology.py | 24 ++++++++++++++++-- .../1_5_images/after/1_5_image.gns3 | 23 +++++++++++++++++ .../after/project-files/images/gns3_logo.png | Bin 0 -> 7921 bytes .../1_5_images/before/1_5_image.gns3 | 17 +++++++++++++ .../before/project-files/images/gns3_logo.png | Bin 0 -> 7921 bytes 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/topologies/1_5_images/after/1_5_image.gns3 create mode 100644 tests/topologies/1_5_images/after/project-files/images/gns3_logo.png create mode 100644 tests/topologies/1_5_images/before/1_5_image.gns3 create mode 100644 tests/topologies/1_5_images/before/project-files/images/gns3_logo.png diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py index c0457467..3e80c7fc 100644 --- a/gns3server/controller/topology.py +++ b/gns3server/controller/topology.py @@ -307,11 +307,31 @@ def _convert_1_3_later(topo, topo_path): "x": int(note["x"]), "y": int(note["y"]), "z": int(note.get("z", 0)), - "rotation": int(ellipse.get("rotation", 0)), + "rotation": int(note.get("rotation", 0)), "svg": svg } new_topo["topology"]["drawings"].append(new_note) + # Images + for image in topo.get("images", []): + img_path = image["path"] + # Absolute image path are rewrite to project specific image + if os.path.abspath(img_path): + try: + os.makedirs(os.path.join(topo_dir, "images"), exist_ok=True) + shutil.copy(img_path, os.path.join(topo_dir, "images", os.path.basename(img_path))) + except OSError: + pass + new_image = { + "drawing_id": str(uuid.uuid4()), + "x": int(image["x"]), + "y": int(image["y"]), + "z": int(image.get("z", 0)), + "rotation": int(image.get("rotation", 0)), + "svg": os.path.basename(img_path) + } + new_topo["topology"]["drawings"].append(new_image) + # Rectangles for rectangle in topo.get("rectangles", []): svg = ''.format( @@ -325,7 +345,7 @@ def _convert_1_3_later(topo, topo_path): "x": int(rectangle["x"]), "y": int(rectangle["y"]), "z": int(rectangle.get("z", 0)), - "rotation": int(ellipse.get("rotation", 0)), + "rotation": int(rectangle.get("rotation", 0)), "svg": svg } new_topo["topology"]["drawings"].append(new_rectangle) diff --git a/tests/topologies/1_5_images/after/1_5_image.gns3 b/tests/topologies/1_5_images/after/1_5_image.gns3 new file mode 100644 index 00000000..24099682 --- /dev/null +++ b/tests/topologies/1_5_images/after/1_5_image.gns3 @@ -0,0 +1,23 @@ +{ + "auto_start": false, + "name": "1_5_image", + "project_id": "ANYUUID", + "revision": 5, + "topology": { + "computes": [], + "drawings": [ + { + "drawing_id": "ANYUUID", + "rotation": 0, + "svg": "gns3_logo.png", + "x": -64, + "y": -64, + "z": 0 + } + ], + "links": [], + "nodes": [] + }, + "type": "topology", + "version": "ANYSTR" +} diff --git a/tests/topologies/1_5_images/after/project-files/images/gns3_logo.png b/tests/topologies/1_5_images/after/project-files/images/gns3_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dd412d33086260bb33d519b23716caf7abdbb5be GIT binary patch literal 7921 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