#!/usr/bin/env python3 # Get topologies import sys from birdvisu.providers import BirdSocketTopologyProvider, OspfFileTopologyProvider ref_topo_file = 'reference.ospf' if len(sys.argv) > 1: ref_topo_file = sys.argv[1] ref_topo = OspfFileTopologyProvider(ref_topo_file).get_topology() try: cur_topo = BirdSocketTopologyProvider(instance='ospf1', area=0).get_topology() except OSError as e: raise NotImplementedError('Cannot create a mock topology atm') from e # Create combined topology from birdvisu.topo_v3 import TopologyV3 combined_topology = TopologyV3.combine_topologies(reference=ref_topo, current=cur_topo) combined_topology.freeze() # Annotate it from birdvisu.topo_v3 import VertexID from birdvisu.annotations import AnnotatedTopology, AnnotatorID from birdvisu.annotations.analysis import TopologyDifference, ShortestPathTree from ipaddress import IPv4Address annot_topo = AnnotatedTopology(combined_topology) annotators = [ AnnotatorID(TopologyDifference), AnnotatorID(ShortestPathTree, (VertexID( family=None, is_router=True, address=None, router_id=int(IPv4Address('172.23.100.10')), dr_id=None, discriminator=None ), 'current')), ] for ann_id in annotators: annot_topo.run_annotator(ann_id) # --- # Show it #from birdvisu.visualisation import annotators #from birdvisu import maps_new # annotators.create_qgritems does not like being run without Qt initialization. from PySide6 import QtCore, QtGui, QtWidgets app = QtWidgets.QApplication([]) #annotated_topology = maps_new.annotate_topology(combined_topology, # # A semi-canonical set of annotators: # [ # annotators.extract_positions, # annotators.random_position, # annotators.assign_brushes, # annotators.create_qgritems, # ] # ) from random import randint from collections import defaultdict shapes = dict() nei = defaultdict(lambda: []) class MyGraphicsRectItem(QtWidgets.QGraphicsRectItem): #def __init__(self, *a, **kwa): # return super().__init__(*a, **kwa) #def itemChange(self, change, val): # return super().itemChange(change, val) def mouseMoveEvent(self, evt): vtxid = self.data(0) for e in nei[vtxid]: x1 = self.x() y1 = self.y() other = e.source if e.source != vtxid else e.target x2 = shapes[other].x() y2 = shapes[other].y() qlinef = QtCore.QLineF(x1, y1, x2, y2) shapes[e].setLine(qlinef) return super().mouseMoveEvent(evt) for k, v in annot_topo.topology.vertices.items(): size = 30 if k.is_router else 10 x, y = randint(0, 1920), randint(0, 1080) shape = MyGraphicsRectItem(-size/2, -size/2, size, size) shape.setPos(x,y) # TODO:brush label_text = str(IPv4Address(k.router_id)) if k.is_router else str(k.address) # Surprisingly works for all the possible addresses. label = QtWidgets.QGraphicsSimpleTextItem(label_text, parent=shape) label.setY(size*0.8) text_width = label.boundingRect().width() label.setX(-text_width/2) shape.setData(0, k) shape.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemIsSelectable) shapes[k] = shape for e in annot_topo.topology.edges: start = shapes[e.source].pos() end = shapes[e.target].pos() qlinef = QtCore.QLineF(start, end) line = QtWidgets.QGraphicsLineItem(qlinef) line.setData(0, e) nei[e.source].append(e) nei[e.target].append(e) shapes[e] = line # Render the widget scene = QtWidgets.QGraphicsScene() #for tagsrc in [ # annotated_topology.router_annotations.values(), # annotated_topology.network_annotations.values(), # annotated_topology.link_annotations.values(), # ]: # for taglist in tagsrc: # assert len(taglist) > 0 # assert isinstance(taglist[-1], QtWidgets.QGraphicsItem) # scene.addItem(taglist[-1]) for sh in shapes.values(): scene.addItem(sh) view = QtWidgets.QGraphicsView(scene) view.setDragMode(view.DragMode.ScrollHandDrag) #view.show() main_window = QtWidgets.QMainWindow() main_window.setCentralWidget(view) menu = main_window.menuBar().addMenu('Hello') act = QtGui.QAction('Hi') #act.setToolTip('Howdy') menu.addAction(act) main_window.show() app.exec()