From: smbaker Date: Wed, 24 Aug 2011 01:31:00 +0000 (-0700) Subject: check in slice user management screen X-Git-Tag: sface-0.1-17~6 X-Git-Url: http://git.onelab.eu/?p=sface.git;a=commitdiff_plain;h=7ea27c8a5bb47cce1d9cc5a9c6e40d56ed11026d check in slice user management screen --- diff --git a/sface/screens/userscreen.py b/sface/screens/userscreen.py new file mode 100644 index 0000000..53c279f --- /dev/null +++ b/sface/screens/userscreen.py @@ -0,0 +1,301 @@ + +import datetime +import os +import pickle +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from sfa.util.record import SfaRecord, SliceRecord, AuthorityRecord, UserRecord +from sface.config import config +from sface.sfiprocess import SfiProcess +from sface.screens.sfascreen import SfaScreen + +NAME_COLUMN = 0 +ROLE_COLUMN = 1 +MEMBERSHIP_STATUS_COLUMN = 2 +SERVER_MEMBERSHIP_STATUS_COLUMN = 3 + +user_status = { "in": "Already Selected", + "out": "Not Selected", + "add": "To be Added", + "remove": "To be Removed"} + +class UserView(QTableView): + def __init__(self, parent=None): + QTableView.__init__(self, parent) + + self.setSelectionBehavior(QAbstractItemView.SelectRows) + self.setSelectionMode(QAbstractItemView.SingleSelection) + self.setAlternatingRowColors(True) + self.setAttribute(Qt.WA_MacShowFocusRect, 0) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + self.setToolTip("Double click on a row to change its status.") + + def mouseDoubleClickEvent(self, event): + index = self.currentIndex() + model = index.model() + status_index = model.index(index.row(), MEMBERSHIP_STATUS_COLUMN, index.parent()) + status_data = status_index.data().toString() + server_status_data = model.index(index.row(), SERVER_MEMBERSHIP_STATUS_COLUMN, index.parent()).data().toString() + node_index = model.index(index.row(), NAME_COLUMN, index.parent()) + node_data = node_index.data().toString() + + # This is a hostname + if status_data == user_status['in']: + model.setData(status_index, QString(user_status['remove'])) + elif status_data == user_status['out']: + model.setData(status_index, QString(user_status['add'])) + elif status_data in (user_status['add'], user_status['remove']): + if server_status_data == user_status["in"]: + model.setData(status_index, QString(user_status['in'])) + else: + model.setData(status_index, QString(user_status['out'])) + + model.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), node_index, node_index) + + def currentChanged(self, current, previous): + model = current.model() + node_index = model.index(current.row(), 0, current.parent()) + node_data = node_index.data().toString() + self.emit(SIGNAL('hostnameClicked(QString)'), node_data) + + +class UsersWidget(QWidget): + def __init__(self, parent): + QWidget.__init__(self, parent) + + self.process = SfiProcess(self) + + self.slicename = QLabel("", self) + self.updateSliceName() + self.slicename.setScaledContents(False) + searchlabel = QLabel ("Search: ", self) + searchlabel.setScaledContents(False) + searchbox = QLineEdit(self) + searchbox.setAttribute(Qt.WA_MacShowFocusRect, 0) + + toplayout = QHBoxLayout() + toplayout.addWidget(self.slicename, 0, Qt.AlignLeft) + toplayout.addStretch() + toplayout.addWidget(searchlabel, 0, Qt.AlignRight) + toplayout.addWidget(searchbox, 0, Qt.AlignRight) + + self.userView = UserView() + #self.userView.setSelectionBehavior(QAbstractItemView.SelectRows) + #self.userView.setSelectionMode(QAbstractItemView.SingleSelection) + + refresh = QPushButton("Refresh", self) + refresh.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) + submit = QPushButton("Submit", self) + submit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) + + bottomlayout = QHBoxLayout() + bottomlayout.addWidget(refresh, 0, Qt.AlignLeft) + bottomlayout.addStretch() + bottomlayout.addWidget(submit, 0, Qt.AlignRight) + + layout = QVBoxLayout() + layout.addLayout(toplayout) + layout.addWidget(self.userView) + layout.addLayout(bottomlayout) + self.setLayout(layout) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + self.userModel = QStandardItemModel(0, 4, self) + + self.connect(refresh, SIGNAL('clicked()'), self.refresh) + self.connect(submit, SIGNAL('clicked()'), self.submit) + + self.updateView() + + def submitFinished(self): + self.setStatus("Slice data submitted.") + QTimer.singleShot(1000, self.refresh) + + def getSliceRecordFinished(self): + self.setStatus("Authority data refreshed.", timeout=5000) + self.refreshAuthority() + + def getAuthorityRecordFinished(self): + self.setStatus("Slice data refreshed.", timeout=5000) + self.updateView() + #self.parent().signalAll("usersUpdated") + + def readSliceRecord(self): + rec_file = config.getSliceRecordFile() + if os.path.exists(rec_file): + xml = open(rec_file).read() + rec = SliceRecord() + rec.load_from_string(xml) + return rec + return None + + def readAuthorityRecord(self): + rec_file = config.getAuthorityRecordFile() + if os.path.exists(rec_file): + xml = open(rec_file).read() + rec = AuthorityRecord() + rec.load_from_string(xml) + return rec + return None + + def readUserRecord(self, i): + rec_file = config.getAuthorityListFile(i) + if os.path.exists(rec_file): + xml = open(rec_file).read() + rec = UserRecord() + rec.load_from_string(xml) + return rec + return None + + def setStatus(self, msg, timeout=None): + self.parent().setStatus(msg, timeout) + + def checkRunningProcess(self): + if self.process.isRunning(): + self.setStatus("There is already a process running. Please wait.") + return True + return False + + def submit(self): + if self.checkRunningProcess(): + return + + rec = self.readSliceRecord() + change = self.process_table(rec) + + if not change: + self.setStatus("No change in slice data. Not submitting!", timeout=3000) + return + + rec_file = config.getSliceRecordFile() + file(rec_file, "w").write(rec.save_to_string()) + + self.disconnect(self.process, SIGNAL('finished()'), self.getAuthorityRecordFinished) + self.connect(self.process, SIGNAL('finished()'), self.submitFinished) + + self.process.updateRecord(rec_file) + self.setStatus("Sending slice record. This will take some time...") + + def refresh(self): + if not config.getSlice(): + self.setStatus("Slice not set yet!") + return + + if self.process.isRunning(): + self.setStatus("There is already a process running. Please wait.") + return + + self.disconnect(self.process, SIGNAL('finished()'), self.submitFinished) + self.connect(self.process, SIGNAL('finished()'), self.getSliceRecordFinished) + + self.process.getSliceRecord() + self.setStatus("Refreshing slice record. This will take some time...") + + def refreshAuthority(self): + self.disconnect(self.process, SIGNAL('finished()'), self.getSliceRecordFinished) + self.connect(self.process, SIGNAL('finished()'), self.getAuthorityRecordFinished) + + self.process.listRecords(config.getAuthority(), "user", config.getAuthorityListFile()) + self.setStatus("Refreshing user records. This will take some time...") + + def addTableItem(self, table, row, col, val, data=None, readonly=True): + item = QTableWidgetItem(str(val)) + if readonly: + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) + if data: + if not isinstance(data, str): + data = pickle.dumps(data) + item.setData(Qt.UserRole, QVariant(data)) + table.setItem(row, col, item) + + def updateModel(self): + self.userModel.clear() + + sliceRec = self.readSliceRecord() + if not sliceRec: + return None + + added_persons = [] + slice_persons = [] + + for pi in sliceRec.get_field("PI"): + name = str(pi) + if not name in added_persons: + slice_persons.append({"name": name, "role": "PI", "member": user_status["in"]}) + added_persons.append(name) + for researcher in sliceRec.get_field("researcher"): + name = str(researcher) + if not name in added_persons: + slice_persons.append({"name": name, "role": "researcher", "member": user_status["in"]}) + added_persons.append(name) + + i=1 + while (os.path.exists(config.getAuthorityListFile(i))): + rec = self.readUserRecord(i) + if rec: + name = str(rec.get_name()) + if not name in added_persons: + slice_persons.append({"name": name, "role": "", "member": user_status["out"]}) + added_persons.append(name) + i=i+1 + + rootItem = self.userModel.invisibleRootItem() + + for person in slice_persons: + rootItem.appendRow([QStandardItem(QString(person["name"])), + QStandardItem(QString(person["role"])), + QStandardItem(QString(person["member"])), + QStandardItem(QString(person["member"]))]) + + headers = QStringList() << "User Name" << "Role" << "Status" << "ServerStatus" + self.userModel.setHorizontalHeaderLabels(headers) + + def updateView(self): + self.updateModel() + + self.userView.setModel(self.userModel) + self.userView.hideColumn(SERVER_MEMBERSHIP_STATUS_COLUMN) + self.userView.resizeColumnToContents(0) + + def updateSliceName(self): + self.slicename.setText("Slice : %s" % (config.getSlice() or "None")) + + def nodeSelectionChanged(self, hostname): + self.parent().nodeSelectionChanged(hostname) + + def process_table(self, slicerec): + change = False + + item = self.userModel.invisibleRootItem() + children = item.rowCount() + for row in range(0, children): + childName = str(item.child(row, NAME_COLUMN).data(Qt.DisplayRole).toString()) + childStatus = str(item.child(row, MEMBERSHIP_STATUS_COLUMN).data(Qt.DisplayRole).toString()) + + if (childStatus == user_status['add']): + slicerec.get_field("researcher").append(childName) + change = True + elif (childStatus == user_status['remove']): + if childName in slicerec.get_field("PI"): + slicerec.get_field("PI").remove(childName) + if childName in slicerec.get_field("researcher"): + slicerec.get_field("researcher").remove(childName) + change = True + + print "XXX", slicerec.get_field("researcher") + return change + + +class MainScreen(SfaScreen): + def __init__(self, parent): + SfaScreen.__init__(self, parent) + + slice = UsersWidget(self) + self.init(slice, "Users", "OneLab SFA crawler") + + def configurationChanged(self): + self.widget.updateSliceName() + self.widget.updateView() + +