extract nodeview and nodemodel
[sface.git] / sface / screens / mainscreen.py
1
2 import os
3 from PyQt4.QtCore import *
4 from PyQt4.QtGui import *
5
6 from sfa.util.rspecHelper import RSpec
7 from sface.sfahelper import *
8 from sface.sficonfig import config
9 from sface.sfiprocess import SfiProcess
10 from sface.screens.sfascreen import SfaScreen
11
12 class NodeView(QTreeView):
13     def __init__(self, parent):
14         QTreeView.__init__(self, parent)
15
16         self.setRootIsDecorated(False)
17         self.setAlternatingRowColors(True)
18         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
19
20 class NodeModel(QStandardItemModel):
21     def __init__(self, parent):
22         QStandardItemModel.__init__(self, 0, 3, parent)
23         self.setHeaderData(0, Qt.Horizontal, QString("Testbed"))
24         self.setHeaderData(1, Qt.Horizontal, QString("Hostname"))
25         self.setHeaderData(2, Qt.Horizontal, QString("IsIn"))
26
27
28 class SliceWidget(QWidget):
29     def __init__(self, parent):
30         QWidget.__init__(self, parent)
31
32         self.nodeView = NodeView(self)
33         self.nodeModel = NodeModel(self)
34         self.nodeView.setModel(self.nodeModel)
35
36         refresh = QLabel("<a href='refresh'>Refresh</a>", self)
37         refresh.setScaledContents(False)
38         slicename = QLabel ("Slice : %s"%(config.getSlice() or "None"),self)
39         slicename.setScaledContents(False)
40
41         hlayout = QHBoxLayout()
42         hlayout.addWidget(slicename)
43         hlayout.addStretch()
44         hlayout.addWidget(refresh)
45
46         layout = QVBoxLayout()
47         layout.addLayout(hlayout)
48         layout.addWidget(self.nodeView)
49         self.setLayout(layout)
50         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
51
52         self.connect(refresh, SIGNAL('linkActivated(QString)'), self.refresh)
53
54         rspec_file = os.path.expanduser("~/.sfi/%s.rspec" % config.getSlice())
55         if os.path.exists(rspec_file):
56             self.updateView()
57         
58     def readSliceRSpec(self):
59         rspec_file = os.path.expanduser("~/.sfi/%s.rspec" % config.getSlice())
60         xml = open(rspec_file).read()
61         return xml
62
63     def refresh(self, link=None):
64         if not config.getSlice():
65             self.parent().setStatus("<font color='red'>Slice not set yet!</font>")
66             return
67
68         self.process = SfiProcess()
69         outfile = self.process.getRSpecFromSM()
70         self.parent().setStatus("Updating slice data. This may take some time...")
71         
72         self.connect(self.process, SIGNAL('finished()'), self.refreshFinished)
73
74     def refreshFinished(self):
75         del self.process
76         self.parent().setStatus("<font color='green'>Slice data updated.</font>")
77         self.updateView()
78
79     def updateView(self):
80         rspec_string = self.readSliceRSpec()
81         networks = rspec_get_networks(rspec_string)
82         networks.reverse()
83
84         for network in networks:
85 #            nodes = self.rspec_get_sliver_nodes_from_network(rspec_string, network)
86 #            for node in nodes: self.addNode(network, node, True)
87 #            nodes = self.rspec_get_other_nodes_from_network(rspec_string, network)
88 #            for node in nodes: self.addNode(network, node, False)
89             # hacky - i'm just gettin used to this xml navigation stuff
90             xml_nodes = rspec_get_xml_nodes_from_network(rspec_string, network)
91             from lxml import etree
92             # addNode inserts before, so let's start with the ones that are not in
93             for xml_node in xml_nodes:
94                 if not xml_node.xpath('sliver'): 
95                     self.addNode(network, xml_node.xpath('hostname/text()')[0],False)
96             for xml_node in xml_nodes:
97                 if xml_node.xpath('sliver'): 
98                     self.addNode(network, xml_node.xpath('hostname/text()')[0],True)
99                 
100
101     def addNode(self, testbed, hostname, mark):
102         self.nodeModel.insertRow(0)
103         self.nodeModel.setData(self.nodeModel.index(0,0), QString(testbed))
104         self.nodeModel.setData(self.nodeModel.index(0,1), QString(hostname))
105         if mark:msg="x"
106         else:   msg="-"
107         self.nodeModel.setData(self.nodeModel.index(0,2), QString(msg))
108
109
110 class MainScreen(SfaScreen):
111     def __init__(self, parent):
112         SfaScreen.__init__(self, parent)
113
114         slice = SliceWidget(self)
115         self.init(slice, "Main Window", "PlanetLab Federation GUI")