Exemplo n.º 1
0
    def __init__(self):
        QMainWindow.__init__(self)

        # Set up the user interface from Designer.
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.actionGenerate.setIcon( QIcon( StatsMainWindow.BASEDIR+"tools/statsviewer/rsrc/refresh.png") )

        sys.stdout = OutLog( self.ui.log , sys.stdout)
        xlogger.info("Starting log")


        # Create tmp file for svg
        self.svgFile = NamedTemporaryFile( suffix=".svg", delete=True )
        xlogger.info("Creating temp file: %s"%self.svgFile.name)

        #
        # Set UI values
        #

        # Set report choices
        for key, elem in self.reportDict.items():
            self.ui.cbReport.addItem(key)

        # Set queue param choices
        for key, elem in sorted(self.queueTrackParam.items()):
            self.ui.cbTrack.addItem(key)
        self.ui.cbTrack.setCurrentIndex(1)

        for key, elem in sorted(self.queueGroupByParam.items()):
            self.ui.cbGroupBy.addItem(key)
        self.ui.cbGroupBy.setCurrentIndex(0)


        #
        # Connect UI
        #

        # Update end date value
        self.ui.dtEndDate.setDateTime( QDateTime.currentDateTime() )
        
        # Connect up the buttons.
        self.ui.actionGenerate.triggered.connect(self.generateGraph)
        self.ui.actionReset.triggered.connect(self.resetParams)
        self.ui.cbReport.currentIndexChanged.connect( self.updateParamsVisibility )
        self.ui.cbReport.currentIndexChanged.connect( self.ui.actionGenerate.trigger )

        # Connect Now/Enddate widgets
        self.ui.chkNow.toggled.connect(lambda toggled: self.ui.dtEndDate.setDateTime( QDateTime.currentDateTime() ))
        self.ui.chkNow.toggled[bool].connect( self.ui.dtEndDate.setDisabled )
        self.ui.chkNow.toggled[bool].connect( self.ui.actionGenerate.trigger )
        self.ui.dtEndDate.editingFinished.connect( self.ui.actionGenerate.trigger )

        # RN usage params
        self.ui.chkWorking.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkPaused.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkOffline.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkIdle.toggled.connect( self.ui.actionGenerate.trigger )

        # Jobs params
        self.ui.cbTrack.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbGroupBy.currentIndexChanged.connect( self.ui.actionGenerate.trigger )


        # Handle length slider and spinbox
        self.ui.slLength.sliderReleased.connect(self.ui.actionGenerate.trigger)
        self.ui.slLength.valueChanged.connect(self.ui.spLength.setValue)
        self.ui.spLength.valueChanged.connect(self.ui.slLength.setValue)
        self.ui.spLength.editingFinished.connect(self.ui.actionGenerate.trigger)
        self.ui.slLength.sliderReleased.connect(self.ui.actionGenerate.trigger)

        # Handle display options
        self.ui.slResolution.sliderReleased.connect(self.ui.actionGenerate.trigger)
        self.ui.slResolution.valueChanged.connect(self.ui.spResolution.setValue)
        self.ui.spResolution.valueChanged.connect(self.ui.slResolution.setValue)
        self.ui.spResolution.editingFinished.connect(self.ui.actionGenerate.trigger)
        self.ui.cbGraphStyle.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbGraphType.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbScaleType.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbScaleRound.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.spScaleResolution.editingFinished.connect(self.ui.actionGenerate.trigger)


        # Hide/Show report param
        self.updateParamsVisibility()

        self.currentCmd = self.reportDict[ str(self.ui.cbReport.currentText()) ]["cmd"]
        self.currentSource = self.reportDict[ str(self.ui.cbReport.currentText()) ]["source"]

        xlogger.debug("current command is: %s" % self.currentCmd)
        xlogger.debug("current source is: %s" % self.currentSource)

        # self.ui.webView.loadFinished.connect( self.initSvgFile )
        # self.ui.webView.settings().setAttribute( QWebSettings.JavascriptEnabled, True)
        # self.ui.webView.load(QUrl("rsrc/www/display.html"))

        self.ui.webView.load(QUrl(self.svgFile.name))
        self.generateGraph()
