b55b4768dab8a57163605fcf4b9e31f25aabb91c
[oam.git] / code / network-generator / network_generation / view / network_viewer.py
1 # Copyright 2023 highstreet technologies GmbH
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # !/usr/bin/python
16 """
17 Provides functions to convert the Network into different formats
18 """
19
20 import gzip
21 import json
22 from typing_extensions import Buffer
23 import zipfile
24 import xml.etree.ElementTree as ET
25 from typing import Any
26
27 from network_generation.model.python.o_ran_network import ORanNetwork
28
29
30 class NetworkViewer:
31     """
32     This class contains all functions converting the Network into
33     different formats
34     """
35
36     # constructor
37     def __init__(self, network: ORanNetwork) -> None:
38         self.__network = network
39
40     # json format
41
42     def json(self) -> "NetworkViewer":
43         """
44         Getter returns the class as json object
45         :return The class itself, as it is json serializable
46         """
47         return self
48
49     def show_as_json(self) -> None:
50         """
51         Method printing the class in json format.
52         """
53         print(self.__network.json())
54
55     def show(self) -> None:
56         """
57         Method printing the network
58         """
59         print(self.__network)
60
61     def save(self, filename: str, compressed: bool = True) -> None:
62         """
63         Method saving the class content to a file in json format.
64         :param filename: A valid path to a file on the system.
65         :param compressed: if True, svg is stored as svgz format.
66         :type filename: string
67         """
68         output: dict[str, Any] = self.__network.to_topology()
69         if compressed is True:
70             with gzip.open(f'{filename}-operational.json.gz', 'wb') as zf:
71                 zf.write(json.dumps(output, indent=2).encode('utf-8'))
72             print(f'File "{filename}-operational.json.gz" saved!')
73         else:
74             with open(
75                 f'{filename}-operational.json', "w", encoding="utf-8"
76             ) as jf:
77                 json.dump(output, jf, ensure_ascii=False, indent=2)
78             print(f'File "{filename}-operational.json" saved!')
79
80     def readStylesFromFile(self) -> str:
81         """
82         Method reading the css styles from known file
83         return: content of the file as string
84         """
85         with open("network_generation/view/svg.style.css") as styles:
86             content = styles.read()
87             return content
88
89     def svg(self, filename: str, compressed: bool = True) -> None:
90         """
91         Method saving the class content to a file in xml/svg format.
92
93         :param filename: A valid path to a file on the system.
94         :param compressed: if True, svg is stored as svgz format.
95         :type filename: string
96         """
97         root = self.__network.toSvg()
98         style = ET.Element("style")
99         style.text = self.readStylesFromFile()
100         root.findall(".//desc")[0].append(style)
101
102         if compressed is True:
103             svg_output: Buffer = ET.tostring(
104                 root, encoding="utf-8", xml_declaration=True)
105             with gzip.open(f'{filename}.svgz', 'wb') as zf:
106                 zf.write(svg_output)
107             print(f'File "{filename}.svgz" saved!')
108         else:
109             ET.ElementTree(root).write(
110                 f'{filename}.svg', encoding="utf-8", xml_declaration=True
111             )
112             print(f'File "{filename}.svg" saved!')
113
114     def kml(self, filename: str, compressed: bool = True) -> None:
115         """
116         Method saving the class content to a file in xml/kml format.
117
118         :param filename: A valid path to a file on the system.
119         :param compressed: if True, kml is stored as kmz format.
120         :type filename: string
121         """
122         root = self.__network.toKml()
123         with open("network_generation/view/kml.styles.json") as kml_styles:
124             styles: dict[str, dict] = json.load(kml_styles)
125             for key, value in styles.items():
126                 # add style
127                 style = ET.Element("Style", {"id": key})
128                 line_style = ET.SubElement(style, "LineStyle")
129                 color = ET.SubElement(line_style, "color")
130                 color.text = str(value["stroke"]["color"])
131                 width = ET.SubElement(line_style, "width")
132                 width.text = str(value["stroke"]["width"])
133                 poly_style = ET.SubElement(style, "PolyStyle")
134                 fill = ET.SubElement(poly_style, "color")
135                 fill.text = str(value["fill"]["color"])
136                 root.findall(".//Document")[0].append(style)
137
138         kml: str = ET.tostring(
139             root, encoding="utf-8", xml_declaration=True)
140         if compressed is True:
141             with zipfile.ZipFile(
142                 f'{filename}.kmz', 'w', zipfile.ZIP_DEFLATED
143             ) as zf:
144                 zf.writestr(f'{filename.split("/")[1]}.kml', data=kml)
145             print(f'File "{filename}.kmz" saved!')
146         else:
147             kml_file = open(f'{filename}.kml', 'w')
148             kml_file.write(kml)
149             kml_file.close()
150             print(f'File "{filename}.kml" saved!')