def addJob(self, job): if self.__jobs.has_key(job.id): return False item = QtGui.QTreeWidgetItem([ job.name, "", "%02d" % job.totals.running, "%02d" % job.totals.waiting, "%02d" % job.minCores, formatMaxValue(job.maxCores), formatDuration(job.startTime, job.stopTime) ]) self.__jobs[job.id] = item item.setToolTip( 6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) item.setData(0, JOBID_ROLE, job.id) item.setData(0, JOB_ROLE, job) self.__tree.addTopLevelItem(item) progress = JobProgressBar(job.totals, self.__tree) self.__tree.setItemWidget(item, len(self.Header) - 1, progress) self.__setJobStateAndColor(item) return True
def addJob(self, job): if self.__jobs.has_key(job.id): return False item = QtGui.QTreeWidgetItem([ job.name, "", "%02d" % job.totals.running, "%02d" % job.totals.waiting, "%02d" % job.minCores, formatMaxValue(job.maxCores), formatDuration(job.startTime, job.stopTime) ]) self.__jobs[job.id] = item item.setToolTip(6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) item.setData(0, JOBID_ROLE, job.id) item.setData(0, JOB_ROLE, job) self.__tree.addTopLevelItem(item) progress = JobProgressBar(job.totals, self.__tree) self.__tree.setItemWidget(item, len(self.Header)-1, progress); self.__setJobStateAndColor(item) return True
def updateJob(self, job): item = self.__jobs[job.id] item.setData(0, JOB_ROLE, job) item.setText(2, "%02d" % job.totals.running) item.setText(3, "%02d" % job.totals.waiting) item.setText(4, "%02d" % job.minCores) item.setText(5, formatMaxValue(job.maxCores)) item.setText(6, formatDuration(job.startTime, job.stopTime)) item.setToolTip(6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) self.__tree.itemWidget(item, len(self.Header)-1).setTotals(job.totals) self.__setJobStateAndColor(item)
def data(self, column, role=QtCore.Qt.DisplayRole): job = self.ref DISP = QtCore.Qt.DisplayRole TOOL = QtCore.Qt.ToolTipRole BG = QtCore.Qt.BackgroundRole FG = QtCore.Qt.ForegroundRole if role == QtCore.Qt.TextAlignmentRole: if column > 0: return QtCore.Qt.AlignCenter # State if column == 2: if role == DISP or role == BG or role == FG: totals = job.totals color = QtCore.Qt.black bgcolor = constants.COLOR_JOB_STATE[job.state] text = constants.JOB_STATES[job.state] if job.paused: bgcolor = constants.BLUE color = QtCore.Qt.white elif totals.dead: bgcolor = constants.COLOR_TASK_STATE[TaskState.DEAD] color = QtCore.Qt.white if role == BG: return QtGui.QBrush(bgcolor) elif role == FG: return QtGui.QBrush(color) else: return text # Start time elif column == 4: if role == DISP: return formatDuration(job.startTime, job.stopTime) elif role == TOOL: return "Started: {0}\nStopped:{1}".format( formatDateTime(job.startTime), formatDateTime(job.stopTime) ) return super(JobNode, self).data(column, role)
def updateJob(self, job): item = self.__jobs[job.id] item.setData(0, JOB_ROLE, job) item.setText(2, "%02d" % job.totals.running) item.setText(3, "%02d" % job.totals.waiting) item.setText(4, "%02d" % job.minCores) item.setText(5, formatMaxValue(job.maxCores)) item.setText(6, formatDuration(job.startTime, job.stopTime)) item.setToolTip( 6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) self.__tree.itemWidget(item, len(self.Header) - 1).setTotals(job.totals) self.__setJobStateAndColor(item)
def addJob(self, job): if self.__jobs.has_key(job.id): return False item = QtGui.QTreeWidgetItem([ job.name, "", "%02d" % job.totals.running, "%02d" % (job.totals.waiting + job.totals.depend), "%02d" % job.minCores, formatMaxValue(job.maxCores), formatMaxValue(job.stats.highRam), formatDuration(job.startTime, job.stopTime) ]) center = QtCore.Qt.AlignCenter for i in xrange(2, item.columnCount()): item.setTextAlignment(i, center) self.__jobs[job.id] = item item.setToolTip(0, job.name) item.setToolTip( 6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) item.setData(0, JOBID_ROLE, job.id) item.setData(0, JOB_ROLE, job) self.__tree.addTopLevelItem(item) progress = JobProgressBar(job.totals, self.__tree) self.__tree.setItemWidget(item, len(self.HEADER) - 1, progress) self.__setJobStateAndColor(item) return True
def addJob(self, job): if self.__jobs.has_key(job.id): return False item = QtGui.QTreeWidgetItem([ job.name, "", "%02d" % job.totals.running, "%02d" % (job.totals.waiting + job.totals.depend), "%02d" % job.minCores, formatMaxValue(job.maxCores), formatMaxValue(job.stats.highRam), formatDuration(job.startTime, job.stopTime) ]) center = QtCore.Qt.AlignCenter for i in xrange(2, item.columnCount()): item.setTextAlignment(i, center) self.__jobs[job.id] = item item.setToolTip(0, job.name) item.setToolTip(6, "Started: %s\nStopped:%s" % (formatDateTime(job.startTime), formatDateTime(job.stopTime))) item.setData(0, JOBID_ROLE, job.id) item.setData(0, JOB_ROLE, job) self.__tree.addTopLevelItem(item) progress = JobProgressBar(job.totals, self.__tree) self.__tree.setItemWidget(item, len(self.HEADER)-1, progress); self.__setJobStateAndColor(item) return True
class TaskModel(models.PlowTableModel): HEADERS = [ "Name", "State", "Node", "Resources", "Max Resources", "Duration", "Retries", "Log" ] DISPLAY_CALLBACKS = { 0: lambda t: t.name, 1: lambda t: constants.TASK_STATES[t.state], 2: lambda t: t.stats.lastNode, 3: lambda t: "%s/%02dMB" % (t.stats.cores, t.stats.ram), 4: lambda t: "%0.2f/%02dMB" % (t.stats.highCores, t.stats.highRam), 5: lambda t: formatDuration(t.stats.startTime, t.stats.stopTime), 6: lambda t: formatMaxValue(t.stats.retryNum), 7: lambda t: t.stats.lastLogLine, } SORT_CALLBACKS = DISPLAY_CALLBACKS.copy() SORT_CALLBACKS[3] = lambda t: (t.stats.cores, t.stats.ram) SORT_CALLBACKS[4] = lambda t: (t.stats.highCores, t.stats.highRam) SORT_CALLBACKS[5] = lambda t: t.stats.stopTime - t.stats.startTime SORT_CALLBACKS[6] = lambda t: t.stats.retryNum SortRole = models.PlowTableModel.DataRole def __init__(self, parent=None): super(TaskModel, self).__init__(parent) self.__jobId = None self.__lastUpdateTime = 0 # Tasks are updated incrementally, so don't # remove missing ones self.refreshShouldRemove = False # A timer for refreshing duration column. self.__timer = QtCore.QTimer(self) self.__timer.setInterval(1000) self.__timer.timeout.connect(self.__durationRefreshTimer) def fetchObjects(self): if not self.__jobId: return [] opts = {"jobId": self.__jobId} if self.__lastUpdateTime: opts["lastUpdateTime"] = self.__lastUpdateTime t = plow.client.get_plow_time() tasks = plow.client.get_tasks(**opts) self.__lastUpdateTime = t return tasks def getJobId(self): return self.__jobId def setJob(self, jobid): ## Clear out existing tasks. ## TODO make sure to emit right signals self.__timer.stop() self.__jobId = jobid self.__lastUpdateTime = 0 try: tasks = self.fetchObjects() self.setItemList(tasks) finally: self.__timer.start() def refresh(self): if not self.__jobId: return super(TaskModel, self).refresh() def data(self, index, role): row = index.row() col = index.column() if role == QtCore.Qt.TextAlignmentRole: if 0 < col < 6: return QtCore.Qt.AlignCenter task = self._items[row] stats = task.stats BG = QtCore.Qt.BackgroundRole FG = QtCore.Qt.ForegroundRole if col == 1: if role == BG: return constants.COLOR_TASK_STATE[task.state] elif role == FG: if task.state == TaskState.RUNNING: return constants.BLACK else: return constants.WHITE elif role == TaskModel.SortRole: cbk = self.SORT_CALLBACKS.get(col) if cbk is not None: return cbk(task) elif role == QtCore.Qt.ToolTipRole and col == 3: tip = "Allocated Cores: %d\nCurrent CPU Perc:%d\n" \ "Max CPU Perc:%d\nAllocated RAM:%dMB\nCurrent RSS:%dMB\nMaxRSS:%dMB" return tip % (stats.cores, stats.usedCores, stats.highCores, stats.ram, stats.usedRam, stats.highRam) return super(TaskModel, self).data(index, role) def headerData(self, section, orientation, role): if role == QtCore.Qt.ToolTipRole: if section == 3: return "The Cores/Ram that were allocated to the task" elif section == 4: return "The maximum Cores/Ram that this task has used" return super(TaskModel, self).headerData(section, orientation, role) def __durationRefreshTimer(self): RUNNING = plow.client.TaskState.RUNNING for idx, t in enumerate(self._items): if t.state == RUNNING: self.dataChanged.emit(self.index(idx, 4), self.index(idx, 4))
class TaskModel(QtCore.QAbstractTableModel): HEADERS = [ "Name", "State", "Node", "Resources", "Duration", "Retries", "Log" ] DISPLAY_CALLBACKS = { 0: lambda t: t.name, 1: lambda t: constants.TASK_STATES[t.state], 2: lambda t: t.stats.lastNode, 3: lambda t: "%s/%02dMB" % (t.stats.cores, t.stats.ram), 4: lambda t: formatDuration(t.stats.startTime, t.stats.stopTime), 5: lambda t: t.stats.retryNum, 6: lambda t: t.stats.lastLogLine, } SORT_CALLBACKS = { 0: DISPLAY_CALLBACKS[0], 1: DISPLAY_CALLBACKS[1], 2: DISPLAY_CALLBACKS[2], 3: lambda t: (t.stats.cores, t.stats.ram), 4: lambda t: t.stats.stopTime - t.stats.startTime, 5: DISPLAY_CALLBACKS[5], 6: DISPLAY_CALLBACKS[6], } def __init__(self, parent=None): QtCore.QAbstractTableModel.__init__(self, parent) self.__tasks = [] self.__index = {} self.__jobId = None self.__lastUpdateTime = 0 # A timer for refreshing duration column. self.__timer = QtCore.QTimer(self) self.__timer.setInterval(1000) self.__timer.timeout.connect(self.__durationRefreshTimer) def setJob(self, jobid): ## Clear out existing tasks. ## TODO make sure to emit right signals self.__timer.stop() self.beginResetModel() self.__tasks = [] self.__index.clear() self.__jobId = jobid self.__lastUpdateTime = 0 try: self.__tasks = plow.client.get_tasks(jobId=jobid) self.__lastUpdateTime = plow.client.get_plow_time() for i, task in enumerate(self.__tasks): self.__index[task.id] = i finally: self.endResetModel() self.__timer.start() def getJobId(self): return self.__jobId def refresh(self): if not self.__jobId: return t = plow.client.get_plow_time() tasks = plow.client.get_tasks(jobId=self.__jobId, lastUpdateTime=self.__lastUpdateTime) self.__lastUpdateTime = t count = len(self.HEADERS) - 1 for task in tasks: row = self.__index[task.id] self.__tasks[row] = task self.dataChanged.emit(self.index(row, 0), self.index(row, count)) def rowCount(self, parent=None): return len(self.__tasks) def columnCount(self, parent=None): return len(self.HEADERS) def data(self, index, role): row = index.row() col = index.column() task = self.__tasks[row] stats = task.stats if role == QtCore.Qt.DisplayRole: cbk = self.DISPLAY_CALLBACKS.get(col) if cbk is not None: return cbk(task) elif role == QtCore.Qt.BackgroundRole and col == 1: return constants.COLOR_TASK_STATE[task.state] elif role == QtCore.Qt.TextAlignmentRole: if 0 < col < 6: return QtCore.Qt.AlignCenter elif role == SortRole: cbk = self.SORT_CALLBACKS.get(col) if cbk is not None: return cbk(task) elif role == QtCore.Qt.ToolTipRole and col == 3: tip = "Allocated Cores: %d\nCurrent CPU Perc:%d\n" \ "Max CPU Perc:%d\nAllocated RAM:%dMB\nCurrent RSS:%dMB\nMaxRSS:%dMB" return tip % (stats.cores, stats.usedCores, stats.highCores, stats.ram, stats.usedRam, stats.highRam) elif role == IdRole: return task.id elif role == ObjectRole: return task return def headerData(self, section, orientation, role): if role == QtCore.Qt.DisplayRole and orientation == QtCore.Qt.Horizontal: return self.HEADERS[section] def __durationRefreshTimer(self): RUNNING = plow.client.TaskState.RUNNING for idx, t in enumerate(self.__tasks): if t.state == RUNNING: self.dataChanged.emit(self.index(idx, 4), self.index(idx, 4))
def displayLayer(self, layerid): layer = pc.get_layer_by_id(layerid) self.__object = ("layer", layerid) widgets = [ { "title": "Layer", "children": [ { "title": "Name", "widget": "text", "value": layer.name, "readOnly": True }, { "title": "Service", "widget": "text", "value": layer.service, "readOnly": True }, { "title": "Range", "widget": "text", "value": layer.range, "readOnly": True }, { "title": "Chunk", "value": layer.chunk, "readOnly": True }, ] }, { "title": "Task Totals", "children": [ { "title": "Running", "value": layer.totals.running, "readOnly": True }, { "title": "Succeeded", "value": layer.totals.succeeded, "readOnly": True }, { "title": "Depend", "value": layer.totals.depend, "readOnly": True }, { "title": "Dead", "value": layer.totals.dead, "readOnly": True }, { "title": "Waiting", "value": layer.totals.waiting, "readOnly": True } ] }, { "title": "Stats", "children": [ { "title": "Memory", "children": [ { "title": "High Memory (MB)", "value": layer.stats.highRam, "readOnly": True }, { "title": "Avg Memory (MB)", "value": layer.stats.avgRam, "readOnly": True }, { "title": "Std Deviation", "value": layer.stats.stdDevRam, "readOnly": True }, ] }, { "title": "CPU Usage", "children": [ { "title": "High CPU%", "value": layer.stats.highCores, "readOnly": True }, { "title": "Avg CPU%", "value": layer.stats.avgCores, "readOnly": True }, { "title": "Std Deviation", "value": layer.stats.stdDevCores, "readOnly": True }, ] }, { "title": "Core Hours", "children": [ { "title": "Total", "value": formatCoreTime(layer.stats.totalCoreTime), "readOnly": True }, { "title": "Succeeded", "value": [formatCoreTime(layer.stats.totalSuccessCoreTime), "rgba(76, 115, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [formatCoreTime(layer.stats.totalFailCoreTime), "rgba(177, 24, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatCoreTime(layer.stats.highCoreTime), "readOnly": True }, { "title": "Avg Task", "value": formatCoreTime(layer.stats.avgCoreTime), "readOnly": True }, { "title": "Low Task", "value": formatCoreTime(abs(layer.stats.lowCoreTime)), "readOnly": True }, ] }, { "title": "Clock Hours", "children": [ { "title": "Total", "value": formatDuration(layer.stats.totalClockTime, -1), "readOnly": True }, { "title": "Succeeded", "value": [formatDuration(layer.stats.totalSuccessClockTime, -1), "rgba(76, 115, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [formatDuration(layer.stats.totalFailClockTime, -1), "rgba(177, 24, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatDuration(layer.stats.highClockTime, -1), "readOnly": True }, { "title": "Avg Task", "value": formatDuration(layer.stats.avgClockTime, -1), "readOnly": True }, { "title": "Low Task", "value": formatDuration(abs(layer.stats.lowClockTime), -1), "readOnly": True }, ] } ] }, { "title": "Task Settings", "children": [ { "title": "Tags", "value": ",".join(layer.tags), "readOnly": True }, { "title": "Min Cores", "value": layer.minCores, "readOnly": True }, { "title": "Max Cores", "value": layer.maxCores, "readOnly": True }, { "title": "Min Memory (MB)", "value": layer.minRam, "readOnly": True }, { "title": "Max Memory (MB)", "value": layer.maxRam, "readOnly": True }, { "title": "Threadable", "value": layer.threadable, "readOnly": True }, ] } ] form = PlowForm(widgets) self.widget().setWidget(form)
def __init__(self, times, parent=None): FormWidget.__init__(self, parent) self.setWidget(QtGui.QLabel(formatDuration(times[0], times[1]), self))
def displayJob(self, jobid): job = pc.get_job(jobid) self.__object = ("job", jobid) widgets = [{ "title": "Job Status", "children": [ { "title": "Name", "widget": "text", "value": job.name, "readOnly": True }, { "title": "ID", "widget": "text", "value": job.id, "readOnly": True }, { "title": "User", "widget": "text", "value": job.username, "readOnly": True }, { "title": "UID", "value": str(job.uid), "widget": "text", "readOnly": True }, { "title": "State", "widget": "jobState", "value": job.state }, { "title": "Progress", "widget": "jobProgressBar", "value": job.totals }, { "title": "Start Time", "widget": "datetime", "value": job.startTime }, { "title": "Stop Time", "widget": "datetime", "value": job.stopTime }, { "title": "Duration", "widget": "duration", "value": [job.startTime, job.stopTime] }, ] }, { "title": "Core Totals", "children": [{ "title": "Min Cores", "value": job.minCores }, { "title": "Max Cores", "value": job.maxCores }, { "title": "Run Cores", "value": job.runCores, "readOnly": True, }] }, { "title": "Task Totals", "children": [{ "title": "Running", "value": job.totals.running, "readOnly": True }, { "title": "Succeeded", "value": job.totals.succeeded, "readOnly": True }, { "title": "Depend", "value": job.totals.depend, "readOnly": True }, { "title": "Dead", "value": job.totals.dead, "readOnly": True }, { "title": "Waiting", "value": job.totals.waiting, "readOnly": True }] }, { "title": "Stats", "children": [{ "title": "Memory", "children": [ { "title": "High Memory (MB)", "value": job.stats.highRam, "readOnly": True }, ] }, { "title": "CPU Usage", "children": [ { "title": "High CPU%", "value": job.stats.highCores, "readOnly": True }, ] }, { "title": "Core Hours", "children": [ { "title": "Total", "value": formatCoreTime(job.stats.totalCoreTime), "readOnly": True }, { "title": "Succeeded", "value": [ formatCoreTime(job.stats.totalSuccessCoreTime), "rgba(76, 115, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [ formatCoreTime(job.stats.totalFailCoreTime), "rgba(177, 24, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatCoreTime(job.stats.highCoreTime), "readOnly": True }, ] }, { "title": "Clock Hours", "children": [ { "title": "High Task", "value": formatDuration(job.stats.highClockTime, -1), "readOnly": True }, ] }] }] form = PlowForm(widgets) self.widget().setWidget(form)
def displayLayer(self, layerid): layer = pc.get_layer_by_id(layerid) self.__object = ("layer", layerid) widgets = [{ "title": "Layer", "children": [ { "title": "Name", "widget": "text", "value": layer.name, "readOnly": True }, { "title": "Service", "widget": "text", "value": layer.service, "readOnly": True }, { "title": "Range", "widget": "text", "value": layer.range, "readOnly": True }, { "title": "Chunk", "value": layer.chunk, "readOnly": True }, ] }, { "title": "Task Totals", "children": [{ "title": "Running", "value": layer.totals.running, "readOnly": True }, { "title": "Succeeded", "value": layer.totals.succeeded, "readOnly": True }, { "title": "Depend", "value": layer.totals.depend, "readOnly": True }, { "title": "Dead", "value": layer.totals.dead, "readOnly": True }, { "title": "Waiting", "value": layer.totals.waiting, "readOnly": True }] }, { "title": "Stats", "children": [{ "title": "Memory", "children": [ { "title": "High Memory (MB)", "value": layer.stats.highRam, "readOnly": True }, { "title": "Avg Memory (MB)", "value": layer.stats.avgRam, "readOnly": True }, { "title": "Std Deviation", "value": layer.stats.stdDevRam, "readOnly": True }, ] }, { "title": "CPU Usage", "children": [ { "title": "High CPU%", "value": layer.stats.highCores, "readOnly": True }, { "title": "Avg CPU%", "value": layer.stats.avgCores, "readOnly": True }, { "title": "Std Deviation", "value": layer.stats.stdDevCores, "readOnly": True }, ] }, { "title": "Core Hours", "children": [ { "title": "Total", "value": formatCoreTime(layer.stats.totalCoreTime), "readOnly": True }, { "title": "Succeeded", "value": [ formatCoreTime(layer.stats.totalSuccessCoreTime), "rgba(76, 115, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [ formatCoreTime(layer.stats.totalFailCoreTime), "rgba(177, 24, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatCoreTime(layer.stats.highCoreTime), "readOnly": True }, { "title": "Avg Task", "value": formatCoreTime(layer.stats.avgCoreTime), "readOnly": True }, { "title": "Low Task", "value": formatCoreTime(abs(layer.stats.lowCoreTime)), "readOnly": True }, ] }, { "title": "Clock Hours", "children": [ { "title": "Total", "value": formatDuration(layer.stats.totalClockTime, -1), "readOnly": True }, { "title": "Succeeded", "value": [ formatDuration(layer.stats.totalSuccessClockTime, -1), "rgba(76, 115, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [ formatDuration(layer.stats.totalFailClockTime, -1), "rgba(177, 24, 0, 192)" ], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatDuration(layer.stats.highClockTime, -1), "readOnly": True }, { "title": "Avg Task", "value": formatDuration(layer.stats.avgClockTime, -1), "readOnly": True }, { "title": "Low Task", "value": formatDuration(abs(layer.stats.lowClockTime), -1), "readOnly": True }, ] }] }, { "title": "Task Settings", "children": [ { "title": "Tags", "value": ",".join(layer.tags), "readOnly": True }, { "title": "Min Cores", "value": layer.minCores, "readOnly": True }, { "title": "Max Cores", "value": layer.maxCores, "readOnly": True }, { "title": "Min Memory (MB)", "value": layer.minRam, "readOnly": True }, { "title": "Max Memory (MB)", "value": layer.maxRam, "readOnly": True }, { "title": "Threadable", "value": layer.threadable, "readOnly": True }, ] }] form = PlowForm(widgets) self.widget().setWidget(form)
class NodeModel(QtCore.QAbstractTableModel): HEADERS = [ "Name", "Cluster", "State", "Locked", "Cores (Total)", "Cores (Idle)", "Ram (Total)", "Ram (Free)", "Swap (Total)", "Swap (Free)", "Ping", "Uptime" ] HEADER_CALLBACKS = { 0: lambda n: n.name, 1: lambda n: n.clusterName, 2: lambda n: NODE_STATES.get(n.state, ''), 3: lambda n: str(bool(n.locked)), 4: lambda n: n.totalCores, 5: lambda n: n.idleCores, 6: lambda n: n.system.totalRamMb, 7: lambda n: n.system.freeRamMb, 8: lambda n: n.system.totalSwapMb, 9: lambda n: n.system.freeSwapMb, 10: lambda n: formatDuration(n.updatedTime), 11: lambda n: formatDuration(n.bootTime), } def __init__(self, parent=None): super(NodeModel, self).__init__(parent) self.__items = [] def hasChildren(self, parent): return False def reload(self): nodes = plow.client.get_nodes() self.setNodeList(nodes) def refresh(self): if not self.__items: self.reload() return rows = self.__index colCount = self.columnCount() parent = QtCore.QModelIndex() nodes = plow.client.get_nodes() nodes_ids = set() to_add = set() # Update for node in nodes: nodes_ids.add(node.id) if node.id in self.__index: row = rows[node.id] self.__items[row] = node start = self.index(row, 0) end = self.index(row, colCount - 1) self.dataChanged.emit(start, end) LOGGER.debug("updating %s %s", node.id, node.name) else: to_add.add(node) # Add new if to_add: size = len(to_add) start = len(self.__items) end = start + size - 1 self.beginInsertRows(parent, start, end) self.__items.extend(to_add) self.endInsertRows() LOGGER.debug("adding %d new nodes", size) # Remove to_remove = set(self.__index.iterkeys()).difference(nodes_ids) for row, old_id in sorted( ((rows[old_id], old_id) for old_id in to_remove), reverse=True): self.beginRemoveRows(parent, row, row) node = self.__items.pop(row) self.endRemoveRows() LOGGER.debug("removing %s %s", old_id, node.name) self.__index = dict((n.id, row) for row, n in enumerate(self.__items)) def rowCount(self, parent): return len(self.__items) def columnCount(self, parent=None): return len(self.HEADERS) def data(self, index, role): if not index.isValid(): return row = index.row() col = index.column() node = self.__items[row] if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.ToolTipRole: return self.HEADER_CALLBACKS[col](node) elif role == QtCore.Qt.UserRole: if col == 7: return node.system.freeRamMb / float(node.system.totalRamMb) elif col == 9: return node.system.freeSwapMb / float(node.system.totalSwapMb) else: return self.HEADER_CALLBACKS[col](node) elif role == QtCore.Qt.TextAlignmentRole: if col != 0: return QtCore.Qt.AlignCenter elif role == QtCore.Qt.BackgroundRole: if node.state == plow.client.NodeState.DOWN: return constants.RED if node.locked: return constants.BLUE return None elif role == ObjectRole: return node def headerData(self, section, orientation, role): if role == QtCore.Qt.TextAlignmentRole: if section == 0: return QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter else: return QtCore.Qt.AlignCenter if role != QtCore.Qt.DisplayRole: return None if orientation == QtCore.Qt.Vertical: return section return self.HEADERS[section] def nodeFromIndex(self, idx): if not idx.isValid(): return None node = self.__items[idx.row()] return node def setNodeList(self, nodeList): self.beginResetModel() self.__items = nodeList self.__index = dict((n.id, row) for row, n in enumerate(nodeList)) self.endResetModel()
class JobNode(PlowNode): TYPE = JOB_TYPE HEADERS = [ "Name", "Run Cores", "Min Cores", "Total", "Pend.", "Run", "State", "Owner", "Duration", "Max MB", ] HEADER_WIDTHS = (300,75,75,60,60,60,80,80,100) DISPLAY_CALLBACKS = [ lambda j: j.name, lambda j: j.runCores, lambda j: j.minCores, lambda j: j.totals.total, lambda j: j.totals.waiting + j.totals.depend, lambda j: j.totals.running, lambda j: "Paused" if j.paused else JOB_STATES.get(j.state, '').title(), lambda j: j.username, lambda j: formatDuration(j.startTime, j.stopTime), lambda j: j.stats.highRam, ] DATA_CALLBACKS = DISPLAY_CALLBACKS[:] DATA_CALLBACKS[6] = lambda j: j.state DATA_CALLBACKS[8] = lambda j: j.startTime def data(self, column, role=QtCore.Qt.DisplayRole): job = self.ref DISP = QtCore.Qt.DisplayRole TOOL = QtCore.Qt.ToolTipRole BG = QtCore.Qt.BackgroundRole FG = QtCore.Qt.ForegroundRole # State if column == 6: if role == DISP or role == BG or role == FG: totals = job.totals color = QtCore.Qt.black bgcolor = constants.COLOR_JOB_STATE[job.state] text = constants.JOB_STATES[job.state] if job.paused: bgcolor = constants.BLUE color = QtCore.Qt.white elif totals.dead: bgcolor = constants.COLOR_TASK_STATE[TaskState.DEAD] color = QtCore.Qt.white if role == BG: return QtGui.QBrush(bgcolor) elif role == FG: return QtGui.QBrush(color) else: return text # Start time elif column == 8 and role == TOOL: start = formatDateTime(job.startTime) stop = formatDateTime(job.stopTime) return "Started: {0}\nStopped:{1}".format(start, stop) return super(JobNode, self).data(column, role)
def displayJob(self, jobid): job = pc.get_job(jobid) self.__object = ("job", jobid) widgets = [ { "title": "Job Status", "children": [ { "title": "Name", "widget": "text", "value": job.name, "readOnly": True }, { "title": "ID", "widget": "text", "value": job.id, "readOnly": True }, { "title": "User", "widget": "text", "value": job.username, "readOnly": True }, { "title": "UID", "value": str(job.uid), "widget": "text", "readOnly": True }, { "title": "State", "widget": "jobState", "value": job.state }, { "title": "Progress", "widget": "jobProgressBar", "value": job.totals }, { "title": "Start Time", "widget": "datetime", "value": job.startTime }, { "title": "Stop Time", "widget": "datetime", "value": job.stopTime }, { "title": "Duration", "widget": "duration", "value": [job.startTime, job.stopTime] }, ] }, { "title": "Core Totals", "children": [ { "title": "Min Cores", "value": job.minCores }, { "title": "Max Cores", "value": job.maxCores }, { "title": "Run Cores", "value": job.runCores, "readOnly": True, } ] }, { "title": "Task Totals", "children": [ { "title": "Running", "value": job.totals.running, "readOnly": True }, { "title": "Succeeded", "value": job.totals.succeeded, "readOnly": True }, { "title": "Depend", "value": job.totals.depend, "readOnly": True }, { "title": "Dead", "value": job.totals.dead, "readOnly": True }, { "title": "Waiting", "value": job.totals.waiting, "readOnly": True } ] }, { "title": "Stats", "children": [ { "title": "Memory", "children": [ { "title": "High Memory (MB)", "value": job.stats.highRam, "readOnly": True }, ] }, { "title": "CPU Usage", "children": [ { "title": "High CPU%", "value": job.stats.highCores, "readOnly": True }, ] }, { "title": "Core Hours", "children": [ { "title": "Total", "value": formatCoreTime(job.stats.totalCoreTime), "readOnly": True }, { "title": "Succeeded", "value": [formatCoreTime(job.stats.totalSuccessCoreTime), "rgba(76, 115, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "Failed", "value": [formatCoreTime(job.stats.totalFailCoreTime), "rgba(177, 24, 0, 192)"], "widget": "pillWidget", "readOnly": True, "maximumWidth": 125 }, { "title": "High Task", "value": formatCoreTime(job.stats.highCoreTime), "readOnly": True }, ] }, { "title": "Clock Hours", "children": [ { "title": "High Task", "value": formatDuration(job.stats.highClockTime, -1), "readOnly": True }, ] } ] } ] form = PlowForm(widgets) self.widget().setWidget(form)
class NodeModel(models.PlowTableModel): HEADERS = [ "Name", "Cluster", "State", "Locked", "Total Cores", "Idle Cores", "Total Ram", "Free Ram", "Total Swap", "Free Swap", "Ping", "Uptime", "Tags", ] DISPLAY_CALLBACKS = { 0 : lambda n: n.name, 1 : lambda n: n.clusterName, 2 : lambda n: NODE_STATES.get(n.state, ''), 3 : lambda n: str(bool(n.locked)), 4 : lambda n: n.totalCores, 5 : lambda n: n.idleCores, 6 : lambda n: n.system.totalRamMb, 7 : lambda n: n.system.freeRamMb, 8 : lambda n: n.system.totalSwapMb, 9 : lambda n: n.system.freeSwapMb, 10: lambda n: formatDuration(n.updatedTime), 11: lambda n: formatDuration(n.bootTime), 12: lambda n: ', '.join(n.tags), } def __init__(self, parent=None): super(NodeModel, self).__init__(parent) def fetchObjects(self): return plow.client.get_nodes() def reload(self): nodes = plow.client.get_nodes() self.setItemList(nodes) def refresh(self): if not self._items: self.reload() return super(NodeModel, self).refresh() def data(self, index, role): row = index.row() col = index.column() node = self._items[row] if role == self.DataRole: if col == 7: return node.system.freeRamMb / float(node.system.totalRamMb) elif col == 9: return node.system.freeSwapMb / float(node.system.totalSwapMb) else: return self.DISPLAY_CALLBACKS[col](node) elif role == QtCore.Qt.BackgroundRole: if node.state == plow.client.NodeState.DOWN: return constants.RED if node.locked: return constants.BLUE return super(NodeModel, self).data(index, role)