Exemplo n.º 2
0
class StatsMainWindow(QMainWindow):
    """
    """

    LOGDIR = "/s/apps/lin/vfx_test_apps/pulistats/"
    # SRCDIR = "/datas/jsa/OpenRenderManagement/"
    BASEDIR = "/s/apps/lin/puli/"

    reportDict={ 
        "RN usage": { 
            "cmd": BASEDIR + "scripts/util/update_usage_stats",
            "source":"/s/apps/lin/vfx_test_apps/pulistats/logs/usage_stats.log"
            },

        "Job usage" : { 
            "cmd": BASEDIR + "scripts/util/update_queue_stats",
            "source":"/s/apps/lin/vfx_test_apps/pulistats/logs/queue_stats.log"
        },
    }

    queueTrackParam={
        "Num errors":"err",
        "Num jobs":"jobs",
        "Num paused":"paused",
        "Num ready or blocked":"ready",
        "Num rn allocated":"allocatedRN",
        "Num running":"running",
    }

    queueGroupByParam={
        "Prod":"prod",
        "User":"******",
        "Step":"step",
        "Type":"type"
    }

    def __init__(self):
        QMainWindow.__init__(self)

        # Set up the user interface from Designer.
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.actionGenerate.setIcon( QIcon( StatsMainWindow.BASEDIR+"tools/statsviewer/rsrc/refresh.png") )

        sys.stdout = OutLog( self.ui.log , sys.stdout)
        xlogger.info("Starting log")


        # Create tmp file for svg
        self.svgFile = NamedTemporaryFile( suffix=".svg", delete=True )
        xlogger.info("Creating temp file: %s"%self.svgFile.name)

        #
        # Set UI values
        #

        # Set report choices
        for key, elem in self.reportDict.items():
            self.ui.cbReport.addItem(key)

        # Set queue param choices
        for key, elem in sorted(self.queueTrackParam.items()):
            self.ui.cbTrack.addItem(key)
        self.ui.cbTrack.setCurrentIndex(1)

        for key, elem in sorted(self.queueGroupByParam.items()):
            self.ui.cbGroupBy.addItem(key)
        self.ui.cbGroupBy.setCurrentIndex(0)


        #
        # Connect UI
        #

        # Update end date value
        self.ui.dtEndDate.setDateTime( QDateTime.currentDateTime() )
        
        # Connect up the buttons.
        self.ui.actionGenerate.triggered.connect(self.generateGraph)
        self.ui.actionReset.triggered.connect(self.resetParams)
        self.ui.cbReport.currentIndexChanged.connect( self.updateParamsVisibility )
        self.ui.cbReport.currentIndexChanged.connect( self.ui.actionGenerate.trigger )

        # Connect Now/Enddate widgets
        self.ui.chkNow.toggled.connect(lambda toggled: self.ui.dtEndDate.setDateTime( QDateTime.currentDateTime() ))
        self.ui.chkNow.toggled[bool].connect( self.ui.dtEndDate.setDisabled )
        self.ui.chkNow.toggled[bool].connect( self.ui.actionGenerate.trigger )
        self.ui.dtEndDate.editingFinished.connect( self.ui.actionGenerate.trigger )

        # RN usage params
        self.ui.chkWorking.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkPaused.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkOffline.toggled.connect( self.ui.actionGenerate.trigger )
        self.ui.chkIdle.toggled.connect( self.ui.actionGenerate.trigger )

        # Jobs params
        self.ui.cbTrack.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbGroupBy.currentIndexChanged.connect( self.ui.actionGenerate.trigger )


        # Handle length slider and spinbox
        self.ui.slLength.sliderReleased.connect(self.ui.actionGenerate.trigger)
        self.ui.slLength.valueChanged.connect(self.ui.spLength.setValue)
        self.ui.spLength.valueChanged.connect(self.ui.slLength.setValue)
        self.ui.spLength.editingFinished.connect(self.ui.actionGenerate.trigger)
        self.ui.slLength.sliderReleased.connect(self.ui.actionGenerate.trigger)

        # Handle display options
        self.ui.slResolution.sliderReleased.connect(self.ui.actionGenerate.trigger)
        self.ui.slResolution.valueChanged.connect(self.ui.spResolution.setValue)
        self.ui.spResolution.valueChanged.connect(self.ui.slResolution.setValue)
        self.ui.spResolution.editingFinished.connect(self.ui.actionGenerate.trigger)
        self.ui.cbGraphStyle.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbGraphType.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbScaleType.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.cbScaleRound.currentIndexChanged.connect( self.ui.actionGenerate.trigger )
        self.ui.spScaleResolution.editingFinished.connect(self.ui.actionGenerate.trigger)


        # Hide/Show report param
        self.updateParamsVisibility()

        self.currentCmd = self.reportDict[ str(self.ui.cbReport.currentText()) ]["cmd"]
        self.currentSource = self.reportDict[ str(self.ui.cbReport.currentText()) ]["source"]

        xlogger.debug("current command is: %s" % self.currentCmd)
        xlogger.debug("current source is: %s" % self.currentSource)

        # self.ui.webView.loadFinished.connect( self.initSvgFile )
        # self.ui.webView.settings().setAttribute( QWebSettings.JavascriptEnabled, True)
        # self.ui.webView.load(QUrl("rsrc/www/display.html"))

        self.ui.webView.load(QUrl(self.svgFile.name))
        self.generateGraph()

        # self.ui.webView.load(QUrl("/tmp/graph.svg"))
        # self.ui.webView.load(QUrl("/tmp/test.html"))

    # def initSvgFile(self):
    #     doc = self.ui.webView.page().mainFrame().documentElement()
    #     em = doc.findFirst("embed")
    #     em.setAttribute("src", self.svgFile.name)

    #     print "RESULT=%r" % self.ui.webView.page().mainFrame().toHtml()
    #     self.ui.webView.show()
    #     pass

    def updateParamsVisibility(self):

        if self.ui.cbReport.currentText() == "RN usage":
            self.ui.gbJobUsage.setVisible( False )
            self.ui.gbRnUsage.setVisible( True )
        else:
            self.ui.gbJobUsage.setVisible( True )
            self.ui.gbRnUsage.setVisible( False )

    def closeEvent(self, pEvent):
        """
        """
        xlogger.info("Removing temp file: %s"%self.svgFile.name)
        del(self.svgFile)
        pEvent.accept()


    def createBaseArgs(self):
        """
        """
        startDate = self.ui.dtEndDate.dateTime().addSecs( -1*self.ui.slLength.value()*3600 )
        endDate = self.ui.dtEndDate.dateTime()
        
        title = "%s - %s" % (startDate.toString("MM/dd hh:mm"), endDate.toString("MM/dd hh:mm"))
        startTime = startDate.toTime_t()
        endTime = endDate.toTime_t()

        args = []
        args += ["-t", title]
        args += ["--startTime", str(startTime)]
        args += ["--endTime", str(endTime)]
        args += ["-f", self.currentSource]
        args += ["-o", self.svgFile.name]
        args += ["--render-mode", "svg"]
        args += ["--scale", str(self.ui.spScaleResolution.value())]
        args += ["--scaleRound", str( int(self.ui.cbScaleRound.currentText()) * 60 )]

        #
        # Display params
        #
        args += ["--res", str(self.ui.slResolution.value())]
        args += ["--style", str(self.ui.cbGraphStyle.currentText())]
        args += ["--width", str(800)]
        args += ["--height", str(300)]
        
        if self.ui.cbGraphType.currentText() == "Stacked":
            args.append("--stack")
        if self.ui.cbScaleType.currentText() == "Logarithmic":
            args.append("--log")

        return args

    def createRnUsageArgs(self):
        """
        """
        args = []

        if not self.ui.chkOffline.isChecked():
            args.append("--hide-offline")
        if not self.ui.chkPaused.isChecked():
            args.append("--hide-paused")
        if not self.ui.chkWorking.isChecked():
            args.append("--hide-working")
        if not self.ui.chkIdle.isChecked():
            args.append("--hide-idle")

        return args

    def createQueueUsageArgs(self):
        """
        Add 2 fields to graph one value with a specific groupby attribute.
        Warning: the order of the params are important: groupby, value
        """
        args = []
        # args.append("prod")
        # args.append("jobs")

        args.append( self.queueGroupByParam[ str(self.ui.cbGroupBy.currentText()) ] )
        args.append( self.queueTrackParam[ str(self.ui.cbTrack.currentText()) ] )
        xlogger.info( "Tracking %s grouped by %s" % (self.queueTrackParam[ str(self.ui.cbTrack.currentText()) ],
                                                    self.queueGroupByParam[ str(self.ui.cbGroupBy.currentText()) ]) )
        return args

    def resetParams(self):
        """
        Set default values for all widget elements that might have been changed by user.
        Signals are blocked for actionGenerate during the reset, a call to grapheGenerate is done to refresh the view at the end.
        """

        xlogger.info( "Reset all params" )
        self.ui.actionGenerate.blockSignals(True)

        self.ui.cbReport.setCurrentIndex(0)
        self.ui.slLength.setValue(24)
        self.ui.chkNow.setChecked(True)

        self.ui.chkWorking.setChecked(True)
        self.ui.chkPaused.setChecked(True)
        self.ui.chkIdle.setChecked(True)
        self.ui.chkOffline.setChecked(True)

        self.ui.cbTrack.setCurrentIndex(1)
        self.ui.cbGroupBy.setCurrentIndex(0)

        self.ui.slResolution.setValue(30)
        self.ui.cbGraphType.setCurrentIndex(0)
        self.ui.cbScaleType.setCurrentIndex(0)
        self.ui.cbGraphStyle.setCurrentIndex(0)
        self.ui.cbScaleRound.setCurrentIndex(3)
        self.ui.spScaleResolution.setValue(20)

        self.ui.actionGenerate.blockSignals(False)
        self.generateGraph()

    def generateGraph(self):

        #
        # Disable GUI
        #
        self.ui.actionGenerate.setEnabled( False )


        #
        # Prepare process params
        #
        startDate = self.ui.dtEndDate.dateTime().addSecs( -1*self.ui.slLength.value()*3600 )
        endDate = self.ui.dtEndDate.dateTime()


        self.currentCmd = self.reportDict[ str(self.ui.cbReport.currentText()) ]["cmd"]
        self.currentSource = self.reportDict[ str(self.ui.cbReport.currentText()) ]["source"]
        
        args = self.createBaseArgs()
        if self.ui.cbReport.currentText() == "RN usage":
            args += self.createRnUsageArgs()
        else:
            args += self.createQueueUsageArgs()


        # Start thread
        self.p = QProcess(self)
        self.p.finished.connect( self.renderFinished )
        self.p.started.connect( self.renderStarted )


        xlogger.debug("starting command: %s %s" % (self.currentCmd, " ".join(args)) )
        res = self.p.start( self.currentCmd, args )
        if res==False:
            xlogger.info("Error starting subprocess: code=%s" % str(self.p.error()))

        self.ui.statusbar.showMessage("Graph update in progress...", 10000)
        self.ui.actionGenerate.setEnabled( False )
        

    def renderStarted(self):
        
        self.creationStartTime = time.time()
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # Activate webview display
        # self.ui.webView.page().mainFrame().findFirstElement("#wait").setAttribute("class", "visible")
        # self.ui.webView.page().mainFrame().findFirstElement("#graph").setAttribute("class", "loading")


    def renderFinished(self, retCode):
        """
        Refresh result in webview
        """
        self.ui.actionGenerate.setEnabled( True )
        self.ui.statusbar.clearMessage()

        QApplication.restoreOverrideCursor()

        # # Activate webview display
        # self.ui.webView.page().mainFrame().findFirstElement("#wait").removeAttribute("class")
        # self.ui.webView.page().mainFrame().findFirstElement("#graph").removeAttribute("class")
        
        # svg = self.ui.webView.page().mainFrame().documentElement().findFirst("svg")
        # svg.setAttribute("style", "opacity: 1.0;")

        if retCode == 0:
            # # try to replace svg inline html
            # result = str(self.p.readAllStandardOutput())
            # svg = self.ui.webView.page().mainFrame().findFirstElement("#svg")
            # svg.setInnerXml(svgMarkup)
            # svg.replace(svgMarkup)
            
            self.ui.webView.reload()
            xlogger.info("graph updated in %.2fs" % (time.time() - self.creationStartTime ))
        else:
            xlogger.info("An error occured")