|
|
@ -2,6 +2,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
from birdvisu.annotations import AnnotatedTopology, AnnotatorID
|
|
|
|
from birdvisu.annotations import AnnotatedTopology, AnnotatorID
|
|
|
|
from birdvisu.annotations.analysis import TopologyDifference, ShortestPathTree
|
|
|
|
from birdvisu.annotations.analysis import TopologyDifference, ShortestPathTree
|
|
|
|
|
|
|
|
from birdvisu.annotations.layout import MegaStyler
|
|
|
|
from birdvisu.ospfsock import BirdSocketConnection
|
|
|
|
from birdvisu.ospfsock import BirdSocketConnection
|
|
|
|
from birdvisu.providers import BirdSocketTopologyProvider, OspfFileTopologyProvider, OspfFileParseError
|
|
|
|
from birdvisu.providers import BirdSocketTopologyProvider, OspfFileTopologyProvider, OspfFileParseError
|
|
|
|
from birdvisu.topo_v3 import TopologyV3, VertexID
|
|
|
|
from birdvisu.topo_v3 import TopologyV3, VertexID
|
|
|
@ -100,27 +101,19 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
|
|
MoveTopology = auto()
|
|
|
|
MoveTopology = auto()
|
|
|
|
ShortestPath = auto()
|
|
|
|
ShortestPath = auto()
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *a, **kwa):
|
|
|
|
def create_menus(self):
|
|
|
|
super().__init__(*a, **kwa)
|
|
|
|
print('Creating menus…')
|
|
|
|
self.ref_topo_provider = None
|
|
|
|
|
|
|
|
self.cur_topo_provider = None
|
|
|
|
|
|
|
|
self.annotators = self.get_annotators()
|
|
|
|
|
|
|
|
self.annot_topo = None
|
|
|
|
|
|
|
|
self.highlighter = None
|
|
|
|
|
|
|
|
self.tool = self.Tool.MoveTopology
|
|
|
|
|
|
|
|
self.scene = QtWidgets.QGraphicsScene()
|
|
|
|
|
|
|
|
self.view = QtWidgets.QGraphicsView(self.scene)
|
|
|
|
|
|
|
|
self.view.setDragMode(self.view.DragMode.ScrollHandDrag)
|
|
|
|
|
|
|
|
self.setCentralWidget(self.view)
|
|
|
|
|
|
|
|
self.statusbar = self.statusBar()
|
|
|
|
|
|
|
|
self.statusbar.showMessage('Hello!')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.menubar = self.menuBar()
|
|
|
|
self.menubar = self.menuBar()
|
|
|
|
mode_menu = self.menubar.addMenu('&Mode')
|
|
|
|
mode_menu = self.menubar.addMenu('&Mode')
|
|
|
|
short_path_act = QtGui.QAction("Sh. path &DAG", self)
|
|
|
|
short_path_act = QtGui.QAction("Sh. path &DAG", self)
|
|
|
|
short_path_act.triggered.connect(self.shortestPathMode)
|
|
|
|
short_path_act.triggered.connect(self.shortestPathMode)
|
|
|
|
mode_menu.addAction(short_path_act)
|
|
|
|
mode_menu.addAction(short_path_act)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Hack!
|
|
|
|
|
|
|
|
autoload_act = QtGui.QAction("&Load automatically", self)
|
|
|
|
|
|
|
|
autoload_act.triggered.connect(self.autoLoad)
|
|
|
|
|
|
|
|
self.menubar.addAction(autoload_act)
|
|
|
|
|
|
|
|
|
|
|
|
topo_menu = self.menubar.addMenu('&Topology')
|
|
|
|
topo_menu = self.menubar.addMenu('&Topology')
|
|
|
|
open_ref_act = QtGui.QAction("&Load reference", self)
|
|
|
|
open_ref_act = QtGui.QAction("&Load reference", self)
|
|
|
|
open_ref_act.triggered.connect(self.openRefTopology)
|
|
|
|
open_ref_act.triggered.connect(self.openRefTopology)
|
|
|
@ -138,10 +131,38 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
|
|
refresh_act.triggered.connect(self.refreshTopologies)
|
|
|
|
refresh_act.triggered.connect(self.refreshTopologies)
|
|
|
|
topo_menu.addAction(refresh_act)
|
|
|
|
topo_menu.addAction(refresh_act)
|
|
|
|
|
|
|
|
|
|
|
|
def get_annotators(self):
|
|
|
|
def __init__(self, *a, **kwa):
|
|
|
|
return [
|
|
|
|
super().__init__(*a, **kwa)
|
|
|
|
AnnotatorID(TopologyDifference),
|
|
|
|
self.ref_topo_provider = None
|
|
|
|
AnnotatorID(ShortestPathTree, (VertexID(
|
|
|
|
self.cur_topo_provider = None
|
|
|
|
|
|
|
|
self.set_initial_annotators()
|
|
|
|
|
|
|
|
self.annot_topo = None
|
|
|
|
|
|
|
|
self.highlighter = None
|
|
|
|
|
|
|
|
self.tool = self.Tool.MoveTopology
|
|
|
|
|
|
|
|
self.scene = QtWidgets.QGraphicsScene()
|
|
|
|
|
|
|
|
self.view = QtWidgets.QGraphicsView(self.scene)
|
|
|
|
|
|
|
|
self.view.setDragMode(self.view.DragMode.ScrollHandDrag)
|
|
|
|
|
|
|
|
self.setCentralWidget(self.view)
|
|
|
|
|
|
|
|
self.statusbar = self.statusBar()
|
|
|
|
|
|
|
|
self.statusbar.showMessage('Hello!')
|
|
|
|
|
|
|
|
self.create_menus()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#Hack
|
|
|
|
|
|
|
|
@Slot()
|
|
|
|
|
|
|
|
def autoLoad(self):
|
|
|
|
|
|
|
|
print('Auto-loading…')
|
|
|
|
|
|
|
|
self.ref_topo_provider = OspfFileTopologyProvider('./empty.ospf')
|
|
|
|
|
|
|
|
self.cur_topo_provider = BirdSocketTopologyProvider(instance='gennet4', area=1, version=2)
|
|
|
|
|
|
|
|
self.refreshTopologies()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_initial_annotators(self):
|
|
|
|
|
|
|
|
# We have three kinds of annotators:
|
|
|
|
|
|
|
|
# - The essential analytic ones (TopologyDifference)
|
|
|
|
|
|
|
|
# - The one that describes the current tool (when that is Annotator backed, like for ShortestPathTree)
|
|
|
|
|
|
|
|
# - The styling ones, that actually help visualise stuff (MegaStyler)
|
|
|
|
|
|
|
|
self.essential_annotators = [AnnotatorID(TopologyDifference)]
|
|
|
|
|
|
|
|
self.current_annotators = [AnnotatorID(ShortestPathTree, (VertexID(
|
|
|
|
family=None,
|
|
|
|
family=None,
|
|
|
|
is_router=True,
|
|
|
|
is_router=True,
|
|
|
|
address=None,
|
|
|
|
address=None,
|
|
|
@ -150,6 +171,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
|
|
discriminator=None
|
|
|
|
discriminator=None
|
|
|
|
), 'current')),
|
|
|
|
), 'current')),
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
self.styling_annotators = [AnnotatorID(MegaStyler, tuple(self.essential_annotators + self.current_annotators))]
|
|
|
|
|
|
|
|
|
|
|
|
@Slot()
|
|
|
|
@Slot()
|
|
|
|
def shortestPathMode(self):
|
|
|
|
def shortestPathMode(self):
|
|
|
@ -222,15 +244,34 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
|
|
combined_topology = TopologyV3.combine_topologies(reference=ref_topo, current=cur_topo)
|
|
|
|
combined_topology = TopologyV3.combine_topologies(reference=ref_topo, current=cur_topo)
|
|
|
|
combined_topology.freeze()
|
|
|
|
combined_topology.freeze()
|
|
|
|
self.annot_topo = AnnotatedTopology(combined_topology)
|
|
|
|
self.annot_topo = AnnotatedTopology(combined_topology)
|
|
|
|
for ann_id in self.annotators:
|
|
|
|
for ann_id in self.essential_annotators + self.current_annotators + self.styling_annotators:
|
|
|
|
self.annot_topo.run_annotator(ann_id)
|
|
|
|
self.annot_topo.run_annotator(ann_id)
|
|
|
|
# Draw it
|
|
|
|
# Draw it
|
|
|
|
self.set_current_highlighter()
|
|
|
|
self.draw_visu()
|
|
|
|
self.ad_hoc_draw_visu()
|
|
|
|
|
|
|
|
|
|
|
|
def draw_visu(self):
|
|
|
|
|
|
|
|
# just take the result of the MegaStyler and create vertices according to the style.
|
|
|
|
|
|
|
|
megastyler = self.styling_annotators[-1]
|
|
|
|
|
|
|
|
assert megastyler.annotator == MegaStyler
|
|
|
|
|
|
|
|
msann = self.annot_topo.annotations[megastyler]
|
|
|
|
|
|
|
|
self.graphicsitems: dict[VertexID, QGraphicsItem] = dict()
|
|
|
|
|
|
|
|
self.topologyitems: dict[QGraphicsItem, VertexID|Edge] = dict()
|
|
|
|
|
|
|
|
for vtxid, style in msann.for_vertex.items():
|
|
|
|
|
|
|
|
gritem = self.create_vertex(vtxid, style)
|
|
|
|
|
|
|
|
self.graphicsitems[vtxid] = gritem
|
|
|
|
|
|
|
|
self.topologyitems[gritem] = vtxid
|
|
|
|
|
|
|
|
self.scene.addItem(gritem)
|
|
|
|
|
|
|
|
for edge, style in msann.for_edge.items():
|
|
|
|
|
|
|
|
gritem = self.create_edge(edge, style)
|
|
|
|
|
|
|
|
self.graphicsitems[edge] = gritem
|
|
|
|
|
|
|
|
self.topologyitems[gritem] = edge
|
|
|
|
|
|
|
|
self.scene.addItem(gritem)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_vertex(self, vtxid, style):
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
def set_current_highlighter(self):
|
|
|
|
def create_edge(self, edge, style):
|
|
|
|
# TODO!
|
|
|
|
...
|
|
|
|
self.highlighter = self.annotators[-1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ad_hoc_draw_visu(self):
|
|
|
|
def ad_hoc_draw_visu(self):
|
|
|
|
shapes = dict()
|
|
|
|
shapes = dict()
|
|
|
|