Example #1
0
class PythonWidget(QWidget):
    def __init__(self, parent):
        super().__init__(parent)

        self.pythonScript = QTextEdit()
        self.pythonScript.setReadOnly(False)  # asked by Manolo
        self.pythonScript.setMaximumHeight(340)

        script_box = oasysgui.widgetBox(self, "", addSpace=False, orientation="vertical", height=545, width=750)
        script_box.layout().addWidget(self.pythonScript)

        console_box = oasysgui.widgetBox(script_box, "", addSpace=False, orientation="vertical", height=150, width=750)

        self.console = PythonConsole(self.__dict__, self)
        console_box.layout().addWidget(self.console)

        button_box = oasysgui.widgetBox(script_box, "", addSpace=False, orientation="horizontal")

        gui.button(button_box, self, "Run Script", callback=self.execute_script, height=35)
        gui.button(button_box, self, "Save Script to File", callback=self.save_script, height=35)

    def execute_script(self):
        self._script = str(self.pythonScript.toPlainText())
        self.console.write("\nRunning script:\n")
        self.console.push("exec(_script)")
        self.console.new_prompt(sys.ps1)

    def save_script(self):
        file_name = QFileDialog.getSaveFileName(self, "Save File to Disk", ".", "*.py")

        if not file_name is None:
            if not file_name.strip() == "":
                file = open(file_name, "w")
                file.write(str(self.pythonScript.toPlainText()))
                file.close()

                QMessageBox.information(self, "QMessageBox.information()",
                                              "File " + file_name + " written to disk",
                                              QMessageBox.Ok)

    def setText(self, text):
        self.pythonScript.clear()
        self.pythonScript.setText(self.parse_nans(text))

    def parse_nans(self, text):
        return text.replace("nan", "numpy.nan")

# --------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------

    if __name__ == "__main__":
        app = QApplication(sys.argv)
        w = OWmare()
        w.show()
        app.exec()
        w.saveSettings()
Example #2
0
class SVNPluginPropsDialog( QDialog ):
    " SVN plugin properties dialog "

    def __init__( self, plugin, client, path, parent = None ):
        QDialog.__init__( self, parent )

        self.__plugin = plugin
        self.__client = client
        self.__path = path

        self.__createLayout()
        self.setWindowTitle( "SVN Properties of " + path )
        self.__populate()
        self.__propsView.setFocus()
        return

    def __populate( self ):
        " Populate the properties list "
        # Get the currently selected name
        selectedName = None
        selected = list( self.__propsView.selectedItems() )
        if selected:
            selectedName = str( selected[ 0 ].text( 0 ) )

        self.__propsView.clear()
        properties = readProperties( self.__client, self.__path )
        if properties:
            for itemPath, itemProps in properties:
                if self.__path == itemPath or \
                   self.__path == itemPath + os.path.sep:
                    for name, value in itemProps.iteritems():
                        name = str( name ).strip()
                        value = str( value ).strip()
                        newItem = QTreeWidgetItem( [ name, value ] )
                        self.__propsView.addTopLevelItem( newItem )

        self.__resizePropsView()
        self.__sortPropsView()

        if selectedName:
            index = 0
            for index in xrange( 0, self.__propsView.topLevelItemCount() ):
                item = self.__propsView.topLevelItem( index )
                if selectedName == item.text( 0 ):
                    item.setSelected( True )
        return

    def __resizePropsView( self ):
        " Resizes the properties table "
        self.__propsView.header().setStretchLastSection( True )
        self.__propsView.header().resizeSections(
                                        QHeaderView.ResizeToContents )
        return

    def __sortPropsView( self ):
        " Sorts the properties table "
        self.__propsView.sortItems(
                    self.__propsView.sortColumn(),
                    self.__propsView.header().sortIndicatorOrder() )
        return

    def __createLayout( self ):
        " Creates the dialog layout "
        self.resize( 640, 480 )
        self.setSizeGripEnabled( True )

        vboxLayout = QVBoxLayout( self )

        hLayout = QHBoxLayout()
        self.__propsView = QTreeWidget()
        self.__propsView.setAlternatingRowColors( True )
        self.__propsView.setRootIsDecorated( False )
        self.__propsView.setItemsExpandable( False )
        self.__propsView.setSortingEnabled( True )
        self.__propsView.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.__propsView.itemSelectionChanged.connect( self.__propsSelectionChanged )

        propsViewHeader = QTreeWidgetItem( [ "Property Name", "Property Value" ] )
        self.__propsView.setHeaderItem( propsViewHeader )
        self.__propsView.header().setSortIndicator( 0, Qt.DescendingOrder )
        hLayout.addWidget( self.__propsView )

        self.__delButton = QToolButton()
        self.__delButton.setText( "Delete" )
        self.__delButton.setFocusPolicy( Qt.NoFocus )
        self.__delButton.setEnabled( False )
        self.__delButton.clicked.connect( self.__onDel )
        hLayout.addWidget( self.__delButton, 0, Qt.AlignBottom )
        vboxLayout.addLayout( hLayout )

        # Set property part
        setGroupbox = QGroupBox( self )
        setGroupbox.setTitle( "Set Property" )

        setLayout = QGridLayout( setGroupbox )
        setLayout.addWidget( QLabel( "Name" ), 0, 0, Qt.AlignTop | Qt.AlignRight )
        setLayout.addWidget( QLabel( "Value" ), 1, 0, Qt.AlignTop | Qt.AlignRight )

        self.__nameEdit = QLineEdit()
        self.__nameEdit.textChanged.connect( self.__nameChanged )
        setLayout.addWidget( self.__nameEdit, 0, 1 )

        self.__valueEdit = QTextEdit()
        self.__valueEdit.setAcceptRichText( False )
        self.__valueEdit.textChanged.connect( self.__valueChanged )
        metrics = QFontMetrics( self.__valueEdit.font() )
        rect = metrics.boundingRect( "X" )
        self.__valueEdit.setFixedHeight( rect.height() * 4 + 5 )
        setLayout.addWidget( self.__valueEdit, 1, 1 )

        self.__setButton = QToolButton()
        self.__setButton.setText( "Set" )
        self.__setButton.setFocusPolicy( Qt.NoFocus )
        self.__setButton.setEnabled( False )
        self.__setButton.clicked.connect( self.__onSet )
        setLayout.addWidget( self.__setButton, 1, 2, Qt.AlignBottom | Qt.AlignHCenter )
        
        sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth( setGroupbox.sizePolicy().hasHeightForWidth() )
        setGroupbox.setSizePolicy( sizePolicy )
        vboxLayout.addWidget( setGroupbox )

        # Buttons at the bottom
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Ok )
        buttonBox.button( QDialogButtonBox.Ok ).setDefault( True )
        buttonBox.accepted.connect( self.close )
        vboxLayout.addWidget( buttonBox )
        return

    def __onSet( self ):
        " Triggered when propery set is clicked "
        name = self.__nameEdit.text().strip()
        value = self.__valueEdit.toPlainText().strip()
        try:
            commitInfo = self.__client.propset( name, value, self.__path )
            if commitInfo:
                logging.info( str( commitInfo ) )
            self.__populate()
            self.__plugin.notifyPathChanged( self.__path )
            self.__nameEdit.clear()
            self.__valueEdit.clear()
            self.__propsView.setFocus()
        except pysvn.ClientError, exc:
            message = exc.args[ 0 ]
            logging.error( message )
            return
        except Exception, exc:
            logging.error( str( exc ) )
            return
Example #3
0
class QChatWindow(QMainWindow):
    def __init__(self, client, messageQueue, isLightTheme):
        QMainWindow.__init__(self)

        self.client = client
        self.messageQueue = messageQueue
        self.isLightTheme = isLightTheme

        self.__setMenubar()

        self.chatLog = QTextEdit()
        self.chatLog.setReadOnly(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hboxLayout = QHBoxLayout()
        hboxLayout.addWidget(self.chatInput)
        hboxLayout.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hboxLayout)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(self.height()), 1])

        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(splitter)

        # Add the completeted layout to the window
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(vboxLayout)
        self.setCentralWidget(self.centralWidget)

        qtUtils.resizeWindow(self, 700, 400)
        qtUtils.centerWindow(self)

        # Title and icon
        self.setWindowTitle("Cryptully")
        self.setWindowIcon(QIcon(utils.getAbsoluteResourcePath('images/' + ('light' if isLightTheme else 'dark') + '/icon.png')))
        self.statusBar().showMessage("Not Connected")


    def showNowChattingMessage(self):
        self.statusBar().showMessage("Connected to " + self.client.getHostname())
        self.appendMessage("You are now securely chatting with " + self.client.getHostname() + " :)",
                           constants.SERVICE, showTimestamp=False)

        self.appendMessage("It's a good idea to verify the communcation is secure by selecting"
                           "\"verify key integrity\" in the options menu.", constants.SERVICE, showTimestamp=False)


    def chatInputTextChanged(self):
        if str(self.chatInput.toPlainText())[-1:] == '\n':
            self.sendMessage()


    def sendMessage(self):
        message = str(self.chatInput.toPlainText())[:-1]

        # Don't send empty messages
        if message == '':
            return

        # Add the message to the message queue to be sent
        self.messageQueue.put(message)

        # Clear the chat input
        self.chatInput.clear()

        self.appendMessage(message, constants.SENDER)


    @pyqtSlot(str, int, bool)
    def appendMessage(self, message, source, showTimestamp=True):
        if showTimestamp:
            timestamp = utils.getTimestamp()
        else:
            timestamp = ''

        color = self.__getColor(source)

        # If the user has scrolled up (current value != maximum), do not move the scrollbar
        # to the bottom after appending the message
        shouldScroll = True
        scrollbar = self.chatLog.verticalScrollBar()
        if scrollbar.value() != scrollbar.maximum() and source != constants.SENDER:
            shouldScroll = False

        # Append the message to the end of the chat log
        self.chatLog.append(timestamp + '<font color="' + color + '">' + message + "</font>")

        # Move the vertical scrollbar to the bottom of the chat log
        if shouldScroll:
            scrollbar.setValue(scrollbar.maximum())


    def __getColor(self, source):
        if source == constants.SENDER:
            if self.isLightTheme:
                return '#0000CC'
            else:
                return '#6666FF'
        elif source == constants.RECEIVER:
            if self.isLightTheme:
                return '#CC0000'
            else:
                return '#CC3333'
        else:
            if self.isLightTheme:
                return '#000000'
            else:
                return '#FFFFFF'


    def __setMenubar(self):
        iconPath = 'images/'
        if self.isLightTheme:
            iconPath = iconPath + 'light/'
        else:
            iconPath = iconPath + 'dark/'

        fingerprintIcon = QIcon(utils.getAbsoluteResourcePath(iconPath + 'fingerprint.png'))
        saveIcon        = QIcon(utils.getAbsoluteResourcePath(iconPath + 'save.png'))
        clearIcon       = QIcon(utils.getAbsoluteResourcePath(iconPath + 'delete.png'))
        helpIcon        = QIcon(utils.getAbsoluteResourcePath(iconPath + 'help.png'))
        exitIcon        = QIcon(utils.getAbsoluteResourcePath(iconPath + 'exit.png'))
        menuIcon        = QIcon(utils.getAbsoluteResourcePath(iconPath + 'menu.png'))

        fingerprintAction  = QAction(fingerprintIcon, '&Verify key integrity', self)
        saveKeypairAction  = QAction(saveIcon, '&Save current encryption keys', self)
        clearKeypairAction = QAction(clearIcon, 'C&lear saved encryption keys', self)
        helpAction         = QAction(helpIcon, 'Show &help', self)
        exitAction         = QAction(exitIcon, '&Exit', self)

        fingerprintAction.triggered.connect(self.__showFingerprintDialog)
        saveKeypairAction.triggered.connect(self.__showSaveKeypairDialog)
        clearKeypairAction.triggered.connect(self.__clearKeypair)
        helpAction.triggered.connect(self.__showHelpDialog)
        exitAction.triggered.connect(self.__exit)

        fingerprintAction.setShortcut('Ctrl+I')
        saveKeypairAction.setShortcut('Ctrl+S')
        clearKeypairAction.setShortcut('Ctrl+L')
        helpAction.setShortcut('Ctrl+H')
        exitAction.setShortcut('Ctrl+Q')

        optionsMenu = QMenu()

        optionsMenu.addAction(fingerprintAction)
        optionsMenu.addAction(saveKeypairAction)
        optionsMenu.addAction(clearKeypairAction)
        optionsMenu.addAction(helpAction)
        optionsMenu.addAction(exitAction)

        toolButton = QToolButton()
        toolButton.setIcon(menuIcon)
        toolButton.setMenu(optionsMenu)
        toolButton.setPopupMode(QToolButton.InstantPopup)

        toolbar = self.addToolBar('toolbar')
        toolbar.addWidget(toolButton)


    def __showFingerprintDialog(self):
        QFingerprintDialog(self.client.sock.crypto).exec_()


    def __showSaveKeypairDialog(self):
        if utils.doesSavedKeypairExist():
            QMessageBox.warning(self, "Keys Already Saved", "The current encryption keys have already been saved.")
            return

        QMessageBox.information(self, "Save Keys", "For extra security, your encryption keys will be protected with a passphrase. You'll need to enter this each time you start the app.")
        passphrase = qtUtils.getKeypairPassphrase(self.isLightTheme, parent=self, verify=True, showForgotButton=False)

        # Return if the user did not provide a passphrase
        if passphrase is None:
            return

        utils.saveKeypair(self.client.sock.crypto, passphrase)
        QMessageBox.information(QWidget(), "Keys Saved", "Encryption keys saved. The current keys will be used for all subsequent connections.")


    def __clearKeypair(self):
        qtUtils.clearKeypair(self)


    def __showHelpDialog(self):
        QHelpDialog(self).show()


    def __exit(self):
        qtUtils.exitApp()
Example #4
0
class ErrorLogDialog(QDialog):
    def __init__(self, parent):
        super(ErrorLogDialog, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self._empty = True
        
        self._initUI()
        self.setWindowTitle("Error")
        get_notification_center().connectLogMessage(self._checkLogMessage)
        
        for record in getCachedLogRecords():
            self._checkLogMessage(record)
        
    def sizeHint(self):
        return QSize(400, 200)
        
    def _initUI(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 10, 0, 0)
        layout.setSpacing(0)
        
        labelLayout = QHBoxLayout()
        labelLayout.addWidget(QLabel(u"Sorry, something went wrong:", self))
        labelLayout.setContentsMargins(10, 0, 0, 0)
        layout.addLayout(labelLayout)
        layout.addSpacing(5)
        self._errorLog = QTextEdit(self)
        self._errorLog.setReadOnly(True)
        self._errorLog.setWordWrapMode(QTextOption.NoWrap)
        self._errorLog.setTextColor(QColor(180, 0, 0))
        self._errorLog.setObjectName(u"__ERROR_LOG_")
        
        self._errorLog.setFrameShape(QFrame.StyledPanel)
        if getPlatform() == PLATFORM_MAC:
            self._errorLog.setStyleSheet("QFrame#__ERROR_LOG_{border-width: 1px; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-color:palette(mid)}");
            
        layout.addWidget(self._errorLog)
        
        bottomWidget = QWidget(self)
        bottomLayout = QHBoxLayout(bottomWidget)
        
        self._notAgain = QCheckBox(u"Please, no more error messages!", self)
        bottomLayout.addWidget(self._notAgain, 1, Qt.AlignTop)
        
        buttonBox = QDialogButtonBox(QDialogButtonBox.Close, Qt.Horizontal, self)
        buttonBox.rejected.connect(self.reject)
        bottomLayout.addWidget(buttonBox)
        
        layout.addWidget(bottomWidget)
        
    @loggingSlot()
    def reject(self):
        self._errorLog.clear()
        self._empty = True
        return QDialog.reject(self)
    
    @loggingSlot(object)
    def _checkLogMessage(self, record):
        try:
            if self._notAgain.checkState() == Qt.Checked:
                return
            if record.levelno >= logging.ERROR:
                recMsg = record.msg
                if not isinstance(recMsg, basestring):
                    recMsg = unicode(recMsg)
                err = convert_string(recMsg) % record.args
                component = record.name
                if component.startswith("lunchinator."):
                    component = component[12:]
                    
                msg = u"%s - In component %s (%s:%d):\n%s" % (strftime("%H:%M:%S", localtime(record.created)),
                                                              component,
                                                              record.pathname,
                                                              record.lineno,
                                                              err)
                if record.exc_info:
                    out = StringIO()
                    traceback.print_tb(record.exc_info[2], file=out)
                    msg += u"\nStack trace:\n" + out.getvalue() + formatException(record.exc_info) + u"\n"
                    
                self._errorLog.append(msg)
                self._empty = False
                if not self.isVisible():
                    self.showNormal()
                    self.raise_()
                    self.activateWindow()
        except:
            from lunchinator.log import getCoreLogger
            getCoreLogger().info(formatException())
class ConsoleWidget(QWidget):
    _RECORD_ROLE = Qt.UserRole + 1
    
    def __init__(self, parent, logger):
        super(ConsoleWidget, self).__init__(parent)
        
        self.logger = logger
        self._errorColor = QVariant(QColor(180, 0, 0))
        self._warningColor = QVariant(QColor(170, 100, 0))
        self._records = []
        
        self._initModel()
        self._initUI()
        
        get_notification_center().connectLogMessage(self._addLogMessage)
        
    def _initUI(self):
        layout = QVBoxLayout(self)
        
        split = QSplitter(Qt.Vertical, self)
        
        layout.setContentsMargins(0, 0, 0, 0)
        
        console = QTreeView(self)
        console.setSortingEnabled(False)
        console.setHeaderHidden(False)
        console.setAlternatingRowColors(True)
        console.setIndentation(0)
        console.setUniformRowHeights(True)
        console.setObjectName(u"__console_log")
        
        console.setFrameShape(QFrame.StyledPanel)
        #if getPlatform() == PLATFORM_MAC:
        #    console.setStyleSheet("QFrame#__console_log{border-width: 1px; border-top-style: none; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-color:palette(mid)}");
        
        console.setModel(self._logModel)
        console.header().setStretchLastSection(False)
        console.header().setResizeMode(3, QHeaderView.Stretch)
        console.selectionModel().selectionChanged.connect(self._selectionChanged)
        split.addWidget(console)
        
        detailsWidget = QWidget(self)
        detailsLayout = QVBoxLayout(detailsWidget)
        detailsLayout.setContentsMargins(0, 0, 0, 0)
        detailsLayout.setSpacing(0)
        
        detailsLayout.addWidget(QLabel(u"Details:", self))
        
        self._detailsView = QTextEdit(self)
        self._detailsView.setReadOnly(True)
        self._detailsView.setWordWrapMode(QTextOption.NoWrap)
        
        detailsLayout.addWidget(self._detailsView, 1)
        
        split.addWidget(detailsWidget)
        
        layout.addWidget(split, 1)
        
    @loggingSlot(QItemSelection, QItemSelection)
    def _selectionChanged(self, newSel, _oldSel):
        if len(newSel.indexes()) == 0:
            self._detailsView.clear()
        else:
            index = newSel.indexes()[0]
            record = self._records[index.row()]
            
            try:
                logMsg = convert_string(record.msg) % record.args
            except:
                logMsg = convert_string(record.msg) + ', '.join(str(arg) for arg in record.args)
            
            msg = u"%s - In %s:%d: %s" % (strftime("%H:%M:%S", localtime(record.created)),
                                          record.pathname,
                                          record.lineno,
                                          logMsg)
            if record.exc_info:
                out = StringIO()
                traceback.print_tb(record.exc_info[2], file=out)
                msg += u"\nStack trace:\n" + out.getvalue() + formatException(record.exc_info) + u"\n"
                
            self._detailsView.setPlainText(msg)
        
    def _initModel(self):
        self._logModel = QStandardItemModel(self)
        self._logModel.setColumnCount(5)
        self._logModel.setHorizontalHeaderLabels([u"Time", u"Level", u"Component", u"Message", u"Source"])
        for record in getCachedLogRecords():
            self._addLogMessage(record)
    
    def _createItem(self, text, error, toolTip=None):
        item = QStandardItem()
        item.setEditable(False)
        item.setText(text)
        if error is 1:
            item.setData(self._warningColor, Qt.ForegroundRole)
        elif error is 2:
            item.setData(self._errorColor, Qt.ForegroundRole)
        if toolTip is None:
            toolTip = text
        item.setData(QVariant(toolTip), Qt.ToolTipRole)
        return item
        
    @loggingSlot(object)
    def _addLogMessage(self, record):
        self._records.append(record)
        
        msg = record.msg
        if not isinstance(msg, basestring):
            msg = unicode(msg)
        try:
            msg = convert_string(msg) % record.args
        except:
            msg = u"(Error formatting log message) " +\
             convert_string(msg) +\
             ', '.join(unicode(v) for v in record.args)
            
        dirname = os.path.dirname(record.pathname)
        source = u"%s:%d" % (os.path.join(os.path.basename(dirname), os.path.basename(record.pathname)), record.lineno)
        fullsource = u"%s:%d" % (record.pathname, record.lineno)
        component = record.name
        if component.startswith("lunchinator."):
            component = component[12:]
        error = 1 if record.levelno == logging.WARNING else 2 if record.levelno == logging.ERROR else 0
        self._logModel.appendRow([self._createItem(strftime("%H:%M:%S", localtime(record.created)), error),
                                  self._createItem(record.levelname, error),
                                  self._createItem(component, error),
                                  self._createItem(msg, error),
                                  self._createItem(source, error, fullsource)])
    
        
Example #6
0
class DUdpReplay(QtHelper.EnhancedQDialog, Logger.ClassLogger):
    """
    Http replay dialog
    """
    def __init__(self, parent=None, offlineMode=False):
        """
        Constructor

        @param parent: 
        @type parent:
        """
        super(DUdpReplay, self).__init__(parent)
        self.offlineMode = offlineMode
        self.defaultIp = "127.0.0.1"
        self.defaultPort = "80"
        self.newTest = ''
        self.newTestExec = ''
        self.newInputs = []
        self.requests = []
        self.responses = []
        self.defaultTemplates = DefaultTemplates.Templates()
        self.testType = None

        self.createDialog()
        self.createConnections()
        self.createActions()
        self.createToolbar()

    def createActions(self):
        """
        Create qt actions
        """
        self.openAction = QtHelper.createAction(self,
                                                "&Open",
                                                self.importTrace,
                                                icon=QIcon(":/folder_add.png"),
                                                tip='Open network trace.')
        self.exportTUAction = QtHelper.createAction(
            self,
            "&Test Unit",
            self.exportToTU,
            icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE),
            tip='Export to Test Unit')
        self.exportTSAction = QtHelper.createAction(
            self,
            "&Test Suite",
            self.exportToTS,
            icon=QIcon(":/%s.png" % WWorkspace.TestSuite.TYPE),
            tip='Export to Test Suite')
        self.cancelAction = QtHelper.createAction(self,
                                                  "&Cancel",
                                                  self.reject,
                                                  tip='Cancel')

        menu = QMenu(self)
        menu.addAction(self.exportTUAction)
        menu.addAction(self.exportTSAction)

        self.exportToAction = QtHelper.createAction(
            self,
            "&Export to",
            self.exportToTU,
            icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE),
            tip='Export to tests')
        self.exportToAction.setMenu(menu)
        self.exportToAction.setEnabled(False)

    def createDialog(self):
        """
        Create dialog
        """

        self.dockToolbar = QToolBar(self)
        self.dockToolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        self.setWindowTitle(WINDOW_TITLE)
        self.resize(500, 400)

        self.ipEdit = QLineEdit(self.defaultIp)
        ipRegExpVal = QRegExpValidator(self)
        ipRegExp = QRegExp("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
        ipRegExpVal.setRegExp(ipRegExp)
        self.ipEdit.setValidator(ipRegExpVal)

        self.portEdit = QLineEdit(self.defaultPort)
        self.portEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        validatorPort = QIntValidator(self)
        self.portEdit.setValidator(validatorPort)

        self.progressBar = QProgressBar(self)
        self.progressBar.setMaximum(100)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setAlignment(Qt.AlignCenter)
        self.progressBar.setObjectName("progressBar")

        self.guiSikuliGroupBox = QGroupBox("")
        self.guiSikuliGroupBox.setFlat(True)
        self.automaticAdp = QRadioButton("Automatic")
        self.automaticAdp.setChecked(True)
        self.defaultAdp = QRadioButton("Default")
        self.genericAdp = QRadioButton("Generic")
        vbox = QHBoxLayout()
        vbox.addWidget(self.automaticAdp)
        vbox.addWidget(self.defaultAdp)
        vbox.addWidget(self.genericAdp)
        vbox.addStretch(1)
        self.guiSikuliGroupBox.setLayout(vbox)

        layout = QVBoxLayout()
        layout.addWidget(self.dockToolbar)
        layout.addSpacing(12)
        paramLayout = QGridLayout()
        paramLayout.addWidget(QLabel("Destination IP:"), 0, 0, Qt.AlignRight)
        paramLayout.addWidget(self.ipEdit, 0, 1)
        paramLayout.addWidget(QLabel("Destination Port:"), 1, 0, Qt.AlignRight)
        paramLayout.addWidget(self.portEdit, 1, 1)
        paramLayout.addWidget(QLabel(self.tr("Gui adapter selector:")), 2, 0,
                              Qt.AlignRight)
        paramLayout.addWidget(self.guiSikuliGroupBox, 2, 1)
        layout.addLayout(paramLayout)

        self.logsEdit = QTextEdit()
        self.logsEdit.setReadOnly(True)
        self.logsEdit.setTextInteractionFlags(Qt.NoTextInteraction)

        layout.addSpacing(12)
        layout.addWidget(self.logsEdit)
        layout.addSpacing(12)
        layout.addWidget(self.progressBar)

        self.setLayout(layout)

    def createToolbar(self):
        """
        Create toolbar
        """
        self.dockToolbar.setObjectName("File toolbar")
        self.dockToolbar.addAction(self.openAction)
        self.dockToolbar.addSeparator()
        self.dockToolbar.addAction(self.exportToAction)
        self.dockToolbar.addSeparator()
        self.dockToolbar.setIconSize(QSize(16, 16))

    def createConnections(self):
        """
        Create qt connections
        """
        pass

    def autoScrollOnTextEdit(self):
        """
        Automatic scroll on text edit
        """
        cursor = self.logsEdit.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.logsEdit.setTextCursor(cursor)

    def strip_html(self, txt):
        """
        Strip html
        """
        if "<" in txt:
            txt = txt.replace('<', '&lt;')
        if ">" in txt:
            txt = txt.replace('>', '&gt;')
        return txt

    def addLogSuccess(self, txt):
        """
        Add log success in the text edit
        """
        self.logsEdit.insertHtml(
            "<span style='color:darkgreen'>%s</span><br />" %
            unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLogWarning(self, txt):
        """
        Add log warning in the text edit
        """
        self.logsEdit.insertHtml(
            "<span style='color:darkorange'>%s</span><br />" %
            unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLogError(self, txt):
        """
        Add log error in the text edit
        """
        self.logsEdit.insertHtml("<span style='color:red'>%s</span><br />" %
                                 unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLog(self, txt):
        """
        Append log to the logsEdit widget
        """
        self.logsEdit.insertHtml("%s<br />" % unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def importTrace(self):
        """
        Import network trace
        """
        self.logsEdit.clear()
        self.testType = None

        if not self.offlineMode:
            if not RCI.instance().isAuthenticated():
                self.addLogWarning(
                    txt="<< Connect to the test center in first!")
                QMessageBox.warning(self, "Import",
                                    "Connect to the test center in first!")
                return

        self.exportToAction.setEnabled(False)
        self.newTest = ''
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)

        if sys.version_info > (3, ):
            fileName = QFileDialog.getOpenFileName(
                self, self.tr("Open File"), "",
                "Network dump (*.cap;*.pcap;*.pcapng)")
        else:
            fileName = QFileDialog.getOpenFileName(self, self.tr("Open File"),
                                                   "", "Network dump (*.cap)")
        # new in v18 to support qt5
        if QtHelper.IS_QT5:
            _fileName, _type = fileName
        else:
            _fileName = fileName
        # end of new

        if not _fileName:
            return

        if sys.version_info < (3, ):
            extension = str(_fileName).rsplit(".", 1)[1]
            if not (extension == "cap"):
                self.addLogError(txt="<< File not supported %s" % _fileName)
                QMessageBox.critical(self, "Open", "File not supported")
                return

        _fileName = str(_fileName)
        capName = _fileName.rsplit("/", 1)[1]

        self.addLogSuccess(txt=">> Reading the file %s" % _fileName)
        self.readFileV2(fileName=_fileName)

    def exportToTS(self):
        """
        Export to test suite
        """
        self.testType = TS
        self.exportToTest(TS=True, TU=False)

    def exportToTU(self):
        """
        Export to test unit
        """
        self.testType = TU
        self.exportToTest(TS=False, TU=True)

    def searchUDP(self):
        """
        Search UDP module in assistant
        """
        # modules accessor
        ret = "SutAdapters"
        if self.automaticAdp.isChecked():
            isGeneric = WWorkspace.Helper.instance().isGuiGeneric(name="GUI")
            if isGeneric:
                ret = "SutAdapters.Generic"
        elif self.defaultAdp.isChecked():
            return ret
        elif self.genericAdp.isChecked():
            ret = "SutAdapters.Generic"
        else:
            pass
        return ret

    def exportToTest(self, TS=True, TU=False):
        """
        Export to test
        """
        if not RCI.instance().isAuthenticated():
            self.addLogWarning(txt="<< Connect to the test center in first!")
            QMessageBox.warning(self, "Import",
                                "Connect to the test center in first!")
            return

        if TS:
            self.newTest = self.defaultTemplates.getTestDefinitionAuto()
            self.newTestExec = self.defaultTemplates.getTestExecutionAuto()
        if TU:
            self.newTest = self.defaultTemplates.getTestUnitDefinitionAuto()

        destIp = str(self.ipEdit.text())
        destPort = str(self.portEdit.text())

        self.newInputs = []
        self.newInputs.append({
            'type': 'self-ip',
            'name': 'BIND_IP',
            'description': '',
            'value': '0.0.0.0',
            'color': ''
        })
        self.newInputs.append({
            'type': 'int',
            'name': 'BIND_PORT',
            'description': '',
            'value': '0',
            'color': ''
        })
        self.newInputs.append({
            'type': 'str',
            'name': 'DEST_IP',
            'description': '',
            'value': '%s' % destIp,
            'color': ''
        })
        self.newInputs.append({
            'type': 'int',
            'name': 'DEST_PORT',
            'description': '',
            'value': '%s' % destPort,
            'color': ''
        })
        self.newInputs.append({
            'type': 'bool',
            'name': 'DEBUG',
            'description': '',
            'value': 'False',
            'color': ''
        })
        self.newInputs.append({
            'type': 'float',
            'name': 'TIMEOUT',
            'description': '',
            'value': '5.0',
            'color': ''
        })

        adps = """self.ADP_UDP = %s.UDP.Client(parent=self, bindIp=input('BIND_IP'), bindPort=input('BIND_PORT'), destinationIp=input('DEST_IP'), destinationPort=input('DEST_PORT'), debug=input('DEBUG'), separatorDisabled=True)""" % self.searchUDP(
        )

        # prepare steps
        steps = []
        j = 0
        for i in xrange(len(self.requests)):
            j = i + 1
            sentrecv, req = self.requests[i]
            if sentrecv == 'sent':
                steps.append(
                    'self.step%s = self.addStep(expected="udp data sent", description="send udp data", summary="send udp data")'
                    % j)
            else:
                steps.append(
                    'self.step%s = self.addStep(expected="udp data received", description="received udp data", summary="received udp data")'
                    % j)

        tests = []
        for i in xrange(len(self.requests)):
            j = i + 1
            sentrecv, req = self.requests[i]
            (source, dest, source_port, dest_port, data) = req

            if sentrecv == 'sent':
                tests.append("# data to sent %s" % j)
                tests.append('self.step%s.start()' % j)
                if sys.version_info > (3, ):
                    tests.append('rawSent = %s' % data.replace(b"'", b"\\'"))
                else:
                    tests.append('rawSent = """%s"""' % data)
                tests.append('SentMsg = self.ADP_UDP.sendData(data=rawSent)')
                tests.append('if not SentMsg:')
                tests.append(
                    '\tself.step%s.setFailed(actual="unable to send data")' %
                    j)
                tests.append('else:')
                tests.append(
                    '\tself.step%s.setPassed(actual="udp data sent succesfully")'
                    % j)
                tests.append('')

            if sentrecv == 'recv':
                tests.append("# data to received %s" % j)
                tests.append('self.step%s.start()' % j)
                if sys.version_info > (3, ):
                    tests.append('rawRecv = %s' % data.replace(b'"', b'\\"'))
                else:
                    tests.append('rawRecv = """%s"""' % data)
                tests.append(
                    'RecvMsg = self.ADP_UDP.hasReceivedData(data=rawRecv, timeout=input("TIMEOUT"))'
                )
                tests.append('if RecvMsg is None:')
                tests.append(
                    '\tself.step%s.setFailed(actual="unable to received data")'
                    % j)
                tests.append('else:')
                tests.append(
                    '\tself.step%s.setPassed(actual="udp data received succesfully")'
                    % j)
                tests.append('')
        if TS:
            init = """self.ADP_UDP.startListening()
		udpListening = self.ADP_UDP.isListening( timeout=input('TIMEOUT') )
		if not udpListening:
			self.abort( 'unable to listing to the udp port %s'  )
""" % str(self.portEdit.text())

        if TU:
            init = """self.ADP_UDP.startListening()
	udpListening = self.ADP_UDP.isListening( timeout=input('TIMEOUT') )
	if not udpListening:
		self.abort( 'unable to connect to the udp port %s'  )
""" % str(self.portEdit.text())

        if TS:
            cleanup = """self.ADP_UDP.stopListening()
		udpStopped = self.ADP_UDP.isStopped( timeout=input('TIMEOUT') )
		if not udpStopped:
			self.error( 'unable to no more listen from the udp port %s' )
""" % str(self.portEdit.text())

        if TU:
            cleanup = """self.ADP_UDP.stopListening()
	udpStopped = self.ADP_UDP.isStopped( timeout=input('TIMEOUT') )
	if not udpStopped:
		self.error( 'unable to no more listen  from the udp port %s' )
""" % str(self.portEdit.text())

        self.newTest = self.newTest.replace(
            "<<PURPOSE>>", 'self.setPurpose(purpose="Replay UDP")')
        self.newTest = self.newTest.replace("<<ADPS>>", adps)
        if TS:
            self.newTest = self.newTest.replace("<<STEPS>>",
                                                '\n\t\t'.join(steps))
        if TU:
            self.newTest = self.newTest.replace("<<STEPS>>",
                                                '\n\t'.join(steps))
        self.newTest = self.newTest.replace("<<INIT>>", init)
        self.newTest = self.newTest.replace("<<CLEANUP>>", cleanup)
        if TS:
            self.newTest = self.newTest.replace("<<TESTS>>",
                                                '\n\t\t'.join(tests))
        if TU:
            self.newTest = self.newTest.replace("<<TESTS>>",
                                                '\n\t'.join(tests))

        self.accept()

    def readFileV2(self, fileName):
        """
        Read pcap file 
        Support pcap-ng too
        """
        fd = open(fileName, 'rb')
        fileFormat, fileHead = PcapParse.extractFormat(fd)
        if fileFormat == PcapParse.FileFormat.PCAP:
            self.trace("pcap file detected")
            pcapFile = PcapReader.PcapFile(fd, fileHead).read_packet
            self.readFilePacket(pcapFile=pcapFile)
        elif fileFormat == PcapParse.FileFormat.PCAP_NG:
            self.trace("pcap-png file detected")
            pcapFile = PcapngReader.PcapngFile(fd, fileHead).read_packet
            self.readFilePacket(pcapFile=pcapFile)
        else:
            self.addLogError(txt="<< Error to open the network trace")
            self.error('unable to open the network trace: file format = %s' %
                       fileFormat)
            QMessageBox.critical(self, "Import", "File not supported")

    def readFilePacket(self, pcapFile):
        """
        Read file packet by packet
        """
        ip_expected = str(self.ipEdit.text())
        port_expected = int(self.portEdit.text())

        # read packet)
        packets = pcapFile()
        ethernetPackets = list(packets)
        self.addLogSuccess(txt="<< Total packets detected: %s " %
                           len(ethernetPackets))

        # extract udp packet according to the expected ip and port
        self.requests = []
        i = 1
        self.progressBar.setMaximum(len(ethernetPackets))
        self.progressBar.setValue(0)
        for pkt in ethernetPackets:
            self.progressBar.setValue(i)
            i += 1
            pktDecoded = PcapParse.decodePacket(pkt, getTcp=False, getUdp=True)
            if pktDecoded is not None:
                (source, dest, source_port, dest_port, data) = pktDecoded
                # skip when no data exists
                if dest == ip_expected and int(dest_port) == int(
                        port_expected) and len(data) > 0:
                    self.requests.append(('sent', pktDecoded))
                if source == ip_expected and int(source_port) == int(
                        port_expected) and len(data) > 0:
                    self.requests.append(('recv', pktDecoded))
        self.addLogSuccess(txt="<< Number of UDP packets detected: %s" %
                           len(self.requests))

        if self.requests:
            self.addLogSuccess("<< File decoded with success!")
            self.addLogWarning(
                "<< Click on the export button to generate the test!")
            self.exportToAction.setEnabled(True)
        else:
            self.addLogWarning("<< No udp extracted!")
Example #7
0
class TermWidget(QWidget):
    """Widget wich represents terminal. It only displays text and allows to enter text.
    All highlevel logic should be implemented by client classes
    """
    def __init__(self, font, *args):
        QWidget.__init__(self, *args)
        self._browser = QTextEdit(self)
        self._browser.setReadOnly(True)
        document = self._browser.document()
        document.setDefaultStyleSheet(document.defaultStyleSheet() +
                                      "span {white-space:pre;}")

        self._browser.setFont(font)
        self._edit = _TextEdit(self, font)

        lowLevelWidget = self._edit.focusProxy()
        if lowLevelWidget is None:
            lowLevelWidget = self._edit
        lowLevelWidget.installEventFilter(self)

        self._edit.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
        self.setFocusProxy(self._edit)

        layout = QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._browser)
        layout.addWidget(self._edit)

        self._history = ['']  # current empty line
        self._historyIndex = 0

        self._edit.setFocus()

    def terminate(self):
        self._edit.terminate()

    def eventFilter(self, obj, event):
        pass  # suppress docsting for non-public method
        """QWidget.eventFilter implementation. Catches _edit key pressings. Processes some of them
        """
        if event.type() == QEvent.KeyPress:
            if event.matches(QKeySequence.MoveToNextLine):
                if self._edit.cursorPosition[0] == (len(self._edit.lines) - 1):
                    self._onHistoryNext()
                    return True
            elif event.matches(QKeySequence.MoveToPreviousLine):
                if self._edit.cursorPosition[0] == 0:
                    self._onHistoryPrev()
                    return True
            elif event.matches(QKeySequence.MoveToNextPage) or \
                 event.matches(QKeySequence.MoveToPreviousPage):
                self._browser.keyPressEvent(event)
                return True
            elif event.matches(QKeySequence.InsertParagraphSeparator):
                return self._editNewLineEvent()

        return QWidget.eventFilter(self, obj, event)

    def _appendToBrowser(self, style, text):
        """Convert text to HTML for inserting it to browser. Insert the HTML
        """
        text = cgi.escape(text)

        text = text.replace('\n', '<br/>')

        defBg = self._browser.palette().color(QPalette.Base)

        h, s, v, a = defBg.getHsvF()

        if style == 'out':
            pass
        elif style == 'in':
            if v > 0.5:  # white background
                v = v - (v / 8)  # make darker
            else:
                v = v + ((1 - v) / 4)  # make ligher
        elif style == 'err':
            if v < 0.5:  # dark background
                v = v + ((1 - v) / 4)  # make ligher

            h = 0
            s = .4
        elif style == 'hint':
            if v < 0.5:  # dark background
                v = v + ((1 - v) / 4)  # make ligher

            h = 0.33
            s = .4
        else:
            assert 0

        bg = QColor.fromHsvF(h, s, v)
        text = '<span style="background-color: %s;">%s</span>' % (bg.name(),
                                                                  text)

        scrollBar = self._browser.verticalScrollBar()
        oldValue = scrollBar.value()

        if False:
            # hlamer: It seems, it is more comfortable, if text is always scrolled
            scrollAtTheEnd = oldValue == scrollBar.maximum()
        else:
            scrollAtTheEnd = True

        self._browser.moveCursor(QTextCursor.End)
        self._browser.insertHtml(text)

        if scrollAtTheEnd:
            scrollBar.setValue(scrollBar.maximum())
        else:
            scrollBar.setValue(oldValue)

        while self._browser.document().characterCount() > 1024 * 1024:
            cursor = self._browser.cursorForPosition(QPoint(0, 0))
            cursor.select(cursor.LineUnderCursor)
            if not cursor.selectedText():
                cursor.movePosition(cursor.Down, cursor.KeepAnchor)
                cursor.movePosition(cursor.EndOfLine, cursor.KeepAnchor)
            cursor.removeSelectedText()

    def setLanguage(self, language):
        """Set highlighting language for input widget
        """
        self._edit.detectSyntax(language=language)

    def execCommand(self, text):
        """Save current command in the history. Append it to the log. Execute child's method. Clear edit line.
        """
        self._appendToBrowser('in', text + '\n')

        if len(self._history) < 2 or\
           self._history[-2] != text:  # don't insert duplicating items
            self._history.insert(-1, text)

        self._historyIndex = len(self._history) - 1

        self._history[-1] = ''
        self._edit.text = ''

        if not text.endswith('\n'):
            text += '\n'

        self.childExecCommand(text)

    def childExecCommand(self, text):
        """Reimplement in the child classes to execute enterred commands
        """
        pass

    def appendOutput(self, text):
        """Appent text to output widget
        """
        self._appendToBrowser('out', text)

    def appendError(self, text):
        """Appent error text to output widget. Text is drawn with red background
        """
        self._appendToBrowser('err', text)

    def appendHint(self, text):
        """Appent error text to output widget. Text is drawn with red background
        """
        self._appendToBrowser('hint', text)

    def clear(self):
        """Clear the widget"""
        self._browser.clear()

    def isCommandComplete(self, text):
        """Executed when Enter is pressed to check if widget should execute the command, or insert newline.

        Implement this function in the child classes.
        """
        return True

    def _editNewLineEvent(self):
        """Handler of Enter pressing in the edit
        """
        text = self._edit.text

        if self.isCommandComplete(text):
            self.execCommand(text)
            return True  # processing finished
        else:
            return False  # let the editor process the event

    def _onHistoryNext(self):
        """Down pressed, show next item from the history
        """
        if (self._historyIndex + 1) < len(self._history):
            self._historyIndex += 1
            self._edit.text = self._history[self._historyIndex]
            self._edit.absCursorPosition = len(self._edit.text)

    def _onHistoryPrev(self):
        """Up pressed, show previous item from the history
        """
        if self._historyIndex > 0:
            if self._historyIndex == (len(self._history) - 1):
                self._history[-1] = self._edit.text
            self._historyIndex -= 1
            self._edit.text = self._history[self._historyIndex]
            self._edit.absCursorPosition = len(self._edit.text)
Example #8
0
class HDFWidget(QWidget):
    def __init__(self, parent=None):
        super(HDFWidget, self).__init__(parent=parent)
        self.parent = parent

        self.main_layout = QVBoxLayout()

        ### Select Dataset and properties ###
        self.layout = QHBoxLayout()
        self.list = QListWidget()
        self.textBox = QTextEdit()
        self.textBox.resize(200, 200)

        ### Add button ###
        self.button = QPushButton("Apply")

        self.main_layout.addLayout(self.layout)
        self.main_layout.addWidget(self.button)
        self.setLayout(self.main_layout)

        self.layout.addWidget(self.list)
        self.layout.addWidget(self.textBox)

        ### Variables ###
        self.settings = None

        self.list.itemClicked.connect(self.item_clicked)
        self.connect(self.button, QtCore.SIGNAL("clicked()"),
                     self.apply_settings)

    def item_clicked(self, item):
        """Action triggered when an item is clicked. The content of the metadata is retrieved from its index and not from the file itself, avoiding clashes with the main program. """

        i = self.list.currentRow()
        self.settings = self.all_settings[i]
        self.textBox.clear()
        self.textBox.setText(self.settings)
        # mdd = self.settings.split('\n')
        # for t in mdd:
        #     self.textBox.append(t)

    def add_items(self, name):
        """ Adds the group items to the display.
        The file is closed after extracting the metadata, to avoid conflicts with the main program. 
        
        :param name: Name of the HDF file to be opened.
        :return: Null 
        """
        f = h5py.File(name, 'r')
        self.settings = None
        self.all_settings = []
        self.list.clear()
        for g in f:
            self.all_settings.append(f[g + '/metadata'][()].decode('ascii'))
            self.list.addItem(g)

        f.close()

    def apply_settings(self):
        """ Triggered when the apply button is pressed. The settings are broadcasted as coming from the parent. 
        """
        if self.settings is not None:
            self.parent.emit(QtCore.SIGNAL('settings'), self.settings)
Example #9
0
class QChatWidget(QWidget):
    def __init__(self, connectionManager, parent=None):
        QWidget.__init__(self, parent)

        self.connectionManager = connectionManager
        self.isDisabled = False
        self.wasCleared = False

        self.urlRegex = re.compile(constants.URL_REGEX)

        self.chatLog = QTextBrowser()
        self.chatLog.setOpenExternalLinks(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chatInput)
        hbox.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hbox)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() *
                                          3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typingTimer = QTimer()
        self.typingTimer.setSingleShot(True)
        self.typingTimer.timeout.connect(self.stoppedTyping)

    def chatInputTextChanged(self):
        # Check if the text changed was the text box being cleared to avoid sending an invalid typing status
        if self.wasCleared:
            self.wasCleared = False
            return

        if str(self.chatInput.toPlainText())[-1:] == '\n':
            self.sendMessage()
        else:
            # Start a timer to check for the user stopping typing
            self.typingTimer.start(constants.TYPING_TIMEOUT)
            self.sendTypingStatus(constants.TYPING_START)

    def stoppedTyping(self):
        self.typingTimer.stop()
        if str(self.chatInput.toPlainText()) == '':
            self.sendTypingStatus(constants.TYPING_STOP_WITHOUT_TEXT)
        else:
            self.sendTypingStatus(constants.TYPING_STOP_WITH_TEXT)

    def sendMessage(self):
        if self.isDisabled:
            return

        self.typingTimer.stop()

        text = str(self.chatInput.toPlainText())[:-1]

        # Don't send empty messages
        if text == '':
            return

        # Convert URLs into clickable links
        text = self.__linkify(text)

        # Add the message to the message queue to be sent
        self.connectionManager.getClient(self.nick).sendChatMessage(text)

        # Clear the chat input
        self.wasCleared = True
        self.chatInput.clear()

        self.appendMessage(text, constants.SENDER)

    def sendTypingStatus(self, status):
        self.connectionManager.getClient(self.nick).sendTypingMessage(status)

    def showNowChattingMessage(self, nick):
        self.nick = nick
        self.appendMessage("You are now securely chatting with " + self.nick +
                           " :)",
                           constants.SERVICE,
                           showTimestampAndNick=False)

        self.appendMessage(
            "It's a good idea to verify the communcation is secure by selecting "
            "\"authenticate buddy\" in the options menu.",
            constants.SERVICE,
            showTimestampAndNick=False)

    def appendMessage(self, message, source, showTimestampAndNick=True):
        color = self.__getColor(source)

        if showTimestampAndNick:
            timestamp = '<font color="' + color + '">(' + utils.getTimestamp() + ') <strong>' + \
                        (self.connectionManager.nick if source == constants.SENDER else self.nick) + \
                        ':</strong></font> '
        else:
            timestamp = ''

        # If the user has scrolled up (current value != maximum), do not move the scrollbar
        # to the bottom after appending the message
        shouldScroll = True
        scrollbar = self.chatLog.verticalScrollBar()
        if scrollbar.value() != scrollbar.maximum(
        ) and source != constants.SENDER:
            shouldScroll = False

        self.chatLog.append(timestamp + message)

        # Move the vertical scrollbar to the bottom of the chat log
        if shouldScroll:
            scrollbar.setValue(scrollbar.maximum())

    def __linkify(self, text):
        matches = self.urlRegex.findall(text)

        for match in matches:
            text = text.replace(match[0],
                                '<a href="%s">%s</a>' % (match[0], match[0]))

        return text

    def __getColor(self, source):
        if source == constants.SENDER:
            if qtUtils.isLightTheme:
                return '#0000CC'
            else:
                return '#6666FF'
        elif source == constants.RECEIVER:
            if qtUtils.isLightTheme:
                return '#CC0000'
            else:
                return '#CC3333'
        else:
            if qtUtils.isLightTheme:
                return '#000000'
            else:
                return '#FFFFFF'

    def disable(self):
        self.isDisabled = True
        self.chatInput.setReadOnly(True)

    def enable(self):
        self.isDisabled = False
        self.chatInput.setReadOnly(False)
Example #10
0
class EditBox(QDialog):
    def __init__(self, data, title, description=None, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(title)
        self.setWindowModality(Qt.ApplicationModal)

        QVBoxLayout(self)
        self.list = ListEdit(parent=parent, isChild=True)
        self.list.displayUpDown = False
        self.list.editInPopup = False
        self.list.headers = parent.getHeaders()
        self.list.setColDelegate(parent.getColDelegate)
        self.list.reset([data])
        self.info = QTextEdit()
        self.error = QTextEdit()
        self.grid = None

        self.build(description)

    def build(self, description):
        self.layout().addWidget(self.list)

        cancel = QPushButton(QIcon(":/icons/wrong.png"), tr("Cancel"), self)
        save = QPushButton(QIcon(":/icons/apply.png"), tr("OK"), self)
        save.setDefault(True)

        self.connect(cancel, SIGNAL("clicked()"), self.doClose)
        self.connect(save, SIGNAL("clicked()"), self.doSave)

        self.grid = QWidget(self)
        self.setMinimumWidth(700)
        QGridLayout(self.grid)
        self.grid.layout().addWidget(save, 0, 0, Qt.AlignHCenter)
        self.grid.layout().addWidget(cancel, 0, 1, Qt.AlignHCenter)
        self.layout().addWidget(self.grid)

        self.info.setReadOnly(True)
        if description:
            self.info.append(description)
        else:
            self.info.setVisible(False)

        self.error.setReadOnly(True)
        self.error.setVisible(False)

        self.grid.layout().addWidget(self.info, 1, 0, 1, 0, Qt.AlignHCenter)
        self.grid.layout().addWidget(self.error, 2, 0, 1, 0, Qt.AlignHCenter)

    def doClose(self):
        self.reject()
        self.close()

    def doSave(self):
        self.error.clear()
        hasInvalidData = False
        for col in range(self.list.listEditView.model.columnCount()):
            index = self.list.listEditView.model.index(0, col)
            input_edit = self.list.listEditView.indexWidget(index)
            if not input_edit.isValid():
                col_name = self.list.listEditView.model.headerData(col, Qt.Horizontal, Qt.DisplayRole)
                col_name = unicode(col_name.toString())
                self.error.append(tr("Column '%s': must be '%s'") % (col_name,
                    input_edit.getFieldInfo()))
                hasInvalidData = True

        if hasInvalidData:
            self.error.setVisible(True)
        else:
            self.accept()
            self.close()

    def getData(self):
        """
        single selection only supported
        """
        return self.list.rawData()[0]
Example #11
0
class QChatWidget(QWidget):
    def __init__(self, connectionManager, parent=None):
        QWidget.__init__(self, parent)

        self.connectionManager = connectionManager
        self.isDisabled = False
        self.wasCleared = False

        self.urlRegex = re.compile(constants.URL_REGEX)

        self.chatLog = QTextBrowser()
        self.chatLog.setOpenExternalLinks(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chatInput)
        hbox.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hbox)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typingTimer = QTimer()
        self.typingTimer.setSingleShot(True)
        self.typingTimer.timeout.connect(self.stoppedTyping)

    def chatInputTextChanged(self):
        # Check if the text changed was the text box being cleared to avoid sending an invalid typing status
        if self.wasCleared:
            self.wasCleared = False
            return

        if str(self.chatInput.toPlainText())[-1:] == "\n":
            self.sendMessage()
        else:
            # Start a timer to check for the user stopping typing
            self.typingTimer.start(constants.TYPING_TIMEOUT)
            self.sendTypingStatus(constants.TYPING_START)

    def stoppedTyping(self):
        self.typingTimer.stop()
        if str(self.chatInput.toPlainText()) == "":
            self.sendTypingStatus(constants.TYPING_STOP_WITHOUT_TEXT)
        else:
            self.sendTypingStatus(constants.TYPING_STOP_WITH_TEXT)

    def sendMessage(self):
        if self.isDisabled:
            return

        self.typingTimer.stop()

        text = str(self.chatInput.toPlainText())[:-1]

        # Don't send empty messages
        if text == "":
            return

        # Convert URLs into clickable links
        text = self.__linkify(text)

        # Add the message to the message queue to be sent
        self.connectionManager.getClient(self.nick).sendChatMessage(text)

        # Clear the chat input
        self.wasCleared = True
        self.chatInput.clear()

        self.appendMessage(text, constants.SENDER)

    def sendTypingStatus(self, status):
        self.connectionManager.getClient(self.nick).sendTypingMessage(status)

    def showNowChattingMessage(self, nick):
        self.nick = nick
        self.appendMessage(
            "You are now securely chatting with " + self.nick + " :)", constants.SERVICE, showTimestampAndNick=False
        )

        self.appendMessage(
            "It's a good idea to verify the communcation is secure by selecting "
            '"authenticate buddy" in the options menu.',
            constants.SERVICE,
            showTimestampAndNick=False,
        )

    def appendMessage(self, message, source, showTimestampAndNick=True):
        color = self.__getColor(source)

        if showTimestampAndNick:
            timestamp = (
                '<font color="'
                + color
                + '">('
                + utils.getTimestamp()
                + ") <strong>"
                + (self.connectionManager.nick if source == constants.SENDER else self.nick)
                + ":</strong></font> "
            )
        else:
            timestamp = ""

        # If the user has scrolled up (current value != maximum), do not move the scrollbar
        # to the bottom after appending the message
        shouldScroll = True
        scrollbar = self.chatLog.verticalScrollBar()
        if scrollbar.value() != scrollbar.maximum() and source != constants.SENDER:
            shouldScroll = False

        self.chatLog.append(timestamp + message)

        # Move the vertical scrollbar to the bottom of the chat log
        if shouldScroll:
            scrollbar.setValue(scrollbar.maximum())

    def __linkify(self, text):
        matches = self.urlRegex.findall(text)

        for match in matches:
            text = text.replace(match[0], '<a href="%s">%s</a>' % (match[0], match[0]))

        return text

    def __getColor(self, source):
        if source == constants.SENDER:
            if qtUtils.isLightTheme:
                return "#0000CC"
            else:
                return "#6666FF"
        elif source == constants.RECEIVER:
            if qtUtils.isLightTheme:
                return "#CC0000"
            else:
                return "#CC3333"
        else:
            if qtUtils.isLightTheme:
                return "#000000"
            else:
                return "#FFFFFF"

    def disable(self):
        self.isDisabled = True
        self.chatInput.setReadOnly(True)

    def enable(self):
        self.isDisabled = False
        self.chatInput.setReadOnly(False)
Example #12
0
class InteractiveVelocityPlot(VelocityPlot):
    """
    Visual tool to help with fitting Voigt profiles to absorption lines
    in QSO spectra.

    """

    def __init__(self, filename, transitions, wavelength, flux, error,
                 continuum, redshift, **kwargs):

        # Main window:
        self.window = QMainWindow()

        # Host widget for plot, push button, and checkboxes:
        self.main_frame = QWidget()

        # Spectrum filename:
        self.filename = filename

        # Plotting options:
        self.options = kwargs

        # Optimise screen usage:
        if len(transitions) > 20:
            ncols = int(ceil(len(transitions) / 10))
        else:
            ncols = int(ceil(len(transitions) / 5))

        # Initialise plot:
        super(InteractiveVelocityPlot, self).__init__(
            transitions, ncols=ncols, aspect=0.45, **self.options['WINDOW'])

        # Attach canvas to host widget:
        self.canvas = FigureCanvasQTAgg(self)
        self.canvas.setParent(self.main_frame)

        # Text input/output:
        self.text_output = QTextEdit()

        # Push buttons:
        self.load_button = QPushButton('&Load')
        self.save_button = QPushButton('&Save')
        self.preview_button = QPushButton('&Preview')
        self.clear_button = QPushButton('&Clear')
        self.refresh_plot_button = QPushButton('&Refresh plot')
        self.plot_model_button = QPushButton('&Plot model')
        self.plot_all_models_button = QPushButton('&Plot all models')
        self.clear_models_button = QPushButton('&Clear models')
        self.runvpfit_button = QPushButton('&Run VPFIT')
        self.set_resolution = QPushButton('&Set resolution')
        self.help = QPushButton('&Help')
        self.quit = QPushButton('&Quit')

        # Checkboxes:
        self.cos_fuv_checkbox = QCheckBox('&use COS FUV LSF')
        self.cos_nuv_checkbox = QCheckBox('&use COS NUV LSF')
        self.include_checkbox = QCheckBox('&include previous')

        # Push button `clicked` connections:
        self.load_button.clicked.connect(self.on_load)
        self.save_button.clicked.connect(self.on_save)
        self.preview_button.clicked.connect(self.on_preview)
        self.clear_button.clicked.connect(self.on_clear)
        self.refresh_plot_button.clicked.connect(self.on_refresh)
        self.plot_model_button.clicked.connect(self.on_plot_model)
        self.plot_all_models_button.clicked.connect(self.on_plot_all_models)
        self.clear_models_button.clicked.connect(self.on_clear_models)
        self.runvpfit_button.clicked.connect(self.on_runvpfit)
        self.set_resolution.clicked.connect(self.on_resolution)
        self.help.clicked.connect(self.on_help)
        self.quit.clicked.connect(self.window.close)

        # Checkbox `stateChanged` connections:
        self.cos_fuv_checkbox.stateChanged.connect(self.on_cos_fuv_checkbox)
        self.cos_nuv_checkbox.stateChanged.connect(self.on_cos_nuv_checkbox)
        self.include_checkbox.stateChanged.connect(self.on_include_checkbox)

        # Set up grid layout:
        grid = QGridLayout()
        grid.setSpacing(10)

        # Add widgets:
        grid.addWidget(self.text_output, 1, 1, 4, 3)
        grid.addWidget(self.load_button, 1, 4)
        grid.addWidget(self.save_button, 2, 4)
        grid.addWidget(self.preview_button, 3, 4)
        grid.addWidget(self.clear_button, 4, 4)
        grid.addWidget(self.refresh_plot_button, 1, 5)
        grid.addWidget(self.plot_model_button, 2, 5)
        grid.addWidget(self.plot_all_models_button, 3, 5)
        grid.addWidget(self.clear_models_button, 4, 5)
        grid.addWidget(self.runvpfit_button, 1, 6)
        grid.addWidget(self.cos_fuv_checkbox, 2, 6)
        grid.addWidget(self.cos_nuv_checkbox, 3, 6)
        grid.addWidget(self.include_checkbox, 4, 6)
        grid.addWidget(self.set_resolution, 1, 7)
        grid.addWidget(self.help, 3, 7)
        grid.addWidget(self.quit, 4, 7)

        # Place plotting canvas above the options grid:
        vbox = QVBoxLayout()
        vbox.addWidget(self.canvas)
        vbox.addLayout(grid)

        # Set the layout to the host widget:
        self.main_frame.setLayout(vbox)

        # Store all static elements (can be very slow to re-draw these):
        self.canvas.draw()
        self.backgrounds = [self.canvas.copy_from_bbox(ax.bbox)
                            for ax in self.axes]

        # Plot the data:
        self.plot_data(wavelength, flux, error, continuum, redshift,
                       **self.options['DATA'])

        # Set the window title:
        self.window.setWindowTitle('vpguess z = {0:.3f}'.format(self.redshift))

        # Give keyboard focus to the figure:
        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()

        # Variable defaults:
        self.cos_fuv = False
        self.cos_nuv = False
        self.include = False
        self.last_loaded = None
        self.resolution = None

        # Keypress variables:
        self.previous_keypress = None
        self.previous_wavelength = None

        # Set up the key-press events:
        self.canvas.mpl_connect('key_press_event', self.on_keypress)

        # Set the main frame as the central widget:
        self.window.setCentralWidget(self.main_frame)

        # Resize the window so it will display the canvas with the
        # requested size:
        layout_height = vbox.sizeHint().height()
        layout_width = vbox.sizeHint().width()
        status_bar_height = self.window.statusBar().sizeHint().height()
        height = layout_height + status_bar_height
        self.window.resize(layout_width, height)

        # Re-do labels:
        del self.texts[:]
        self.text(0.45, 0.02, 'Velocity offset (km s$^{-1}$)')
        self.text(0.01, 0.57, 'Transmission', rotation=90)

        # Disable any existing callbacks:
        self.cids = dict()
        cids1 = list(self.canvas.callbacks.callbacks['key_press_event'])
        cids2 = list(self.canvas.callbacks.callbacks['button_press_event'])
        cids = cids1 + cids2
        for cid in cids:
            self.canvas.callbacks.disconnect(cid)

        # Connect new callbacks:
        self.connect()

    def update_plot(self, redshift):

        # Restore background regions:
        [self.canvas.restore_region(background)
         for background in self.backgrounds]

        # Plot data:
        [data.pop(0).remove() for data in self.data]
        self.plot_data(
            self.wavelength, self.flux, self.error, self.continuum,
            redshift, **self.options['DATA'])

        # Draw the artists:
        for artists in self.data:
            for element in artists:
                ax = element.get_axes()
                ax.draw_artist(element)

        # Plot the models (if any):
        if self.options['MODEL']['absorbers'] is not None:
            self.plot_models(resolution=self.resolution,
                             convolve_with_cos_fuv=self.cos_fuv,
                             convolve_with_cos_nuv=self.cos_nuv,
                             **self.options['MODEL'])

            # Draw the artists:
            for artists in self.models:
                for element in artists:
                    ax = element.get_axes()
                    ax.draw_artist(element)

        # Draw new panel labels:
        for i, transition in enumerate(self.transitions):

            ax = self.axes[self._ind[i]]
            transf = blended_transform_factory(ax.transAxes, ax.transData)
            name = transition.name

            # Use TeX fonts if specified:
            if self.usetex:
                name = name.split()
                if name[0][1].islower():
                    name = name[0][:2] + '$\;$\\textsc{' + \
                        name[0][2:].lower() + '} $\lambda$' + name[1]
                else:
                    name = name[0][:1] + '$\;$\\textsc{' + \
                        name[0][1:].lower() + '} $\lambda$' + name[1]

            label = ax.text(0.03, 0.5, name, fontsize=self.label_fontsize,
                            bbox=bbox, transform=transf)
            ax.draw_artist(label)

        # Update:
        self.canvas.update()
        self.window.setWindowTitle(
            'vpguess z = {0:.3f}'.format(self.redshift))

    @staticmethod
    def concatenate_results():

        from glob import glob
        results = glob('*.result')

        with open('.all_results', 'wb') as combined:
            for result in results:
                with open(result, 'rb') as single:
                    combined.write(single.read())

    @pyqtSlot(str)
    def on_output(self, output):

        self.text_output.moveCursor(QTextCursor.End)
        self.text_output.insertPlainText(output)

    def on_load(self):

        self.text_output.clear()

        directory = os.getcwd()
        filename = QFileDialog.getOpenFileName(
            self.window, 'Select f26 file', directory)

        with open(filename, 'rb') as f26:
            self.text_output.setText(f26.read())

        self.last_loaded = filename

    def on_save(self):

        directory = os.getcwd()
        filename, ok = QFileDialog.getSaveFileName(
            self.window, 'Save f26 file', directory)

        with open(filename, 'w') as f26:
            f26.write(str(self.text_output.toPlainText()))

        self.text_output.clear()
        self.last_loaded = None

    def on_preview(self):

        self.concatenate_results()

        with open('.f26_preview', 'wb') as preview:
            with open('.all_results', 'rb') as results:
                preview.write(str(self.text_output.toPlainText()))
                preview.write(results.read())

        f26 = read_f26('.f26_preview')

        self.options['MODEL']['absorbers'] = f26.absorbers
        self.update_plot(self.redshift)

    def on_clear(self):

        self.text_output.clear()
        self.last_loaded = None

    def on_refresh(self):

        self.update_plot(self.redshift)

    def on_plot_model(self):

        directory = os.getcwd()
        filename = QFileDialog.getOpenFileName(
            self.window, 'Select f26 file', directory)

        f26 = read_f26(filename)
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

    def on_plot_all_models(self):

        self.concatenate_results()

        f26 = read_f26('.all_results')
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

    def on_clear_models(self):

        self.options['MODEL']['absorbers'] = None
        self.update_plot(self.redshift)

    def on_runvpfit(self):

        from .vpfit import run_vpfit

        directory = os.getcwd()

        if self.last_loaded is not None:

            filename = self.last_loaded

            if self.text_output.document().isModified():
                with open(filename, 'w') as f26:
                    f26.write(str(self.text_output.toPlainText()))

        else:

            filename = QFileDialog.getSaveFileName(
                self.window, 'Save f26 file', directory)

            with open(filename, 'w') as f26:
                f26.write(str(self.text_output.toPlainText()))

        self.concatenate_results()
        inc = '.all_results' if self.include else None

        self.text_output.clear()
        fwhm = self.resolution if self.resolution is not None else 10
        run_vpfit(filename, inc, fwhm=fwhm, cos_fuv=self.cos_fuv,
                  cos_nuv=self.cos_nuv)

        self.concatenate_results()
        f26 = read_f26('.all_results')
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

        self.last_loaded = None

    def on_cos_fuv_checkbox(self, state):

        if state == Qt.Checked:
            self.cos_fuv = True

        else:
            self.cos_fuv = False

    def on_cos_nuv_checkbox(self, state):

        if state == Qt.Checked:
            self.cos_nuv = True

        else:
            self.cos_nuv = False

    def on_include_checkbox(self, state):

        if state == Qt.Checked:
            self.include = True

        else:
            self.include = False

    def on_resolution(self):

        resolution, ok = SpectralResolutionDialog.get_spectral_resolution(
            self.main_frame)

        if ok:
            self.resolution = resolution

    def on_help(self):

        QMessageBox.information(self.main_frame, 'Help', info, False)

    def on_buttonpress(self, event):

        if event.inaxes is None:
            return

        i = self.axes.index(event.inaxes)
        transition = self.transitions[np.where(self._ind == i)[0]]

        z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
        wavelength = transition.wavelength.value * (1 + z)

        isort = np.argsort(self.ticks['wavelength'])
        wavelengths = self.ticks['wavelength'][isort]
        transitions = self.ticks['transition'][isort]

        idx = wavelengths.searchsorted(wavelength)
        wavelength = wavelengths[idx]
        transition = atom.get_transition(transitions[idx])
        z = wavelength / transition.wavelength.value - 1

        message = '{0}, z = {1:.3f}'.format(transition.name, z)
        QMessageBox.information(self.main_frame, 'Transition', message, False)

    def on_keypress(self, event):

        if event.key == ' ' and event.inaxes is not None:

            z = self.redshift

            # Get amount to add to redshift:
            dz = (event.xdata / c_kms) * (1 + z)

            # Get new axis limits, if any:
            vmin, vmax = event.inaxes.get_xlim()
            self.vmin = min(0, vmin)
            self.vmax = max(0, vmax)
            self.update_plot(z + dz)

        if event.key == 'z':

            redshift, ok = QInputDialog.getText(
                self.main_frame, 'New Redshift', 'Enter redshift: ', False)

            if ok:
                self.update_plot(float(redshift))

        if event.key == 'b':

            i = self.axes.index(event.inaxes)
            transition = self.transitions[np.where(self._ind == i)[0]]

            z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
            wavelength = transition.wavelength.value * (1 + z)

            if (self.previous_keypress == 'b' and
                    self.previous_wavelength is not None):

                wmin = self.previous_wavelength
                wmax = wavelength

                if wmin > wmax:
                    wmin, wmax = wmax, wmin

                print('%% {0} 1 {1:.3f} {2:.3f} vfwhm=10.0'.format(
                    self.filename, wmin, wmax))

                self.previous_keypress = None
                self.previous_wavelength = None

            else:
                self.previous_wavelength = wavelength

        if event.key == 'l':

            from ..calculations.absorption import logn_from_tau_peak

            i = self.axes.index(event.inaxes)
            transition = self.transitions[np.where(self._ind == i)[0]]

            z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
            wavelength = transition.wavelength.value * (1 + z)
            index = self.wavelength.searchsorted(wavelength)

            flux = self.flux[index - 1:index + 1]
            error = self.error[index - 1:index + 1]
            continuum = self.continuum[index - 1:index + 1]
            flux_norm = flux / continuum
            error_norm = error / continuum

            valid = (error_norm > 0) & ~np.isnan(flux_norm)

            if not any(valid):
                print('No good pixels!')
                return

            flux_norm = np.median(flux_norm[valid])
            error_norm = np.median(error_norm[valid])

            if flux_norm < error_norm:
                flux_norm = error_norm

            elif flux_norm > 1 - error_norm:
                flux_norm = 1 - error_norm

            b = 20  # assume 20 km/s
            tau = -np.log(flux_norm)
            logn = logn_from_tau_peak(transition, tau, b)

            print('{0:6s} {1:8.6f} 0.0 {2:4.1f} 0.0 {3:4.1f} 0.0'.format(
                transition.parent, z, b, logn))

        if event.key == 'S':

            filename, ok = QInputDialog.getText(
                self.main_frame, 'Save Figure', 'Enter filename: ', False)

            if ok:
                self.savefig(filename)

        self.previous_keypress = event.key

    def connect(self):
        cids = dict()
        cids['key_press_event'] = self.canvas.mpl_connect(
            'key_press_event', self.on_keypress)
        cids['button_press_event'] = self.canvas.mpl_connect(
            'button_press_event', self.on_buttonpress)
        self.cids.update(cids)
Example #13
0
class PythonWidget(QWidget):
    def __init__(self, parent):
        super().__init__(parent)

        self.pythonScript = QTextEdit()
        self.pythonScript.setReadOnly(False)  # asked by Manolo
        self.pythonScript.setMaximumHeight(340)

        script_box = oasysgui.widgetBox(self,
                                        "",
                                        addSpace=False,
                                        orientation="vertical",
                                        height=545,
                                        width=750)
        script_box.layout().addWidget(self.pythonScript)

        console_box = oasysgui.widgetBox(script_box,
                                         "",
                                         addSpace=False,
                                         orientation="vertical",
                                         height=150,
                                         width=750)

        self.console = PythonConsole(self.__dict__, self)
        console_box.layout().addWidget(self.console)

        button_box = oasysgui.widgetBox(script_box,
                                        "",
                                        addSpace=False,
                                        orientation="horizontal")

        gui.button(button_box,
                   self,
                   "Run Script",
                   callback=self.execute_script,
                   height=35)
        gui.button(button_box,
                   self,
                   "Save Script to File",
                   callback=self.save_script,
                   height=35)

    def execute_script(self):
        self._script = str(self.pythonScript.toPlainText())
        self.console.write("\nRunning script:\n")
        self.console.push("exec(_script)")
        self.console.new_prompt(sys.ps1)

    def save_script(self):
        file_name = QFileDialog.getSaveFileName(self, "Save File to Disk", ".",
                                                "*.py")

        if not file_name is None:
            if not file_name.strip() == "":
                file = open(file_name, "w")
                file.write(str(self.pythonScript.toPlainText()))
                file.close()

                QMessageBox.information(
                    self, "QMessageBox.information()",
                    "File " + file_name + " written to disk", QMessageBox.Ok)

    def setText(self, text):
        self.pythonScript.clear()
        self.pythonScript.setText(self.parse_nans(text))

    def parse_nans(self, text):
        return text.replace("nan", "numpy.nan")

# --------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------

    if __name__ == "__main__":
        app = QApplication(sys.argv)
        w = OWmare()
        w.show()
        app.exec()
        w.saveSettings()
Example #14
0
class SVNPluginPropsDialog(QDialog):
    " SVN plugin properties dialog "

    def __init__(self, plugin, client, path, parent=None):
        QDialog.__init__(self, parent)

        self.__plugin = plugin
        self.__client = client
        self.__path = path

        self.__createLayout()
        self.setWindowTitle("SVN Properties of " + path)
        self.__populate()
        self.__propsView.setFocus()
        return

    def __populate(self):
        " Populate the properties list "
        # Get the currently selected name
        selectedName = None
        selected = list(self.__propsView.selectedItems())
        if selected:
            selectedName = str(selected[0].text(0))

        self.__propsView.clear()
        properties = readProperties(self.__client, self.__path)
        if properties:
            for itemPath, itemProps in properties:
                if self.__path == itemPath or \
                   self.__path == itemPath + os.path.sep:
                    for name, value in itemProps.iteritems():
                        name = str(name).strip()
                        value = str(value).strip()
                        newItem = QTreeWidgetItem([name, value])
                        self.__propsView.addTopLevelItem(newItem)

        self.__resizePropsView()
        self.__sortPropsView()

        if selectedName:
            index = 0
            for index in xrange(0, self.__propsView.topLevelItemCount()):
                item = self.__propsView.topLevelItem(index)
                if selectedName == item.text(0):
                    item.setSelected(True)
        return

    def __resizePropsView(self):
        " Resizes the properties table "
        self.__propsView.header().setStretchLastSection(True)
        self.__propsView.header().resizeSections(QHeaderView.ResizeToContents)
        return

    def __sortPropsView(self):
        " Sorts the properties table "
        self.__propsView.sortItems(
            self.__propsView.sortColumn(),
            self.__propsView.header().sortIndicatorOrder())
        return

    def __createLayout(self):
        " Creates the dialog layout "
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)

        hLayout = QHBoxLayout()
        self.__propsView = QTreeWidget()
        self.__propsView.setAlternatingRowColors(True)
        self.__propsView.setRootIsDecorated(False)
        self.__propsView.setItemsExpandable(False)
        self.__propsView.setSortingEnabled(True)
        self.__propsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__propsView.itemSelectionChanged.connect(
            self.__propsSelectionChanged)

        propsViewHeader = QTreeWidgetItem(["Property Name", "Property Value"])
        self.__propsView.setHeaderItem(propsViewHeader)
        self.__propsView.header().setSortIndicator(0, Qt.DescendingOrder)
        hLayout.addWidget(self.__propsView)

        self.__delButton = QToolButton()
        self.__delButton.setText("Delete")
        self.__delButton.setFocusPolicy(Qt.NoFocus)
        self.__delButton.setEnabled(False)
        self.__delButton.clicked.connect(self.__onDel)
        hLayout.addWidget(self.__delButton, 0, Qt.AlignBottom)
        vboxLayout.addLayout(hLayout)

        # Set property part
        setGroupbox = QGroupBox(self)
        setGroupbox.setTitle("Set Property")

        setLayout = QGridLayout(setGroupbox)
        setLayout.addWidget(QLabel("Name"), 0, 0, Qt.AlignTop | Qt.AlignRight)
        setLayout.addWidget(QLabel("Value"), 1, 0, Qt.AlignTop | Qt.AlignRight)

        self.__nameEdit = QLineEdit()
        self.__nameEdit.textChanged.connect(self.__nameChanged)
        setLayout.addWidget(self.__nameEdit, 0, 1)

        self.__valueEdit = QTextEdit()
        self.__valueEdit.setAcceptRichText(False)
        self.__valueEdit.textChanged.connect(self.__valueChanged)
        metrics = QFontMetrics(self.__valueEdit.font())
        rect = metrics.boundingRect("X")
        self.__valueEdit.setFixedHeight(rect.height() * 4 + 5)
        setLayout.addWidget(self.__valueEdit, 1, 1)

        self.__setButton = QToolButton()
        self.__setButton.setText("Set")
        self.__setButton.setFocusPolicy(Qt.NoFocus)
        self.__setButton.setEnabled(False)
        self.__setButton.clicked.connect(self.__onSet)
        setLayout.addWidget(self.__setButton, 1, 2,
                            Qt.AlignBottom | Qt.AlignHCenter)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            setGroupbox.sizePolicy().hasHeightForWidth())
        setGroupbox.setSizePolicy(sizePolicy)
        vboxLayout.addWidget(setGroupbox)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
        buttonBox.accepted.connect(self.close)
        vboxLayout.addWidget(buttonBox)
        return

    def __onSet(self):
        " Triggered when propery set is clicked "
        name = self.__nameEdit.text().strip()
        value = self.__valueEdit.toPlainText().strip()
        try:
            commitInfo = self.__client.propset(name, value, self.__path)
            if commitInfo:
                logging.info(str(commitInfo))
            self.__populate()
            self.__plugin.notifyPathChanged(self.__path)
            self.__nameEdit.clear()
            self.__valueEdit.clear()
            self.__propsView.setFocus()
        except pysvn.ClientError, exc:
            message = exc.args[0]
            logging.error(message)
            return
        except Exception, exc:
            logging.error(str(exc))
            return
Example #15
0
 def clear(self):
     self.urls = []
     QTextEdit.clear(self)
Example #16
0
class Calibrador(QWidget):
    def __init__(self, parent=None):
        super(Calibrador, self).__init__(parent)

        layout = QVBoxLayout()

        self.btabrir = QPushButton('Abrir')
        self.btabrir.clicked.connect(self.abrirArchivo)
        layout.addWidget(self.btabrir)

        self.gb1 = QGroupBox('Valores a Calibrar')
        l1 = QVBoxLayout()

        self.lx1 = QLabel('Archivo X1')
        self.x1 = QLineEdit()
        self.x1.setReadOnly(True)
        l1.addWidget(self.lx1)
        l1.addWidget(self.x1)

        self.lx2 = QLabel('Archivo X2')
        self.x2 = QLineEdit()
        self.x2.setReadOnly(True)
        l1.addWidget(self.lx2)
        l1.addWidget(self.x2)

        self.gb1.setLayout(l1)
        layout.addWidget(self.gb1)

        self.gb2 = QGroupBox('Valores de Referencia')
        l2 = QVBoxLayout()

        self.ly1 = QLabel('Archivo Y1')
        self.y1 = QLineEdit()
        self.y1.setReadOnly(True)
        l2.addWidget(self.ly1)
        l2.addWidget(self.y1)

        self.ly2 = QLabel('Archivo Y2')
        self.y2 = QLineEdit()
        self.y2.setReadOnly(True)
        l2.addWidget(self.ly2)
        l2.addWidget(self.y2)

        self.gb2.setLayout(l2)
        layout.addWidget(self.gb2)

        self.btlimpiar = QPushButton('Limpiar')
        self.btlimpiar.clicked.connect(self.limpiar)
        layout.addWidget(self.btlimpiar)

        self.contents = QTextEdit()
        self.contents.setReadOnly(True)
        layout.addWidget(self.contents)

        self.btcalibrar = QPushButton('Calibrar')
        self.btcalibrar.clicked.connect(self.calibrar)
        layout.addWidget(self.btcalibrar)

        self.setLayout(layout)
        self.setWindowTitle('Calibrador Radiométrico')
        self.setWindowIcon(QIcon('c:/Users/Juanjo/Pictures/CONAE_chico_transp.ico'))

    def abrirArchivo(self):
        f = QFileDialog.getOpenFileName(self, 'Abrir archivo a calibrar', expanduser('~'), 'Textos (*.txt)')
        nom = f.split('/')
        if self.x1.text() == '':
            self.xi = f
            self.x1.setText(nom[len(nom)-1])
        elif self.x2.text() == '':
            self.xj = f
            self.x2.setText(nom[len(nom)-1])
        elif self.y1.text() == '':
            self.yi = f
            self.y1.setText(nom[len(nom)-1])
        elif self.y2.text() == '':
            self.yj = f
            self.y2.setText(nom[len(nom)-1])
        else:
            self.contents.setText('Limpie los campos para cagar nuevos archivos')

    def limpiar(self):
        self.x1.clear()
        self.x2.clear()
        self.y1.clear()
        self.y2.clear()
        self.contents.clear()

    def calibrar(self):
        if self.x1.text() == '' or self.x2.text() == '' or self.y1.text() == '' or self.y2.text() == '':
            self.contents.setText('Cargue todos los archivos antes de calibrar.')
        else:
            self.contents.setText('Calibrando...')
            w, xi, xj, yi, yj = leer(self.xi, self.xj, self.yi, self.yj)
            if isinstance(xi, list) and isinstance(xj, list) and isinstance(yi, list) and isinstance(yj, list):
                self.c1, self.c2, pends, ords = corregir(w, xi, xj, yi, yj)
                crear_archivo(w, self.c1, self.c2, self.x1.text().split('.')[0], self.x2.text().split('.')[0], pends, ords)
                self.contents.setText('Calibrado.\nArchivos generados en el Escritorio.\n\n'
                                      'Se calibraron los archivos:\n'+self.x1.text()+'\n'+self.x2.text())

            else:
                if isinstance(xi, str):
                    self.contents.setText('Se encontró inconsistencia en los datos contenidos por el archivo: \n\n* '
                                          +self.x1.text()+'\n\n'+'Limpie los campos e ingrese nuevamente archivos '
                                          'con datos correctos de la forma:\n\nWavelength\tnombre_archivo\n350\t'
                                            '7,06635974347591E-03\n351\t7,32030812650919E-03\n...')
                if isinstance(xj, str):
                    self.contents.setText('* Se encontró inconsistencia en los datos contenidos por el archivo: \n\n* '
                                          +self.x2.text()+'\n\n'+'Limpie los campos e ingrese nuevamente archivos '
                                          'con datos correctos de la forma:\n\nWavelength\tnombre_archivo\n350\t'
                                            '7,06635974347591E-03\n351\t7,32030812650919E-03\n...')
                if isinstance(yi, str):
                    self.contents.setText('* Se encontró inconsistencia en los datos contenidos por el archivo: \n\n* '
                                          +self.y1.text()+'\n\n'+'Limpie los campos e ingrese nuevamente archivos '
                                          'con datos correctos de la forma:\n\nWavelength\tnombre_archivo\n350\t'
                                            '7,06635974347591E-03\n351\t7,32030812650919E-03\n...')
                if isinstance(yj, str):
                    self.contents.setText('* Se encontró inconsistencia en los datos contenidos por el archivo: \n\n* '
                                          +self.y2.text()+'\n\n'+'Limpie los campos e ingrese nuevamente archivos '
                                          'con datos correctos de la forma:\n\nWavelength\tnombre_archivo\n350\t'
                                            '7,06635974347591E-03\n351\t7,32030812650919E-03\n...')
Example #17
0
class Chat(QFrame):

    # =======================================================================
    def __init__(self, parent=None, _PARENT=None):

        # -------------------------------------------------------------------
        QFrame.__init__(self, parent);
        # -------------------------------------------------------------------
        self.PARENT                         = _PARENT;
        self.CONF                           = _PARENT.CONF;

        self.setGeometry(3, 5, 975, 548);
        self.setStyleSheet( "QFrame{ font: 12px 'monospace'; color: #000; background-color: transparent; background-image: url('./data/imgs/TAB_Chat.png'); }" );

        # -------------------------------------------------------------------
        self.CHAT_URL                       = "https://btc-e.com/";
        self.CHAT_DATA                      = [];
        self.CHAT_LANG                      = self.CONF["USER"]["CHAT_LANG"];

        self.CHAT_HEADERS = {
            "User-Agent"        : "Mozilla/5.0 (Win-32; rv:24.0) Gecko/20140723 Firefox/24.0 Iceweasel/24.7.0",
            "Accept"            : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language"   : "en-US,en;q=0.5",
            "Referer"           : "https://btc-e.com/",
            "Connection"        : "keep-alive",
            "Cache-Control"     : "max-age=0",
            "Cookie"            : ""
        }

        self.CHAT_TIMER                     = QTimer();
        #self.CHAT_BG_COLOR                  = "#555";
        self.CHAT_BG_COLOR                  = "#0F0";
        self.CHAT_ALLOW_UPD                 = False;
        # -------------------------------------------------------------------
        self.CHAT_WIDGET                    = QTextEdit( self );
        self.CHAT_WIDGET.setGeometry( 13, 116, 690, 388 );
        self.CHAT_WIDGET.setStyleSheet( "QTextEdit{ background-color: transparent; color: #fff; background-image: url(''); }" );
        self.CHAT_WIDGET.setReadOnly( True );

        self.LANG_COMBO                     = QComboBox( self);
        self.LANG_COMBO.setGeometry( 86, 20, 108, 44 ); 
        self.connect( self.LANG_COMBO, SIGNAL('currentIndexChanged(int)'), self.CHANGE_CHAT_LANG );
        self.LANG_COMBO.setEditable(False);
        

        self.NEW_MSG                    = QLineEdit("", self);
        self.NEW_MSG.setGeometry( 20, 510, 500, 30 );
        self.NEW_MSG.setStyleSheet(" QLineEdit{ border-style: none; background-color: #333; color: #fff; background-image: url(''); }");
        self.NEW_MSG.setPlaceholderText(" Enter message:");



        self.SEND                       = QPushButton(" Send", self); 
        self.SEND.setGeometry( 593, 510, 90, 30 );
        #self.SEND.setStyleSheet( "QPushButton{ background-color: transparent; border-style: none; }" ); 
        #self.connect( self.SEND, SIGNAL('clicked()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SEND_VALUES") );

        # -------------------------------------------------------------------
        self.ALLOW_UPDATE_CHECKBOX        = QCheckBox("", self);
        self.ALLOW_UPDATE_CHECKBOX.setGeometry( 335, 83, 17, 17 );
        self.ALLOW_UPDATE_CHECKBOX.setCheckState(Qt.Unchecked);
        self.connect(self.ALLOW_UPDATE_CHECKBOX, SIGNAL('stateChanged(int)'), self.CHANGE_VALUES );


        self.UPDATE_NOW_BTN               = QPushButton("Update Now!", self);
        self.UPDATE_NOW_BTN.setGeometry( 360, 74, 94, 24 );
        self.connect( self.UPDATE_NOW_BTN, SIGNAL('clicked()'), self.UPDATE_NOW );

        # -------------------------------------------------------------------
        self.INIT();
        # -------------------------------------------------------------------

    # =======================================================================
    def INIT(self):

        # -------------------------------------------------------------------
        try:
            self.INIT_CHAT_COMBO();
            self.UPDATE();

        except Exception as _exception:

            print("-----------------------------------------------------");
            print("[INIT]"+str(_exception));
        # -------------------------------------------------------------------

    # =======================================================================
    def UPDATE_NOW(self):

        # -------------------------------------------------------------------
        self.CHAT_ALLOW_UPD = True;

        self.UPDATE();

        self.CHAT_ALLOW_UPD = False;
        # -------------------------------------------------------------------

    # =======================================================================
    def UPDATE(self):

        # -------------------------------------------------------------------
        #print("UPDATE:")
        # -------------------------------------------------------------------
        try:

            if self.CHAT_ALLOW_UPD:

                self.GET_DATA();
                self.CHAT_WIDGET.clear();

                for msg in self.CHAT_DATA:

                    # ---------------------------------------------------------------
                    """
                    print(msg["time"]);
                    print(msg["nick"]);
                    print(msg["msg"]);
                    """

                    # ---------------------------------------------------------------
                    item = '<p style="background-color: #555;">';                
                    item += "[<span style='color: #000;'>"+msg["time"].split(" ")[1]+"</span>] : ";

                    if msg["nick"] == "admin":
                        item += "[<span style='color: #f00; font-weight: bold;'>"+msg["nick"]+"</span>]<br/><br/>";
                    else:
                        item += "[<span style='color: #000; font-weight: bold;'>"+msg["nick"]+"</span>]<br/><br/>";

                    item += msg["msg"]+"<br/>";
                    item += "</p>";

                    self.CHAT_WIDGET.append(item);


                    # ---------------------------------------------------------------

            self.CHAT_TIMER.singleShot( self.CONF["SYS"]["UPD_DELAY"], self.UPDATE );

        except Exception as e:
            
            print("CHAT[0:0]"+str(e))
            self.CHAT_TIMER.singleShot( self.CONF["SYS"]["UPD_DELAY"], self.UPDATE );

        # -------------------------------------------------------------------

    # =======================================================================
    def CHANGE_VALUES(self):

        # -------------------------------------------------------------------
        if self.ALLOW_UPDATE_CHECKBOX.isChecked():
            self.CHAT_ALLOW_UPD = True;

        else:
            self.CHAT_ALLOW_UPD = False;

        # -------------------------------------------------------------------

    # =======================================================================
    def GET_DATA(self):
        
        # -------------------------------------------------------------------
        try:

            self.CHAT_HEADERS["Cookie"] = "chatRefresh=1; locale="+self.CHAT_LANG+";"

            req = urllib2.Request(self.CHAT_URL, headers=self.CHAT_HEADERS);
            resp = urllib2.urlopen(req).read();

            CHAT = BeautifulSoup( resp ).body.find('div', attrs={'id':'nChat'});

            self.CHAT_DATA = [];

            for data in CHAT:

                self.CHAT_DATA.append( { "msg_id": data["id"], "nick":data.a.string, "time": data.a["title"], "msg": data.span.string } );


        except Exception as e:
            
            print("CHAT[0:1]"+str(e))
        # -------------------------------------------------------------------

    # =======================================================================
    def CHANGE_CHAT_LANG(self):

        # -------------------------------------------------------------------
        self.CHAT_LANG = str(self.LANG_COMBO.currentText()).lower().strip();
        #print(self.CHAT_LANG);
        # -------------------------------------------------------------------

    # =======================================================================
    def INIT_CHAT_COMBO(self):

        # -------------------------------------------------------------------
        for LANG in self.CONF["USER"]["CHAT_LANGS"]:
            self.LANG_COMBO.addItem(LANG.upper());

        for i in xrange(0, self.LANG_COMBO.__len__()):

            self.LANG_COMBO.setItemData( i, QColor("#333"),Qt.BackgroundRole );
            self.LANG_COMBO.setItemData( i, QColor("#fff"),Qt.ForegroundRole );
Example #18
0
class MainWindow(QMainWindow):
   """ MainWindow(QMainWindow) This is the class/object for the main window 
       of the GUI application. This main window and GUI applicaiton are a Single
       Document Interface (SDI) Application. """

   # ---------------------------------------------------------------------------
   def __init__(self, parent = None):  
      """ MainWindow constructor  """         
   
      # Text messages for the class are set here 
      self.genericMsg = "WARNING -- Your changes have NOT been saved.\nAre you sure you want to %s\nand lose all of your changes?"
      self.quit_msg   = self.genericMsg %"exit the program"   
      self.new_msg    = self.genericMsg %"start a new file"   
      self.open_msg   = self.genericMsg %"open a new file"   
      self.close_msg  = self.genericMsg %"close this file"
      
      self.testcases       = [] # \
      self.testsuitefolder = "" #  \__ Start with a clean slate.
      
      # Read the confuration file data into the local class namespace as the
      # class will need this information.  
      try:
         self.configs = {}
         self.configs = configFile2dictionary(CONFIG_FILE)
         # print self.configs 
         if len(self.configs) == 0:
            raise Exception ("Failed to read configurations from \"%s\"" %CONFIG_FILE)
         self.configs['testcasefolder'] = os.path.join(MY_PATH, self.configs['testcasefolder'])
         self.configs['resultshome']  = os.path.join(MY_PATH, self.configs['resultshome'])
      except Exception as e:
         # TODO: SHow this as a message box as well
         print e
         print "Using default configurations"
         self.configs['testcasefolder'] = "/tmp/testcases"
         self.configs['resultshome']  = "/var/www/html/results"
        
      # Call to the Super Class for QT MainWindow
      super(MainWindow, self).__init__() # Don't ask, just do it.

      # Set up a way to write to the Console Area in from a separate thread. This 
      # allows for real-time output to the consoleArea.   
      self.consoleMessage   = pyqtSignal(str)
      self.connect(self, SIGNAL("self.consoleMessage"), self.updateConsole)
      
      # Set up a way to write to the Debug Area from a separate thread. This 
      # allows for real-time output to the consoleArea.   
      self.debugMessage   = pyqtSignal(str)
      self.connect(self, SIGNAL("self.debugMessage"), self.updateDebug)
            
      # Set up a way to write to the Results Area from a separate thread. This 
      # allows for real-time output to the resultsArea.   
      self.resultsMessage   = pyqtSignal(str)
      self.connect(self, SIGNAL("self.resultsMessage"), self.updateResults)      

      # The Steps for creating the main windows
      self.create_menubarActions()
      self.create_menubar()
      self.create_toolbarActions()
      self.create_toolbar()
      self.createWidgets()
      self.paint_mainWindow()
      self.setState(0) # This needs fixed, see setState()
     
   # ---------------------------------------------------------------------------   
   def create_menubarActions(self):
      # 
      # Create the menubar actions that will server as the link between 
      # menubar items and function calls. NOTE: Every 'triggered' argument 
      # must point to a valid function.  
      
      # File Menu Actions  - - - - - - - - - - - - - - - - - - - - - - - - - - - 
      self.mbExit   = QAction( "E&xit",    self, shortcut="Alt+E", statusTip="Exit the application",  triggered=self.cleanExit)       
      self.mbNew    = QAction( "N&ew",     self, shortcut="Alt+N", statusTip="Create a new file",     triggered=self.newFile)      
      self.mbOpen   = QAction( "O&pen",    self, shortcut="Alt+O", statusTip="Open an existing file", triggered=self.openFile)
      self.mbClose  = QAction( "C&lose",   self, shortcut="Alt+C", statusTip="Close a file",          triggered=self.closeFile)
      self.mbSave   = QAction( "S&ave",    self, shortcut="Alt+S", statusTip="Save the  file",        triggered=self.saveFile)
      self.mbSaveAs = QAction( "Save A&s", self, shortcut="Alt+A", statusTip="Save a file as",        triggered=self.saveAsFile)
      
      # Script Menu Actions  - - - - - - - - - - - - - - - - - - - - - - - - - - 
      self.mbRun   = QAction( "R&un",  self, shortcut="Alt+R", statusTip="Run the loaded file",       triggered=self.runScript)
      self.mbStop  = QAction( "S&top", self, shortcut="Alt+S", statusTip="Stop script execution ",    triggered=self.stopScript) 
      self.mbDebug = QAction( "D&ebug",self, shortcut="Alt+D", statusTip="Debug the loaded file",     triggered=self.debugScript)
      
      # Help Menu Actions   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
      self.mbHelp  = QAction( "H&elp",  self, shortcut="Alt+H", statusTip="Display help",             triggered=self.showHelp) 
      self.mbAbout = QAction( "A&bout", self, shortcut="Alt+A", statusTip="About This program",       triggered=self.showAbout)    
   
   
   # ---------------------------------------------------------------------------
   def create_toolbarActions(self):
      # Create the actions for the toolbar. Status tips and shortcut keys for 
      # the toolbar components are defined here. NOTE: Every 'triggered' 
      # connection must point to a valid function.   
      self.tbExit = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Exit.png')), 'Exit', self)
      self.tbExit.setShortcut('Ctrl+Q')
      self.tbExit.setStatusTip('Exit application')
      self.tbExit.triggered.connect(self.cleanExit)
      
      self.tbNew = QAction(QIcon(os.path.join(RESOURCE_PATH, 'New.png')), 'New', self)
      self.tbNew.setShortcut('Ctrl+N')
      self.tbNew.setStatusTip('Start a new file')
      self.tbNew.triggered.connect(self.newFile)

      self.tbOpen = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Open.png')), 'Open', self)
      self.tbOpen.setShortcut('Ctrl+O')
      self.tbOpen.setStatusTip('Open an existing file')
      self.tbOpen.triggered.connect(self.openFile)

      self.tbSave = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Save.png')), 'Save', self)
      self.tbSave.setShortcut('Ctrl+S')
      self.tbSave.setStatusTip('Save to a file ')
      self.tbSave.triggered.connect(self.saveFile)

      self.tbRun = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Run.png')), 'Run', self)
      self.tbRun.setShortcut('Ctrl+R')
      self.tbRun.setStatusTip('Run the loaded script')
      self.tbRun.triggered.connect(self.runScript)

      self.tbStop = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Stop.png')), 'Stop', self)
      self.tbStop.setShortcut('Ctrl+S')
      self.tbStop.setStatusTip('Stop script execution')
      self.tbStop.triggered.connect(self.stopScript)
      
      self.tbDebug = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Debug.png')), 'Debug', self)
      self.tbDebug.setShortcut('Ctrl+D')
      self.tbDebug.setStatusTip('Debug script')
      self.tbDebug.triggered.connect(self.debugScript)

      self.tbInfo = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Info.png')), 'Info', self)
      self.tbInfo.setShortcut('Ctrl+O')
      self.tbInfo.setStatusTip('Info About this program')
      self.tbInfo.triggered.connect(self.showAbout)

      self.tbHelp = QAction(QIcon(os.path.join(RESOURCE_PATH, 'Help.png')), 'Help', self)
      self.tbHelp.setShortcut('Ctrl+H')
      self.tbHelp.setStatusTip('Help using this program')
      self.tbHelp.triggered.connect(self.showHelp)
   
   # ---------------------------------------------------------------------------
   def create_toolbar(self):   
      self.toolbar = self.addToolBar('Main')
      self.toolbar.addAction(self.tbOpen)
      self.toolbar.addAction(self.tbNew)      
      self.toolbar.addAction(self.tbSave)
      self.toolbar.addAction(self.tbExit)
      self.toolbar.addSeparator()  # -------------
      self.toolbar.addAction(self.tbRun)
      self.toolbar.addAction(self.tbStop)
      self.toolbar.addAction(self.tbDebug)
      self.toolbar.addSeparator() # --------------       
      self.toolbar.addAction(self.tbHelp)
      self.toolbar.setIconSize(QSize(50,50))

   # ---------------------------------------------------------------------------
   def create_menubar(self): 
      # Create File Menu
      self.fileMenu = QMenu("&File")
      self.fileMenu.addAction(self.mbNew)      
      self.fileMenu.addAction(self.mbOpen)
      self.fileMenu.addSeparator()
      self.fileMenu.addAction(self.mbSave)  
      self.fileMenu.addAction(self.mbSaveAs)  
      self.fileMenu.addSeparator()
      self.fileMenu.addAction(self.mbClose) 
      self.fileMenu.addAction(self.mbExit)
      # Create Script Menu 
      self.scriptMenu = QMenu("&Script")
      self.scriptMenu.addAction(self.mbRun)
      self.scriptMenu.addAction(self.mbStop)
      self.scriptMenu.addAction(self.mbDebug)
      # Create Help Menu
      self.helpMenu = QMenu("&Help")
      self.helpMenu.addAction(self.mbHelp)
      self.helpMenu.addAction(self.mbAbout)
      # Add menus to menubar
      menubar = self.menuBar()
      menubar.addMenu(self.fileMenu)
      menubar.addMenu(self.scriptMenu)
      menubar.addMenu(self.helpMenu)

   # ---------------------------------------------------------------------------   
   def createWidgets(self):
      # Create the widgets used in the main window and other parts of the script.
      
      # --- Text Area ----
      self.textArea = QTextEdit()                     # Text editor
      self.textArea.setFont(QFont("Courier", 14))     # Keepin' it simple

      # -- Console Area ---
      self.consoleArea = QTextEdit()                  # Console Area 
      consolePalette = QPalette()                     # A bit more complex
      bgColor = QColor(0, 0, 0)                       #   Green Text with  
      txColor = QColor(0, 255, 0)                     #   Black background 
      consolePalette.setColor(QPalette.Base, bgColor) # 
      consolePalette.setColor(QPalette.Text, txColor) # 
      self.consoleArea.setPalette(consolePalette)     # 
      self.consoleArea.setFont(QFont("Courier", 14))  # Font name and size
      self.consoleArea.setReadOnly(True)              # Read only  

      # --- Debug Area ---
      self.debugArea = QTextEdit()                    # Debug Area
      debugPalette = QPalette()                       # Palette for area
      bgColor = QColor(0, 0, 0)                       # Black Background 
      debugPalette.setColor(QPalette.Base, bgColor)   #
      txColor = QColor(255, 0, 0)                     # Red Text
      debugPalette.setColor(QPalette.Text, txColor)   #
      self.debugArea.setPalette(debugPalette)         #
      self.debugArea.setFont(QFont("Courier", 14))    # Font name and size
      self.debugArea.setReadOnly(True)                # Read only
   
      # --- Results Area ---
      self.resultsArea = QTextEdit()                  # Results Area
      consolePalette = QPalette()                     # A bit more complex
      bgColor = QColor(0, 0, 0)                       #   White Text with  
      txColor = QColor(255, 255, 255)                 #   Black background 
      consolePalette.setColor(QPalette.Base, bgColor) # 
      consolePalette.setColor(QPalette.Text, txColor) # 
      self.resultsArea.setPalette(consolePalette)     # 
      self.resultsArea.setFont(QFont("Courier", 10))  # Font name and size
      self.resultsArea.setReadOnly(True)              # Read only  
      
      # --- Tab Area ---  
      self.tabs = QTabWidget()                       # Tabs
      self.tabs.addTab(self.consoleArea, 'Console')  # Add Console Area tab 
      self.tabs.addTab(self.debugArea,   'Debug'  )  # Add Debug Area tab
      self.tabs.addTab(self.resultsArea, 'Results')  # Add Results Area tab
      # TODO: Change the tab indexes to meaningful words not just 0,1,2
      self.tabs.setTabIcon(0, QIcon(os.path.join(RESOURCE_PATH, "Run.png"     ))) # Add Icon to tab  
      self.tabs.setTabIcon(1, QIcon(os.path.join(RESOURCE_PATH, "Debug.png"   ))) # Add Icon to tab
      self.tabs.setTabIcon(2, QIcon(os.path.join(RESOURCE_PATH, "results.png" ))) # Add Icon to tab
      self.tabs.setIconSize(QSize(30,30))
      self.tabs.setTabShape(QTabWidget.Triangular)   # Set tab shape
   
   # ---------------------------------------------------------------------------
   def paint_mainWindow(self):
         
      # Define and use a "Grid Layout" for the main window.
      grid = QGridLayout()
      grid.addWidget(self.textArea, 1, 1)
      grid.addWidget(self.tabs,     2, 1)
      
      # Create central widget, add layout, and set
      central_widget = QWidget()
      central_widget.setLayout(grid)
      self.setCentralWidget(central_widget)      
      
      # Fun feature for users. If you are going to have a toolbar then you 
      # really need this status bar to show what the icons do.        
      self.statusbar = QStatusBar(self) 
      self.statusbar.setObjectName( "statusbar") 
      MainWindow.setStatusBar(self, self.statusbar) 
      self.statusbar.show()
      
      # Initial settings for the main window 
      #
      #    Set the Main Window Geometry
      top    =  100 # Main Window initial 'top' position (as pixels from top of screen)
      left   =  100 # Main Window initial 'left' position (as pixels from left side of screen)
      width  = 1000 # Main Window initial 'width' (as pixels)
      height =  700 # Main Window initial 'height' (as pixels)
      self.setGeometry(QRect(top, left, width, height))  
 
      # Create connection(s)
      #    If the contents of the text area are changed then call a function 
      #    to set the appropriate file menu state. This file menu state can 
      #    also be used to ensure clean exits. In english, keep track 
      #    of changes to the text editor. It affects the "state" of the
      #    application. See setState()
      self.connect(self.textArea, SIGNAL("textChanged()"), self.textChanged)

  # ---------------------------------------------------------------------------      
   def cleanExit(self): 
      # Provides an "ARE YOU SURE" method for clean exits.
      if self.state == 2: # See setState()
         reply = QMessageBox.question(self, 'Message', self.quit_msg, QMessageBox.Yes, QMessageBox.No)
         if reply == QMessageBox.Yes:
            qApp.quit()
         else:
            pass
      else:   
         qApp.quit()
         
   # ---------------------------------------------------------------------------      
   def newFile(self): 
      # Start a new file. However, if a file is already open AND has not been 
      # saved, then we prompt the user before starting a new file. 
      # Remember, we are implementing SDI behavior, google it.   
      if self.state == 2:
         reply = QMessageBox.question(self, 'Message', self.new_msg, QMessageBox.Yes, QMessageBox.No)
         if reply == QMessageBox.Yes:
            self.textArea.clear()
            self.consoleArea.clear()
            self.debugArea.clear()
            self.resultsArea.clear()
            self.inputFile = ''
            self.setState(1)
            self.updateDebug("New File Started")
         else:
            self.updateDebug("New File Aborted")
      else:   
         self.textArea.clear()
         self.consoleArea.clear()
         self.debugArea.clear()
         self.resultsArea.clear()
         self.inputFile = '' 
         self.setState(1)
         self.updateDebug("New File Started")

   #----------------------------------------------------------------------------
   def openFile(self): 
      # Open a new file. However, if a file is already open AND has not been 
      # saved, then we prompt the user before opening a new file. 
      # Remember, we are implementing SDI behavior, google it.   
      if self.state == 2:
         reply = QMessageBox.question(self, 'Message', self.open_msg, QMessageBox.Yes, QMessageBox.No)
         if reply == QMessageBox.Yes:
            self.textArea.clear()
            self.consoleArea.clear()
            self.debugArea.clear()
            self.resultsArea.clear()
            self.inputFile = ''
            self.setState(1)
            # Let's go ahead and load the file.
            self.loadScript() 
         else:
            self.updateDebug("Open File aborted")
      else:   
         self.inputFile = QFileDialog.getOpenFileName(self, 'Open File', '.')
         fname = open(self.inputFile)
         data = fname.read()
         self.textArea.clear()
         self.consoleArea.clear()
         self.debugArea.clear()
         self.resultsArea.clear()
         self.textArea.setText(data)
         fname.close() 
         self.setState(1)
         # Let's go ahead and load the file.
         self.loadScript()       
      
   # ---------------------------------------------------------------------------      
   def closeFile(self): 
      # Close the open file and return to the initial/unopened state.
      # A clean exit has been implemented 
      if self.state == 2:
         reply = QMessageBox.question(self, 'Message', self.close_msg, QMessageBox.Yes, QMessageBox.No)
         if reply == QMessageBox.Yes:
            self.textArea.clear()
            self.consoleArea.clear()
            self.debugArea.clear()
            self.resultsArea.clear()
            self.inputFile = ""
            self.setState(0)
         else:
            self.updateDebug("Close File aborted")
      else:   
         self.textArea.clear()
         self.consoleArea.clear()
         self.debugArea.clear()
         self.resultsArea.clear()
         self.inputFile = ""
         self.setState(0)

   # ---------------------------------------------------------------------------               
   def saveFile(self): 
      # save the contents of text editor to a file
      if self.inputFile == "":
         self.saveAsFile()   
      else:
         if len(self.inputFile) > 0:
            filePointer = open(self.inputFile, 'w')
            filePointer.write(self.textArea.toPlainText())
            filePointer.close()
            self.setState(1) # Set initial menu state
            self.loadScript()
         else:
            # TODO: Add message box warning here
            pass         
   
   # ---------------------------------------------------------------------------      
   def saveAsFile(self): 
      # save the contents of text editor to a file
      filename = ""      
      filename = QFileDialog.getSaveFileName(self, 
                                             'Save File', 
                                             self.inputFile)
      if len(filename) > 0:
         filePointer = open(filename, 'w')
         filePointer.write(self.textArea.toPlainText())
         filePointer.close()
         self.inputFile = filename # Set to the new file name
         self.setState(1) # Set initial menu state
         self.loadScript()          
      else:
         # TODO: Add message box warning here
         pass      


   # ---------------------------------------------------------------------------
   def checkScript(self):
      """ Checks to see if the loaded script "test suite" is valid. Returns the 
          number of errors found in the script "test suite".  
          A valid script "test suite" has noting but:
            - Comment lines, starting with '#' 
            - Blank lines, contain nothing but white space
            - Filename lines, lines with the name of testcase filenames
      
         Anything else is considered an error. We also take the liberty of 
         verfying that all files (testcases) listed actually exist. Non-existant
         testcases are also errors. The details of this check are listed in the 
         debug tab of the main window.
      """
      errorCount     = 0 
      self.testcases = []
      self.updateDebug("Checking... ") 
      lines = self.textArea.toPlainText().split('\n')
      lineNumber = 0
      for line in lines:
         lineNumber += 1
         line = str(line)
         line = line.strip()
         if len(line) > 0:
            if line[FIRST] != '#':
               if os.path.exists(line): 
                  self.updateDebug("Console line %d: OK." %lineNumber)
                  self.testcases.append(line)
               else:
                  self.updateDebug("Console line %d: Unable to find test case \"%s\"." %(lineNumber, line))
                  errorCount += 1
            else:
               self.updateDebug("Console line %d: Skipped as comment." %lineNumber)            
         else:
            self.updateDebug("Console line %d: Skipped as whitespace." %lineNumber)
         lineNumber = lineNumber +1         
      self.updateDebug("Checked, found %d Error(s)" %errorCount )
      return errorCount
      
   # ---------------------------------------------------------------------------
   def loadScript(self):
      self.updateDebug("Loading \"%s\"" %self.inputFile)
      errors = self.checkScript()
      if errors == 0:
         self.consoleArea.clear() 
         self.debugArea.clear() 
         self.resultsArea.clear() 
         self.setState(4) 
         self.updateDebug("Loaded \"%s\""   %self.inputFile)
         self.updateConsole("Loaded \"%s\"" %self.inputFile)         
      else: 
         msg = "This script has errors and cannot be executed.\n"
         msg +=  "\nSee the Debug Tab for details."
         QMessageBox.critical(self, "Script Error", msg, QMessageBox.Ok) 
         self.setState(3) 
         self.updateConsole("Failed to load \"%s\"\nSee Debug tab for details." %self.inputFile)

   # ---------------------------------------------------------------------------      
   def threadedExecution(self, threadBuffer):
      """ This is the threaded execution of the test cases. While in this 
          thread/function please only use "self.emit(SIGNAL, message)" for  
          outputs to the tabs (console, debug, and results). Any other attempt 
          to update the tabs will raise an unhandled tread exception. 
      """
      try:
         self.setState(5) # Runing test
         
         # Entered Threaded Execution
         message = "Executing %d testcases" %len(self.testcases)
         self.emit(SIGNAL("self.consoleMessage"),  message)
         self.emit(SIGNAL("self.debugMessage"  ),  message)
         
         # For Results Report
         reportTime = time.strftime("%A, %B %d, %Y (%H:%M:%S)", time.localtime())
         message = """
Test Report for test suite: %s %s 

Test Cases in Suite:\n""" %(self.inputFile ,reportTime)
         counter = 0                                        # 
         for t in self.testcases:                           # Add a neatly 
            counter = counter + 1                           # printed list 
            message = message + "  %2d %s\n" %(counter, t)  # of test cases        

         message = message + """

Results Detailed in: %s
         
Results Summary: """ %self.testsuitefolder 

         self.emit(SIGNAL("self.resultsMessage"),  message)
         
         
         # Loop through each of the test cases and create subfolders for each 
         # testcase as we go                  
         testcaseCounter    = 0
         numberOfTestcases  = len(self.testcases)
         for testcase in self.testcases:
            
            # Loop/testcase Counter 
            testcaseCounter += 1
            
            # Initial Testcase Message 
            message = "Starting testcase %d of %d %s" %(testcaseCounter, numberOfTestcases, testcase)
            self.emit(SIGNAL("self.consoleMessage"),  message)
            self.emit(SIGNAL("self.debugMessage"  ),  message)
             
            # Create the folder for the testcase 
            testcasename = os.path.split(testcase)[LAST].split('.')[FIRST]
            testcasefolder = os.path.join(self.testsuitefolder, testcasename)
            message = "Creating testcase folder: %s" % testcasefolder
            self.emit(SIGNAL("self.debugMessage"  ),  message)            
            # TODO: Put this make folder in a try/except block
            os.mkdir(testcasefolder)
            message = "Created testcase folder: %s" % testcasefolder
            self.emit(SIGNAL("self.debugMessage"  ),  message)            

            # Execute the test case.
            message = "Executing: %s" % testcase
            self.emit(SIGNAL("self.consoleMessage"),  message)
            self.emit(SIGNAL("self.debugMessage"  ),  message)

            # *** ******************* ***
            # *** TEST CASE EXECUTION ***
            # *** ******************* ***
            c = am_Command.Command("%s %s " %(testcase, testcasefolder))
            c.run()



            testcaseResults = c.returnResults()
            message = "   Command:\n%s\n   Output:\n%s\n   Errors: \n%s\n   Return: %s\n" %(testcaseResults["command"]   ,
                                                                                            testcaseResults["output"]    ,
                                                                                            testcaseResults["error"]     ,
                                                                                            testcaseResults["returnCode"])           
            self.emit(SIGNAL("self.debugMessage"  ),  message)
               
            if testcaseResults['returnCode'] == 0: 
               message = "Testcase %s PASSED" %testcasename
            else:
               message = "Testcase %s FAILED" %testcasename
            self.emit(SIGNAL("self.consoleMessage"),  message)
            self.emit(SIGNAL("self.debugMessage"  ),  message)
            self.emit(SIGNAL("self.resultsMessage"),  message)      

            # Write the output and error files to the testcase folder
            # TODO: Put these file writes in try/except blocks            
            if len(testcaseResults['output']) > 0:
               message = "Writing output file to testcase folder %s" %testcasefolder
               self.emit(SIGNAL("self.debugMessage"  ),  message)               
               f = open(os.path.join(testcasefolder,"output.txt"), 'w')
               f.write(testcaseResults['output'])
               f.close()
            if len(testcaseResults['error']) > 0:
               message = "Writing error file to testcase folder %s" %testcasefolder
               self.emit(SIGNAL("self.debugMessage"  ),  message)
               f = open(os.path.join(testcasefolder, "errors.txt"), 'w')
               f.write(testcaseResults['error'])
               f.close()                  
            
            # Final Message for this testcase      
            message = "Completed  testcase %d of %d" %(testcaseCounter, numberOfTestcases)
            self.emit(SIGNAL("self.consoleMessage"),  message)
            self.emit(SIGNAL("self.debugMessage"  ),  message)


         # We are now out of the loop and done with all testcase executions.   
         message = "Testcase execution complete, see Results tab for details." 
         self.emit(SIGNAL("self.consoleMessage"),  message)
         self.emit(SIGNAL("self.debugMessage"  ),  message)
         
         # Report Footer
         message = "--- END OF REPORT ---"
         self.emit(SIGNAL("self.resultsMessage"),  message)            
         
         # Show the Results tab when the test suite is fnished.
         time.sleep(3)                 # Wait for the buffer. It may take a few 
         self.tabs.setCurrentIndex(2)  # secons to write the last message to the 
         #                             # tab's text area. 
         
         # Write the report to the "report.txt" file in the test suite results 
         # folder 
         # TODO: Put this file write in a try/except block.
         summaryReportFilename = os.path.join(self.testsuitefolder, "SummaryRepot.txt")
         f = open(summaryReportFilename, 'w')
         f.write(self.resultsArea.toPlainText())
         f.close()
         
         self.setState(7) # Finished test case executions 
      
      except Exception as e:
         print e
      
   # ---------------------------------------------------------------------------
   def runScript(self):
      """ Wrapper for the threaded execution. """
      
      # Make sure we have a results home foldder
      message = "Checking results home folder"
      self.updateDebug(message)
      if not os.path.exists(self.configs['resultshome']):
         message = "Creating Results home: %s" %self.configs['resultshome'] 
         self.updateDebug(message)
         try:
            os.mkdir(resultsHome)
            message = "Created Results home: %s" %self.configs['resultshome'] 
            self.updateDebug(message)
         except:
            message = "Unable to create the Results Home folder.\n%s" % self.configs['resultshome'] 
            self.updateDebug(message)
            QMessageBox.critical(self, "Script Error", message, QMessageBox.Ok) 
            self.setState(3)
            return 
      else:
         message = "Results home using: %s" %self.configs['resultshome'] 
         self.updateDebug(message)
      
      # Create the test suite folder using a timestamp.
      timestamp = time.strftime("%Y%m%d-%H%M%S", time.localtime())
      if os.path.exists(self.configs['resultshome']):
         try: 
            self.testsuitefolder = os.path.join( self.configs['resultshome'], timestamp)
            message = "Creating Test Suite Folder: %s" %self.testsuitefolder             
            self.updateDebug(message)
            os.mkdir(self.testsuitefolder)
            message = "Created Test Suite Folder: %s" %self.testsuitefolder             
            self.updateDebug(message)
         except:
            message = "Unable to create the Test Suite folder.\n%s" % self.testsuitefolder 
            self.updateDebug(message)
            QMessageBox.critical(self, "Script Error", message, QMessageBox.Ok) 
            self.setState(3)
            return 
            
      # Spawn the execution thread. Execution is threaded so that the console 
      # and debug tabs can be updated in real time.  
      start_new_thread(self.threadedExecution, (self,))   
      
   # --------------------------------------------------------------------------
   def stopScript(): 
      pass # TODO: Write this function
   # --------------------------------------------------------------------------
   def debugScript():
      pass # TODO: Write this function
   # --------------------------------------------------------------------------
   def showHelp(self): 
      Popen(["/usr/bin/gedit", "readme.txt"], shell=True)

   # --------------------------------------------------------------------------
   def textChanged(self): 
      # Set the file menu state to indicate unsaved changes to text.
      self.setState(2)      
   
   # ---------------------------------------------------------------------------
   def updateConsole(self, message):
      # Updates the console area
      consoleText = self.consoleArea.toPlainText()
      # consoleText += "\n"
      consoleText += "%s\n" %str(message)
      self.consoleArea.setText(consoleText)
      self.consoleArea.moveCursor(QTextCursor.End)

   # ---------------------------------------------------------------------------
   def updateDebug(self, message):
      # Updates the debug area 
      debugText = self.debugArea.toPlainText()
      # consoleText += "\n"
      debugText += "%s\n" %str(message)
      self.debugArea.setText(debugText)
      self.debugArea.moveCursor(QTextCursor.End)

   # ---------------------------------------------------------------------------
   def updateResults(self, message):
      # Updates the results area
      consoleText = self.resultsArea.toPlainText()
      # consoleText += "\n"
      consoleText += "%s\n" %str(message)
      self.resultsArea.setText(consoleText)
      self.resultsArea.moveCursor(QTextCursor.End)
     
   # ---------------------------------------------------------------------------               
   def showAbout(self): 
      # Shows the about box
      aboutTitle = "About %s" %ME
      aboutText  = "Test Case Runner\n%s, Version %s\nNETSCOUT, April 2016\n\nFor support contact:\[email protected]"%(ME, VERSION)
      QMessageBox.about(self, aboutTitle, aboutText)
      
   # --------------------------------------------------------------------------   
   def textChanged(self): 
      # Set the file menu state to indicate unsaved changes to text.
      self.setState(2)         
      
   # ---------------------------------------------------------------------------
   def setState(self, state):
      # ------------------------------------------------------------------------
      # ************************* STATE MACHINE MANAGEMENT *********************   
      # ------------------------------------------------------------------------
      # The state of the program determines what menubar items or toolbar 
      # buttons are active or even visible. Additionally, some method behavior 
      # may also vary depending on the state of the program. The states are 
      # listed below:
      # 
      #    State 0 : The program is started but no file or editor session is 
      #               opened.
      #    State 1 : A file or text editor session is opened but the text is 
      #              unchanged since last save.
      #    State 2 : A file or text editor session is opened and the text has 
      #              changed since the last save.
      #    State 3 : The text in the editor has errors and cannot be executed.
      #    State 4 : The text in the editor has no errors.
      #    State 5 : The text in the editor is being executed. 
      #    State 6 : The text in the editor has been stopped before execution has 
      #              completed.
      #    State 7 : The text in the editor has successfully completed.
      #    State 8 : The text in the editor has terminated with errors.
      self.state = state  
      if self.state == 0:
         self.mbExit.setEnabled(True)      
         self.mbNew.setEnabled(True) 
         self.mbOpen.setEnabled(True)
         self.mbClose.setEnabled(False)
         self.mbSave.setEnabled(False)
         self.mbSaveAs.setEnabled(False)
         self.mbRun.setEnabled(False)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(False)
         self.tbOpen.setEnabled(True)
         self.tbNew.setEnabled(True) 
         self.tbSave.setEnabled(False)
         self.tbExit.setEnabled(True)
         self.tbRun.setEnabled(False)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(False) 
         self.textArea.setVisible(False)
         self.tabs.setVisible(False)
      elif self.state == 1:
         self.mbExit.setEnabled(True)      
         self.mbNew.setEnabled(True) 
         self.mbOpen.setEnabled(True)
         self.mbClose.setEnabled(True)
         self.mbSave.setEnabled(False)
         self.mbSaveAs.setEnabled(False)
         self.mbRun.setEnabled(True)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbOpen.setEnabled(True)
         self.tbNew.setEnabled(True) 
         self.tbSave.setEnabled(False)
         self.tbExit.setEnabled(True)
         self.tbRun.setEnabled(True)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True) 
         self.textArea.setVisible(True)
         self.tabs.setVisible(True)
         # self.consoleArea.setVisible(True)
         # self.debugArea.setVisible(True)
      elif self.state == 2:
         self.mbExit.setEnabled(True)      
         self.mbNew.setEnabled(True) 
         self.mbOpen.setEnabled(True)
         self.mbClose.setEnabled(True)
         self.mbSave.setEnabled(True)
         self.mbSaveAs.setEnabled(True)
         self.mbRun.setEnabled(True)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbOpen.setEnabled(True)
         self.tbNew.setEnabled(True) 
         self.tbSave.setEnabled(True)
         self.tbExit.setEnabled(True)
         self.tbRun.setEnabled(True)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True) 
         self.textArea.setVisible(True)
         self.tabs.setVisible(True)
      elif self.state == 3:
         self.mbRun.setEnabled(False)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbRun.setEnabled(False)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True) 
      elif self.state == 4:
         pass
      elif self.state == 5:
         self.mbRun.setEnabled(False)
         self.mbStop.setEnabled(True)   
         self.mbDebug.setEnabled(False)
         self.tbRun.setEnabled(False)
         self.tbStop.setEnabled(True)
         self.tbDebug.setEnabled(False) 
      elif self.state == 6:
         self.mbRun.setEnabled(True)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbRun.setEnabled(True)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True)
      elif self.state == 7:
         self.mbRun.setEnabled(True)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbRun.setEnabled(True)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True)
      elif self.state == 8:
         self.mbRun.setEnabled(True)
         self.mbStop.setEnabled(False)   
         self.mbDebug.setEnabled(True)
         self.tbRun.setEnabled(True)
         self.tbStop.setEnabled(False)
         self.tbDebug.setEnabled(True)
      else:
         pass
      return  
Example #19
0
class NoteBook( QFrame ):

    # =======================================================================
    def __init__(self, parent=None):

        # -------------------------------------------------------------------
        QFrame.__init__(self, parent);

        # -------------------------------------------------------------------
        self.PARENT                                 = parent;
        self.DEBUG                                  = False;
        self.LOG_TAG                                = str(self.__class__.__name__).upper();

        self.setGeometry( 4, 34, 1012, 606 );
        self.setStyleSheet( "QFrame{ font: 12px 'monospace'; color: #fff; background-color: rbga(0,0,0, 190); border-style: solid; border-width: 5px; border-color: #FFF; }" );

        # -------------------------------------------------------------------
        self.NOTEBOOK_FILE                          = self.PARENT.STORAGE_ROOT+"notebook.file";
        # -------------------------------------------------------------------
        self.TEXT                                   = QTextEdit( "TEST: TEST", self );
        self.TEXT.setGeometry(5, 35, 980, 560);
        self.TEXT.setStyleSheet("QTextEdit{ font: 12px 'monospace'; color: #fff; margin: 5px; padding: 5px; border-style: solid; border-width: 1px; border-color: #FFF; }")
        self.TEXT.setReadOnly( False );
        self.TEXT.setAcceptRichText( False );
        self.TEXT.setUndoRedoEnabled( True );
        self.TEXT.LineWrapMode( self.TEXT.WidgetWidth );

        self.TEXT.textChanged.connect( self.TEXT_CHANGED );


        # -------------------------------------------------------------------
        self.hide();

        self.IS_OPEN                                = False;
        self.KEEP_OPEN                              = False;

        # -------------------------------------------------------------------
        self.UPDATE_TIMER                           = QTimer();
        self.UPDATE_TIMER.singleShot( 1000, self.UPDATE_FRAME );
        
        # -------------------------------------------------------------------
        self.PARENT.SPLASH.STATUS( self.LOG_TAG+": [INIT]" );
        # -------------------------------------------------------------------

    # =======================================================================
    def TEXT_CHANGED( self ):

        # -------------------------------------------------------------------
        pass;
        #self.TEXT.setText( str(self.TEXT.toPlainText() );
        #self.TEXT.setText( str(self.TEXT.text() ) );
        # -------------------------------------------------------------------

    # =======================================================================
    def CMD( self, _CMD ):

        # -------------------------------------------------------------------
        #__exec:notebook:notes:show"
        #__exec:notebook:notes:hide"
        #__exec:notebook:notes:keep_open:(0|1)

        # -------------------------------------------------------------------
        try:
    
            # -----------------------------------------------
            if _CMD[0] == "notes":

                if _CMD[1] == "show":
                    self.SHOW_NOTES( );

                elif _CMD[1] == "hide":
                    self.HIDE_NOTES( );

                elif _CMD[1] == "keep_open":

                    self.KEEP_OPEN = True if _CMD[2] == "1" else False;
                    self.LOCAL_INFO_LOG( "notebook:notes:keep_open:"+_CMD[2] );


                return;
            # -----------------------------------------------
            if _CMD[0] == "cmd":
                pass;
                    
            # -----------------------------------------------

        except Exception as _err:
            self.LOCAL_ERROR_LOG( str(_CMD)+" | "+str(_err) );
    
        # -------------------------------------------------------------------


    # =======================================================================
    def SHOW_NOTES( self ):

        # -------------------------------------------------------------------
        try:
            """
            out = "";
            for _key in self.LAST_PAGE_REQUEST_HEADERS:
                _l = "-----------------------------------------------------------------------\n";
                _l += '["'+_key+'"] => \n["'+self.LAST_PAGE_REQUEST_HEADERS[ _key ]+'"]'+"\n";
                print( "L: "+_l );
                out += _l;

            self.TEXT.setText( out );
            """
            self.show();
            self.IS_OPEN = True;
            self.TEXT.setFocus( True );

        except Exception as _err:
            self.LOCAL_ERROR_LOG( "'Can't show notes: "+str(_err) );


        # -------------------------------------------------------------------

    # =======================================================================
    def HIDE_NOTES( self ):

        # -------------------------------------------------------------------
        self.hide();

        self.IS_OPEN = False;
        self.TEXT.clearFocus();
        # -------------------------------------------------------------------

    # =======================================================================
    def UPDATE_FRAME(self):

        # -------------------------------------------------------------------
        return;
        # -------------------------------------------------------------------
        """
        try:
            _style = "";
            _conf  = [];

            with open( "./ALPHA_FRAME.conf" ) as FS:
                _conf = FS.readline();
                print(_conf );
                _conf = _conf.split("|");

                self.setGeometry( 
                    int(_conf[0]), 
                    int(_conf[1]), 
                    int(_conf[2]), 
                    int(_conf[3])
                );


                for _line in FS:
                    _style += _line;

            self.setStyleSheet( _style );

        except Exception as _err:
            print("ERROR: "+str(_err));
            
        self.UPDATE_TIMER.singleShot( 1000, self.UPDATE_FRAME );
        """
        # -------------------------------------------------------------------

    # =======================================================================
    def LOAD(self):
    
        # -------------------------------------------------------------------
        if self.DEBUG:
            pass;

        # -------------------------------------------------------------------

        try:

            # ---------------------------------------------------
            self.PARENT.SPLASH.STATUS( self.LOG_TAG+": [LOAD]" );
            self.PARENT.LOG_HANDLER.WRITE_LOG( "Doc-Browser: NOTEBOOK: LODE: ");

            self.TEXT.clear();

            with open( self.NOTEBOOK_FILE, "r") as FS:

                for line in FS:
                    self.TEXT.append(line.strip());
                    #self.TEXT.insertPlainText(line);
                    #self.TEXT.insertHtml(line);

            self.PARENT.LOG_HANDLER.WRITE_LOG( "Doc-Browser: NOTEBOOK: LODE: Done");
            # ---------------------------------------------------

        except Exception as _err:
            self.LOCAL_ERROR_LOG( "Can't load notes: "+str(_err) );
        # -------------------------------------------------------------------

    # =======================================================================
    def SAVE(self):

        # -------------------------------------------------------------------
        if self.DEBUG:
            pass;

        # -------------------------------------------------------------------
        try:

            # ---------------------------------------------------
            self.PARENT.LOG_HANDLER.WRITE_LOG( "Doc-Browser: NOTEBOOK: SAVE: ");

            DATA = str(self.TEXT.toPlainText()).split("\n");

            with open( self.NOTEBOOK_FILE, "w") as FS:

                for line in DATA:
                    FS.write( line+"\n" );

            self.PARENT.LOG_HANDLER.WRITE_LOG( "Doc-Browser: NOTEBOOK: SAVE: Done");
            # ---------------------------------------------------

        except Exception as _err:
            self.LOCAL_ERROR_LOG( "Can't save notes: "+str(_err) );

        # -------------------------------------------------------------------

    # =======================================================================
    def LOCAL_INFO_LOG( self, _msg, METHOD=None ):

        # -------------------------------------------------------------------
        if METHOD is None:
            self.PARENT.LOCAL_INFO_LOG( "['"+self.LOG_TAG+"']: ["+_msg+"]" );
        else:
            self.PARENT.LOCAL_INFO_LOG( "['"+self.LOG_TAG+"."+METHOD+"']: ["+_msg+"]" );
        # -------------------------------------------------------------------

    # =======================================================================
    def LOCAL_ERROR_LOG( self, _msg, METHOD=None ):

        # -------------------------------------------------------------------
        if self.DEBUG or self.PARENT.DEBUG_GLOBAL: self.PARENT.DEBUGGER.DEBUG();
        # -------------------------------------------------------------------
        if METHOD is None:
            self.PARENT.LOCAL_ERROR_LOG( "['"+self.LOG_TAG+"']: ["+_msg+"]" );
        else:
            self.PARENT.LOCAL_ERROR_LOG( "['"+self.LOG_TAG+"."+METHOD+"']: ["+_msg+"]" );
        # -------------------------------------------------------------------

    # =======================================================================
    def LOCAL_WARNING_LOG( self, _msg, METHOD=None ):

        # -------------------------------------------------------------------
        if METHOD is None:
            self.PARENT.LOCAL_WARNING_LOG( "['"+self.LOG_TAG+"']: ["+_msg+"]" );
        else:
            self.PARENT.LOCAL_WARNING_LOG( "['"+self.LOG_TAG+"."+METHOD+"']: ["+_msg+"]" );
Example #20
0
class HAConfigFrontend(FullFeaturedScrollArea):
    COMPONENT = 'ha'
    LABEL = tr('High Availability')
    REQUIREMENTS = ('ha',)
    ICON = ':/icons/picto_ha.png'

    if EDENWALL:
        LINK_STATE = {
            NOT_REGISTERED: tr('Not registered'),
            NOT_CONNECTED: tr('Not connected'),
            CONNECTED: tr('Connected'),
        }

        NODE_STATE = {
            NOT_REGISTERED: tr('Not registered'),
            ACTIVE: tr('Active'),
            INACTIVE: tr('Inactive'),
        }

        STATE_DESCRIPTIONS = {
            ENOHA: span(tr('High availability is not configured.')),
            PENDING_PRIMARY: span(tr('Primary; click "Join" to <br/>complete high availability configuration.')),
            PRIMARY: span(tr('Primary, in function.')),
            SECONDARY: span(tr('Secondary, in function.')),
            PENDING_SECONDARY: span(tr('Secondary; connect EAS to the primary server to <br/>complete high availability configuration.')),
        }

    def __init__(self, client, parent):
        self.auth_page = None
        self.group_page = None
        self.auth_configs = {}
        self.group_configs = {}
        self.mainwindow = parent

        self.node_status_label = QLabel()   # status of current node (active / inactive)
        self.link_status_label = QLabel() # status of dedicaced link
        self.interface_label = QLabel()
        self.activity_label = QLabel()
        self.last_error_text = QTextEdit()
        self.last_error_text.setReadOnly(True)
        self.last_error_text.setMaximumHeight(100)
        self.type_label = QLabel()
        self.join = None

        self.link_state = None
        self.ha_last_date = None

        self.version = self.mainwindow.init_call('ha', 'getComponentVersion')

        FullFeaturedScrollArea.__init__(self, client, parent)
        self.missing_upgrades = []

        # create timer only if HA activated
        if self.__ha_type() != ENOHA:
            self.timer = Timer(
                self.setViewData,
                REFRESH_INTERVAL_MILLISECONDS,
                self.mainwindow.keep_alive.thread,
                self
                )
        else:
            self.timer = None

        self.force_join = QAction(QIcon(":/icons/force_join"), tr("Force joining secondary"), self)
        self.connect(self.force_join, SIGNAL('triggered(bool)'), self.joinSecondary)
        self.force_takeover = QAction(QIcon(":/icons/ha_takeover"), tr("Force to become active"), self)
        self.connect(self.force_takeover, SIGNAL('triggered(bool)'), self.takeover)

        buttons = [self.force_join, self.force_takeover]
        self.contextual_toolbar = ToolBar(buttons, name=tr("High Availability"))

    @staticmethod
    def get_calls():
        """
        services called by initial multicall
        """
        return (('ha', 'getState'), ('ha', 'getFullState'),
            ('ha', 'getComponentVersion'))

    def __ha_type(self):
        config = QHAObject.getInstance().cfg
        if config is None:
            return ENOHA
        return config.ha_type

    def buildInterface(self):
        frame = QFrame()
        self.setWidget(frame)
        self.setWidgetResizable(True)
        layout = QGridLayout(frame)

        title = u'<h1>%s</h1>' % self.tr('High Availability Configuration')
        layout.addWidget(QLabel(title), 0, 0, 1, -1)

        configure = QPushButton(QIcon(":/icons/configurationha.png"), tr('Configure'))
        self.mainwindow.writeAccessNeeded(configure)
        layout.addWidget(configure, 1, 3)

        self.join = QPushButton(QIcon(":/icons/joinha.png"), tr('Join Secondary'))
        layout.addWidget(self.join, 2, 3)

        if "1.1" == self.version:
            layout.addWidget(QLabel(tr('Appliance status')), 3, 0)
            layout.addWidget(self.node_status_label, 3, 1)
            row = 4
        else:
            row = 3

        self.last_error_title = QLabel(tr('Last error'))
        self.missing_upgrade_text_label = QLabel()
        self.missing_upgrade_nums_label = QLabel()
        widgets = [
            (QLabel(tr('Link status')), self.link_status_label),
            (QLabel(tr('Type')),self.type_label),
            (QLabel(tr('Interface')),self.interface_label),
            (QLabel(tr('Last activity')), self.activity_label),
            (self.last_error_title, self.last_error_text),
            (self.missing_upgrade_text_label, self.missing_upgrade_nums_label),
        ]

        for index, (label, widget) in enumerate(widgets):
            layout.addWidget(label, row+index, 0)
            layout.addWidget(widget, row+index, 1)

        # syncUpgrades_button = QPushButton(tr('Synchronize upgrades'))
        # layout.addWidget(syncUpgrades_button, 7, 2)
        # self.connect(syncUpgrades_button, SIGNAL('clicked()'), self.syncUpgrades)

        layout.setColumnStretch(0,  1)
        layout.setColumnStretch(1,  5)
        layout.setColumnStretch(2, 10)
        layout.setColumnStretch(3,  1)
        layout.setRowStretch(row+6, row+7)
        self.connect(configure, SIGNAL("clicked()"), self.displayConfig)
        self.connect(self.join, SIGNAL("clicked()"), self.joinSecondary)

    def displayConfig(self):
        config = QHAObject.getInstance().hacfg
        if config.ha_type == PRIMARY:
            QMessageBox.warning(
                self,
                tr('High availability already configured'),
                tr('High availability status disallows editing the configuration'))
            return

        ha_wizard = ConfigWizard(self)
        ret = ha_wizard.exec_()
        if ret != QDialog.Accepted:
            return False

        qhaobject = QHAObject.getInstance()
        qhaobject.pre_modify()

        config = qhaobject.hacfg

        qnetobject = QNetObject.getInstance()
        qnetobject.pre_modify()
        net_cfg = qnetobject.netcfg

        old_type = config.ha_type
        new_config = ha_wizard.getData()
        config.ha_type = new_config.ha_type
        config.interface_id = new_config.interface_id
        config.interface_name = new_config.interface_name
        if config.ha_type in (PENDING_PRIMARY, PENDING_SECONDARY):
            iface = net_cfg.getIfaceByHardLabel(config.interface_id)
            configureHA(net_cfg, iface)
            network_modified = True
        elif config.ha_type != old_type:
            deconfigureHA(net_cfg)
            network_modified = True
            # XXX should not reconfigure now ?
        else:
            network_modified = False

        valid = qnetobject.post_modify()
        if not valid:
            qhaobject.revert()
        else:
            # FIXME: use post_modify() result?
            qhaobject.post_modify()
            self.setModified(True)
            if network_modified:
                network = self.mainwindow.getPage('network')
                network.setModified(True)
                dhcp = self.mainwindow.getPage('dhcp')
                dhcp.dhcp_widget.setModified(True)
                dhcp.dhcp_widget.fillView()

        self.setViewData()
        return True

    def hide_last_error(self):
        self.last_error_text.clear()
        self.last_error_text.hide()
        self.last_error_title.hide()

    def show_last_error(self, last_error):
        if last_error:
            self.last_error_text.setText(last_error)
            self.last_error_title.show()
            self.last_error_text.show()
        else:
            self.hide_last_error()

    def syncUpgrades(self):
        # First, update the list of missing upgrades:
        defer = self.setViewData()
        if defer:
            defer.addCallback(self._syncUpgrades)

    def _syncUpgrades(self):
        pass

    def fetchConfig(self):
        # we use QHAObject
        pass

    def __disable(self):
        self.close()
        raise NuConfModuleDisabled("Disabling high availability interface")

    def setViewData(self):
        config = QHAObject.getInstance().hacfg

        if "1.0" == self.version:
            raw_state = self.mainwindow.init_call('ha', 'getState')
            if raw_state is None:
                self.__disable()
                return
            self.link_state, self.ha_last_date, last_error = raw_state
            self.link_status_label.setText(self.LINK_STATE.get(self.link_state,
                tr('(unknown)')))
        else:
            raw_state = self.mainwindow.init_call('ha', 'getFullState')
            if raw_state is None:
                self.__disable()
                return
            node_state = raw_state['node_state']
            self.link_state = raw_state['link_state']
            self.ha_last_date = raw_state['seen_other']
            last_error = raw_state['last_error']

            self.link_status_label.setText(self.LINK_STATE.get(self.link_state,
                tr('(unknown)')))
            self.node_status_label.setText(self.NODE_STATE.get(node_state,
                tr('(unknown)')))

        # TEMP : use compatibility instead
        try:
            try:
                if raw_state.get('link_state', None) == CONNECTED:
                    self.join.setEnabled(False)
            except Exception:
                if isinstance(raw_state, list) and len(raw_state) > 0:
                    if raw_state[0] == CONNECTED:
                        self.join.setEnabled(False)
        except TypeError:
            pass

        ha_type = self.__ha_type()

        self.type_label.setText(
            HAConfigFrontend.STATE_DESCRIPTIONS[ha_type]
            )

        if ha_type != ENOHA:
            if self.ha_last_date not in (0, None):
                fmt = '%Y-%m-%d %H:%M:%S'
                seen = time.strftime(fmt, time.localtime(self.ha_last_date))
                self.activity_label.setText(unicode(seen))
            if config.interface_id is not None:
                qnetobject = QNetObject.getInstance()
                iface = qnetobject.netcfg.getIfaceByHardLabel(config.interface_id)
                self.interface_label.setText(iface.fullName())
            try:
                last_error = self.client.call('ha', 'getLastError')
                self.show_last_error(last_error)
            except Exception:
                self.hide_last_error()
        else:
            self.interface_label.clear()
            self.activity_label.clear()
            self.hide_last_error()
        if ha_type == PRIMARY:
            async = self.client.async()
            async.call('ha', 'getMissingUpgradeNums',
                       callback=self._get_missing_upgrade_nums,
                       errback=self.writeError)
        self.mainwindow.writeAccessNeeded(self.join)
        if self.join.isEnabled():
            self.join.setEnabled(PENDING_PRIMARY == ha_type)

    def _get_missing_upgrade_nums(self, missing_upgrade_nums):
        try:
            self.missing_upgrade_nums = missing_upgrade_nums
            if type(missing_upgrade_nums) != type([]):
                self.missing_upgrade_nums_label.setText(tr('N/A'))
            elif not missing_upgrade_nums:
                self.missing_upgrade_nums_label.setText(tr('None '))
            else:
                sample = sorted(missing_upgrade_nums)
                if len(sample) > MAX_MISSING_UPGRADE_NUMS:
                    sample = sample[:MAX_MISSING_UPGRADE_NUMS] + ['...']
                self.missing_upgrade_nums_label.setText(
                    ', '.join([unicode(num) for num in sample]))
            self.missing_upgrade_text_label.setText(
                tr('Missing upgrades on the secondary'))
        except Exception:
            pass

    def sendConfig(self, message):
        """
        Save HA config
        """
        serialized =  QHAObject.getInstance().hacfg.serialize()
        self.client.call('ha', 'configureHA', serialized, message)

    def joinSecondary(self):
        self.mainwindow.addToInfoArea(
            tr("Attempting to enslave the secondary, please wait...")
            )
        self.splash = SplashScreen()
        self.splash.setText(tr("Attempting to enslave the secondary..."))
        self.splash.show()
        async = self.client.async()
        async.call('ha', 'startHA',
            callback = self.successJoin,
            errback = self.errorJoin
            )

    def successJoin(self, ok):
        self.splash.hide()
        self.timer = Timer(
            self.setViewData,
            REFRESH_INTERVAL_MILLISECONDS,
            self.mainwindow.keep_alive.thread,
            self
            )
        self.join.setEnabled(False)
        self.mainwindow.addToInfoArea(tr("Joining secondary: success"), category=COLOR_SUCCESS)

    def errorJoin(self, error):
        self.splash.hide()
        self.mainwindow.addToInfoArea(tr('Joining secondary: fail'), category=COLOR_ERROR)
        warning = QMessageBox(self)
        warning.setWindowTitle(tr('Joining secondary: fail'))
        warning.setText(tr('An error was encountered while joining secondary.'))
        errmsg = exceptionAsUnicode(error)
        if "current state=ENOHA" in errmsg:
            errmsg = tr(
                "Can not join yet: the appliance is still not configured for "
                "high availability. Did you save and apply your changes?"
                )
        warning.setDetailedText(errmsg)
        warning.setIcon(QMessageBox.Warning)
        warning.exec_()

    def takeover(self):
        try:
            self.client.call('ha', 'takeover')
        except Exception, err:
            self.mainwindow.exception(err)
            return
        self.mainwindow.addToInfoArea(tr('Take over request sent.'), category=COLOR_SUCCESS)
Example #21
0
class AddWordWidget(QDialog):

    def __init__(self, parent=None):
        super(AddWordWidget, self).__init__(parent=parent)
        self.setWindowTitle('Add word')

        self.create_layout()
        self.create_connections()

    def create_layout(self):
        hbox = QHBoxLayout()

        vbox = QVBoxLayout()
        vbox.addWidget(QLabel("Dictionary"))
        vbox.addWidget(QLabel("Original"))
        vbox.addWidget(QLabel("Translation"))
        vbox.addWidget(QLabel("Phoneme"))
        vbox.addWidget(QLabel("Parts of Speech"))
        vbox.addWidget(QLabel("Synonyms"))
        vbox.addWidget(QLabel("Antonyms"))
        hbox.addLayout(vbox)

        vbox = QVBoxLayout()

        self.dictionaries = Dictionary.objects.all()
        self.dictionary = QComboBox()
        self.dictionary.addItems([d.name for d in self.dictionaries])
        vbox.addWidget(self.dictionary)

        self.original = QLineEdit()
        vbox.addWidget(self.original)

        self.translation = QLineEdit()
        vbox.addWidget(self.translation)

        self.phoneme = QLineEdit()
        vbox.addWidget(self.phoneme)

        self.pos = QComboBox()
        self.pos.addItems([p.strip() for p in
                           self.dictionaries[0].pos.split(',') if len(p) > 0])
        vbox.addWidget(self.pos)

        self.synonyms = QLineEdit()
        vbox.addWidget(self.synonyms)

        self.antonyms = QLineEdit()
        vbox.addWidget(self.antonyms)

        hbox.addLayout(vbox)

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)

        vbox.addWidget(QLabel("Description"))
        self.description = QTextEdit()
        vbox.addWidget(self.description)

        self.add_button = QPushButton("&Add")
        self.close_button = QPushButton("&Close")
        hbox = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(self.add_button)
        hbox.addWidget(self.close_button)
        vbox.addLayout(hbox)

        self.status = QLabel('Add a new word to a dictionary.')
        vbox.addWidget(self.status)

        self.setLayout(vbox)

    def create_connections(self):
        self.connect(self.dictionary, SIGNAL("currentIndexChanged(int)"),
                     self.change_pos)
        self.connect(self.close_button, SIGNAL("clicked()"), self.close)
        self.connect(self.add_button, SIGNAL("clicked()"), self.add_word)

    def change_pos(self, index):
        current_dict = self.dictionaries[index]
        self.pos.clear()
        self.pos.addItems([p.strip() for p in
                           current_dict.pos.split(',') if len(p) > 0])

    def get_texts(self):
        current_dict = self.dictionaries[self.dictionary.currentIndex()].abbrev
        original = unicode(self.original.text()).strip()
        translation = unicode(self.translation.text()).strip()
        phoneme = unicode(self.phoneme.text()).strip()
        pos = unicode(self.pos.currentText()).strip()
        synonyms = unicode(self.synonyms.text()).strip()
        antonyms = unicode(self.antonyms.text()).strip()
        description = unicode(self.description.toPlainText()).strip()

        if not all([original, translation, pos]):
            self.status.setText('There was an error inserting the word. Please'
                                ' try again.')
            QMessageBox.critical(self, "Error", "You must enter at least "
                                 "'Original', 'Translation' and 'Parts of "
                                 "Speech'.")
            return None

        return dict(dictionary=current_dict, original=original,
                    translation=translation, phoneme=phoneme, pos=pos,
                    synonyms=synonyms, antonyms=antonyms,
                    description=description)

    def clear_texts(self):
        self.translation.clear()
        self.phoneme.clear()
        self.synonyms.clear()
        self.antonyms.clear()
        self.description.clear()

        self.original.setFocus()

    def add_word(self):
        self.status.clear()

        texts = self.get_texts()
        if not texts:
            return

        word = Word(**texts)
        word.save()

        self.clear_texts()
        self.status.setText('Word %s has been added successfully.' %
                            word.original)
        self.words_widget.load_words()

    def save_word(self):
        self.status.clear()

        texts = self.get_texts()
        if not texts:
            return

        word = self.word
        word.dictionary = texts['dictionary']
        word.original = texts['original']
        word.translation = texts['translation']
        word.phoneme = texts['phoneme']
        word.pos = texts['pos']
        word.synonyms = texts['synonyms']
        word.antonyms = texts['antonyms']
        word.description = texts['description']
        word.save()

        self.status.setText('Word %s has been saved successfully' %
                            word.original)
        self.words_widget.load_words()

    def get_word(self):
        return self._word

    def set_word(self, word):
        self._word = word
        self.setWindowTitle("Edit %s" % word.original)
        self.add_button.setText("&Save")
        self.disconnect(self.add_button, SIGNAL("clicked()"), self.add_word)

        if word.exported:
            self.add_button.setEnabled(False)
            self.status.setText('This word has been exported already. '
                                'You cannot save the changes to it.')
        else:
            self.connect(self.add_button, SIGNAL("clicked()"), self.save_word)
            self.status.setText('Edit this word and save to your dictionary.')

        for i, d in enumerate(self.dictionaries):
            if d.abbrev == word.dictionary:
                self.dictionary.setCurrentIndex(i)
                break

        self.original.setText(word.original)
        self.translation.setText(word. translation)
        self.phoneme.setText(word.phoneme)
        self.synonyms.setText(word.synonyms)
        self.antonyms.setText(word.antonyms)
        self.description.setText(word.description)

        for i in range(self.pos.count()):
            if self.pos.itemText(i) == word.pos:
                self.pos.setCurrentIndex(i)
                break

    word = property(get_word, set_word)
class OnlineUpdateGUI(QWidget):
    CHECK_INTERVAL = 12 * 60 * 60 * 1000  # check twice a day

    checkForAppUpdate = pyqtSignal()
    checkForRepoUpdates = pyqtSignal()
    installUpdates = pyqtSignal()

    def __init__(self, installedVersion, parent):
        super(OnlineUpdateGUI, self).__init__(parent)

        self._canCheckForAppUpdate = False
        self._canCheckForRepoUpdate = False
        self._appUpdatesAvailable = False
        self._repoUpdatesAvailable = False

        layout = QVBoxLayout(self)
        layout.addWidget(self._createAppUpdateWidget(installedVersion))
        layout.addWidget(self._createRepoUpdateWidget())

        self._installUpdatesButton = QPushButton("Install Update(s) and Restart", self)
        self._installUpdatesButton.clicked.connect(self.installUpdates)
        self._installUpdatesButton.setEnabled(False)
        layout.addWidget(self._installUpdatesButton)
        self._spacing = QWidget(self)
        layout.addWidget(self._spacing, 1)

        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)

    def _createAppUpdateWidget(self, installedVersion):
        widget = QGroupBox("Application", self)

        layout = QVBoxLayout(widget)
        versionLabel = QLabel("Installed Version: " + installedVersion)
        layout.addWidget(versionLabel, 0)

        self._appStatusLabel = QLabel(widget)
        self._appStatusLabel.setWordWrap(True)
        layout.addWidget(self._appStatusLabel, 0)

        self._progressBar = QProgressBar(widget)
        self._progressBar.setVisible(False)
        layout.addWidget(self._progressBar, 0)

        self._appCheckButton = QPushButton("Check for Update", widget)
        self._appCheckButton.clicked.connect(self.checkForAppUpdate)

        layout.addWidget(self._appCheckButton, 0)

        self._appChangeLog = QTextEdit(self)
        self._appChangeLog.setReadOnly(True)
        self._appChangeLog.setVisible(False)
        layout.addWidget(self._appChangeLog, 1)

        return widget

    def _createRepoUpdateWidget(self):
        widget = QGroupBox("Plugin Repositories", self)
        layout = QVBoxLayout(widget)

        self._repoStatusLabel = QLabel(widget)
        layout.addWidget(self._repoStatusLabel)

        self._repoCheckButton = QPushButton("Check for Updates", widget)
        self._repoCheckButton.clicked.connect(self.checkForRepoUpdates)
        layout.addWidget(self._repoCheckButton)

        return widget

    def setChangelogVisible(self, v):
        self._appChangeLog.setVisible(v)
        self._spacing.setVisible(not v)

    def setProgress(self, prog):
        self._progressBar.setValue(prog)

    def setProgressIndeterminate(self, indeterminate):
        self._progressBar.setMaximum(0 if indeterminate else 100)

    def setCheckAppUpdateButtonText(self, text=None):
        if not text:
            text = "Check for Update"
        self._appCheckButton.setText(text)

    def setInteractive(self, interactive):
        if interactive:
            self._appCheckButton.setEnabled(self._canCheckForAppUpdate)
            self._repoCheckButton.setEnabled(self._canCheckForRepoUpdate)
            self._installUpdatesButton.setEnabled(self._appUpdatesAvailable or self._repoUpdatesAvailable)
        else:
            self._appCheckButton.setEnabled(False)
            self._repoCheckButton.setEnabled(False)
            self._installUpdatesButton.setEnabled(False)

    def setCanCheckForAppUpdate(self, can):
        self._canCheckForAppUpdate = can
        self._appCheckButton.setEnabled(can)

    def setCanCheckForRepoUpdate(self, can):
        self._canCheckForRepoUpdate = can
        self._repoCheckButton.setEnabled(can)

    def appInstallReady(self):
        self._appUpdatesAvailable = True
        self._installUpdatesButton.setEnabled(True)

    def setRepoUpdatesAvailable(self, avail):
        self._repoUpdatesAvailable = True
        self._installUpdatesButton.setEnabled(avail or self._appUpdatesAvailable)

    def setRepoStatus(self, status):
        self._repoStatusLabel.setText(status)

    def setAppStatus(self, status, progress=False):
        self._progressBar.setVisible(progress)
        self._appStatusLabel.setText(status)

    def setAppStatusToolTip(self, text):
        self._appStatusLabel.setToolTip(text)

    def setAppChangeLog(self, log):
        self._appChangeLog.clear()
        document = self._appChangeLog.document()
        document.setIndentWidth(20)
        cursor = QTextCursor(document)

        cursor.insertText("Changes:\n")

        listFormat = QTextListFormat()
        listFormat.setStyle(QTextListFormat.ListDisc)
        listFormat2 = QTextListFormat()
        listFormat2.setStyle(QTextListFormat.ListDisc)
        listFormat2.setIndent(2)

        for line in log:
            if line.startswith("*"):
                cursor.insertList(listFormat2)
                line = line[1:]
            else:
                cursor.insertList(listFormat)
            cursor.insertText(line)

        self.setChangelogVisible(True)
Example #23
0
class DHttpReplay(QtHelper.EnhancedQDialog, Logger.ClassLogger):
    """
    Http replay dialog
    """
    def __init__(self, parent=None, offlineMode=False):
        """
        Constructor

        @param parent: 
        @type parent:
        """
        super(DHttpReplay, self).__init__(parent)
        self.offlineMode = offlineMode
        self.defaultIp = "127.0.0.1"
        self.defaultPort = "80"
        self.newTest = ''
        self.newTestExec = ''
        self.newInputs = []
        self.requests = []
        self.responses = []
        self.defaultTemplates = DefaultTemplates.Templates()
        self.testType = None

        self.createDialog()
        self.createConnections()
        self.createActions()
        self.createToolbar()

    def createActions(self):
        """
        Create qt actions
        """
        self.openAction = QtHelper.createAction(self,
                                                "&Open",
                                                self.importTrace,
                                                icon=QIcon(":/folder_add.png"),
                                                tip='Open network trace.')
        self.exportTUAction = QtHelper.createAction(
            self,
            "&Test Unit",
            self.exportToTU,
            icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE),
            tip='Export to Test Unit')
        self.exportTSAction = QtHelper.createAction(
            self,
            "&Test Suite",
            self.exportToTS,
            icon=QIcon(":/%s.png" % WWorkspace.TestSuite.TYPE),
            tip='Export to Test Suite')
        self.cancelAction = QtHelper.createAction(self,
                                                  "&Cancel",
                                                  self.reject,
                                                  tip='Cancel')

        menu = QMenu(self)
        menu.addAction(self.exportTUAction)
        menu.addAction(self.exportTSAction)

        self.exportToAction = QtHelper.createAction(
            self,
            "&Export to",
            self.exportToTU,
            icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE),
            tip='Export to tests')
        self.exportToAction.setMenu(menu)
        self.exportToAction.setEnabled(False)

    def createDialog(self):
        """
        Create dialog
        """

        self.dockToolbar = QToolBar(self)
        self.dockToolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        self.setWindowTitle(WINDOW_TITLE)
        self.resize(500, 400)

        self.ipEdit = QLineEdit(self.defaultIp)
        ipRegExpVal = QRegExpValidator(self)
        ipRegExp = QRegExp("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
        ipRegExpVal.setRegExp(ipRegExp)
        self.ipEdit.setValidator(ipRegExpVal)

        self.portEdit = QLineEdit(self.defaultPort)
        self.portEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        validatorPort = QIntValidator(self)
        self.portEdit.setValidator(validatorPort)

        self.progressBar = QProgressBar(self)
        self.progressBar.setMaximum(100)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setAlignment(Qt.AlignCenter)
        self.progressBar.setObjectName("progressBar")

        self.guiSikuliGroupBox = QGroupBox("")
        self.guiSikuliGroupBox.setFlat(True)
        self.automaticAdp = QRadioButton("Automatic")
        self.automaticAdp.setChecked(True)
        self.defaultAdp = QRadioButton("Default")
        self.genericAdp = QRadioButton("Generic")
        vbox = QHBoxLayout()
        vbox.addWidget(self.automaticAdp)
        vbox.addWidget(self.defaultAdp)
        vbox.addWidget(self.genericAdp)
        vbox.addStretch(1)
        self.guiSikuliGroupBox.setLayout(vbox)

        layout = QVBoxLayout()
        layout.addWidget(self.dockToolbar)
        layout.addSpacing(12)
        paramLayout = QGridLayout()
        paramLayout.addWidget(QLabel("Destination IP:"), 0, 0, Qt.AlignRight)
        paramLayout.addWidget(self.ipEdit, 0, 1)
        paramLayout.addWidget(QLabel("Destination Port:"), 1, 0, Qt.AlignRight)
        paramLayout.addWidget(self.portEdit, 1, 1)
        paramLayout.addWidget(QLabel(self.tr("Gui adapter selector:")), 2, 0,
                              Qt.AlignRight)
        paramLayout.addWidget(self.guiSikuliGroupBox, 2, 1)
        layout.addLayout(paramLayout)

        self.logsEdit = QTextEdit()
        self.logsEdit.setReadOnly(True)
        self.logsEdit.setTextInteractionFlags(Qt.NoTextInteraction)

        layout.addSpacing(12)
        layout.addWidget(self.logsEdit)
        layout.addSpacing(12)
        layout.addWidget(self.progressBar)

        self.setLayout(layout)

    def createToolbar(self):
        """
        Create toolbar
        """
        self.dockToolbar.setObjectName("File toolbar")
        self.dockToolbar.addAction(self.openAction)
        self.dockToolbar.addSeparator()
        self.dockToolbar.addAction(self.exportToAction)
        self.dockToolbar.addSeparator()
        self.dockToolbar.setIconSize(QSize(16, 16))

    def createConnections(self):
        """
        Create qt connections
        """
        pass

    def autoScrollOnTextEdit(self):
        """
        Automatic scroll on text edit
        """
        cursor = self.logsEdit.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.logsEdit.setTextCursor(cursor)

    def strip_html(self, txt):
        """
        Strip html
        """
        if "<" in txt:
            txt = txt.replace('<', '&lt;')
        if ">" in txt:
            txt = txt.replace('>', '&gt;')
        return txt

    def addLogSuccess(self, txt):
        """
        Add log success in the text edit
        """
        self.logsEdit.insertHtml(
            "<span style='color:darkgreen'>%s</span><br />" %
            unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLogWarning(self, txt):
        """
        Add log warning in the text edit
        """
        self.logsEdit.insertHtml(
            "<span style='color:darkorange'>%s</span><br />" %
            unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLogError(self, txt):
        """
        Add log error in the text edit
        """
        self.logsEdit.insertHtml("<span style='color:red'>%s</span><br />" %
                                 unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def addLog(self, txt):
        """
        Append log to the logsEdit widget
        """
        self.logsEdit.insertHtml("%s<br />" % unicode(self.strip_html(txt)))
        self.autoScrollOnTextEdit()

    def importTrace(self):
        """
        Import network trace
        """
        self.logsEdit.clear()
        self.testType = None

        if not self.offlineMode:
            if not RCI.instance().isAuthenticated():
                self.addLogWarning(
                    txt="<< Connect to the test center in first!")
                QMessageBox.warning(self, "Import",
                                    "Connect to the test center in first!")
                return

        self.exportToAction.setEnabled(False)
        self.newTest = ''
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)

        if sys.version_info > (3, ):
            fileName = QFileDialog.getOpenFileName(
                self, self.tr("Open File"), "",
                "Network dump (*.cap;*.pcap;*.pcapng)")
        else:
            fileName = QFileDialog.getOpenFileName(self, self.tr("Open File"),
                                                   "", "Network dump (*.cap)")
        # new in v18 to support qt5
        if QtHelper.IS_QT5:
            _fileName, _type = fileName
        else:
            _fileName = fileName
        # end of new

        if not _fileName:
            return

        if sys.version_info < (3, ):
            extension = str(_fileName).rsplit(".", 1)[1]
            if not (extension == "cap"):
                self.addLogError(txt="<< File not supported %s" % _fileName)
                QMessageBox.critical(self, "Open", "File not supported")
                return

        _fileName = str(_fileName)
        capName = _fileName.rsplit("/", 1)[1]

        self.addLogSuccess(txt=">> Reading the file %s" % _fileName)
        if sys.version_info > (3, ):
            self.readFileV2(fileName=_fileName)
        else:
            self.readFile(fileName=_fileName)

    def exportToTS(self):
        """
        Export to test suite
        """
        self.testType = TS
        self.exportToTest(TS=True, TU=False)

    def exportToTU(self):
        """
        Export to test unit
        """
        self.testType = TU
        self.exportToTest(TS=False, TU=True)

    def searchHTTP(self):
        """
        Search HTTP module in assistant
        """
        # modules accessor
        ret = "SutAdapters"
        if self.automaticAdp.isChecked():
            isGeneric = WWorkspace.Helper.instance().isGuiGeneric(name="GUI")
            if isGeneric:
                ret = "SutAdapters.Generic"
        elif self.defaultAdp.isChecked():
            return ret
        elif self.genericAdp.isChecked():
            ret = "SutAdapters.Generic"
        else:
            pass
        return ret

    def exportToTest(self, TS=True, TU=False):
        """
        Export to test
        """
        if not RCI.instance().isAuthenticated():
            self.addLogWarning(txt="<< Connect to the test center in first!")
            QMessageBox.warning(self, "Import",
                                "Connect to the test center in first!")
            return

        if TS:
            self.newTest = self.defaultTemplates.getTestDefinitionAuto()
            self.newTestExec = self.defaultTemplates.getTestExecutionAuto()
        if TU:
            self.newTest = self.defaultTemplates.getTestUnitDefinitionAuto()

        destIp = str(self.ipEdit.text())
        destPort = str(self.portEdit.text())

        self.newInputs = []
        self.newInputs.append({
            'type': 'self-ip',
            'name': 'BIND_IP',
            'description': '',
            'value': '0.0.0.0',
            'color': ''
        })
        self.newInputs.append({
            'type': 'int',
            'name': 'BIND_PORT',
            'description': '',
            'value': '0',
            'color': ''
        })
        self.newInputs.append({
            'type': 'str',
            'name': 'DEST_IP',
            'description': '',
            'value': '%s' % destIp,
            'color': ''
        })
        self.newInputs.append({
            'type': 'int',
            'name': 'DEST_PORT',
            'description': '',
            'value': '%s' % destPort,
            'color': ''
        })
        self.newInputs.append({
            'type': 'bool',
            'name': 'DEBUG',
            'description': '',
            'value': 'False',
            'color': ''
        })
        self.newInputs.append({
            'type': 'float',
            'name': 'TIMEOUT',
            'description': '',
            'value': '5.0',
            'color': ''
        })

        adps = """self.ADP_HTTP = %s.HTTP.Client(parent=self, bindIp=input('BIND_IP'), bindPort=input('BIND_PORT'), destinationIp=input('DEST_IP'), destinationPort=input('DEST_PORT'), debug=input('DEBUG'))""" % self.searchHTTP(
        )

        # prepare steps
        steps = []
        j = 0
        for i in xrange(len(self.requests)):
            j = i + 1
            if sys.version_info > (3, ):  # python3 support
                (source, dest, source_port, dest_port, buf_req,
                 reqDecoded) = self.requests[i]
                http_method = str(reqDecoded['method'], 'utf8')
                http_status = 'no'
                http_reason = ''
            else:
                http_method = self.requests[i]['tcp-object'].method
                http_status = 'no'
                http_reason = ''
            try:
                if sys.version_info > (3, ):  # python3 support
                    (sourceRsp, destRsp, sourcePortRsp, destPortRsp, bufReqRsp,
                     reqDecodedRsp) = self.responses[i]
                    http_status = str(reqDecodedRsp['code'])
                    http_reason = str(reqDecodedRsp['phrase'], 'utf8')
                else:
                    http_status = self.responses[i]['tcp-object'].status
                    http_reason = self.responses[i]['tcp-object'].reason
            except Exception as e:
                print(e)
            steps.append(
                'self.step%s = self.addStep(expected="%s %s response", description="send %s request", summary="send %s request")'
                % (j, http_status, http_reason, http_method, http_method))

        tests = []
        for i in xrange(len(self.requests)):
            j = i + 1
            if sys.version_info > (3, ):  # python3 support
                (source, dest, source_port, dest_port, buf_req,
                 reqDecoded) = self.requests[i]
            tests.append("# request %s" % j)
            tests.append('self.step%s.start()' % j)

            if sys.version_info > (3, ):  # python3 support
                lines_req = buf_req.splitlines()
            else:
                lines_req = self.requests[i]['tcp-data'].splitlines()

            if sys.version_info > (3, ):  # python3 support
                tests.append('rawHttp = [%s]' %
                             lines_req[0].replace(b'"', b'\\"'))
            else:
                tests.append('rawHttp = ["%s"]' %
                             lines_req[0].replace(b'"', b'\\"'))
            for lreq in lines_req[1:]:
                if sys.version_info > (3, ):  # python3 support
                    tests.append('rawHttp.append(%s)' %
                                 lreq.replace(b'"', b'\\"'))
                else:
                    tests.append('rawHttp.append("%s")' %
                                 lreq.replace(b'"', b'\\"'))

            tests.append('')
            tests.append(
                'req_tpl = self.ADP_HTTP.constructTemplateRequest(rawHttp=rawHttp)'
            )
            tests.append('req = self.ADP_HTTP.sendRequest(tpl=req_tpl)')

            try:
                tests.append('')
                if sys.version_info > (3, ):  # python3 support
                    (sourceRsp, destRsp, sourcePortRsp, destPortRsp, bufReqRsp,
                     reqDecodedRsp) = self.responses[i]
                    lines_res = bufReqRsp.splitlines()
                else:
                    lines_res = self.responses[i]['tcp-data'].splitlines()
                if sys.version_info > (3, ):  # python3 support
                    tests.append('rawHttpRsp = [%s]' %
                                 lines_res[0].replace(b"'", b"\\'"))
                else:
                    tests.append('rawHttpRsp = ["%s"]' %
                                 lines_res[0].replace(b'"', b'\\"'))
                for lres in lines_res[1:]:
                    if sys.version_info > (3, ):  # python3 support
                        tests.append('rawHttpRsp.append(%s)' %
                                     lres.replace(b"'", b"\\'"))
                    else:
                        tests.append('rawHttpRsp.append("%s")' %
                                     lres.replace(b'"', b'\\"'))
            except Exception as e:
                self.error("unable to append response: %s" % e)
            tests.append(
                'rsp_tpl = self.ADP_HTTP.constructTemplateResponse(rawHttp=rawHttpRsp)'
            )
            tests.append(
                "rsp = self.ADP_HTTP.hasReceivedResponse(expected=rsp_tpl, timeout=input('TIMEOUT'))"
            )
            tests.append('if rsp is None:')
            tests.append(
                '\tself.step%s.setFailed(actual="incorrect response")' % j)
            tests.append('else:')
            tests.append('\tself.step%s.setPassed(actual="ok")' % j)
            tests.append('')
        if TS:
            init = """self.ADP_HTTP.connect()
		connected = self.ADP_HTTP.isConnected( timeout=input('TIMEOUT') )
		if not connected:
			self.abort( 'unable to connect to the tcp port %s'  )
""" % str(self.portEdit.text())

        if TU:
            init = """self.ADP_HTTP.connect()
	connected = self.ADP_HTTP.isConnected( timeout=input('TIMEOUT') )
	if not connected:
		self.abort( 'unable to connect to the tcp port %s'  )
""" % str(self.portEdit.text())

        if TS:
            cleanup = """self.ADP_HTTP.disconnect()
		disconnected = self.ADP_HTTP.isDisconnected( timeout=input('TIMEOUT') )
		if not disconnected:
			self.error( 'unable to disconnect from the tcp port %s' )
""" % str(self.portEdit.text())

        if TU:
            cleanup = """self.ADP_HTTP.disconnect()
	disconnected = self.ADP_HTTP.isDisconnected( timeout=input('TIMEOUT') )
	if not disconnected:
		self.error( 'unable to disconnect from the tcp port %s' )
""" % str(self.portEdit.text())

        self.newTest = self.newTest.replace(
            "<<PURPOSE>>", 'self.setPurpose(purpose="Replay HTTP")')
        self.newTest = self.newTest.replace("<<ADPS>>", adps)
        if TS:
            self.newTest = self.newTest.replace("<<STEPS>>",
                                                '\n\t\t'.join(steps))
        if TU:
            self.newTest = self.newTest.replace("<<STEPS>>",
                                                '\n\t'.join(steps))
        self.newTest = self.newTest.replace("<<INIT>>", init)
        self.newTest = self.newTest.replace("<<CLEANUP>>", cleanup)
        if TS:
            self.newTest = self.newTest.replace("<<TESTS>>",
                                                '\n\t\t'.join(tests))
        if TU:
            self.newTest = self.newTest.replace("<<TESTS>>",
                                                '\n\t'.join(tests))

        self.accept()

    def decodeHttpRequest(self, data):
        """
        Decode http request
        Content chunked not yet implemented
        """
        http = {"type": "request"}
        lines = data.splitlines()
        try:
            request_line = lines[0]
        except Exception:
            self.error("unable to decode http request: %s" % lines)
            return None

        try:
            http["method"] = request_line.split(b" ", 2)[0]
            http["uri"] = request_line.split(b" ", 2)[1]
            http["version"] = request_line.split(b" ", )[2]
        except Exception:
            self.error(
                "unable to decode status code in the http response: %s" %
                request_line)
            return None

        http["body"] = data.split(b"\r\n\r\n")[1]

        headers = []
        contentLenght = 0
        contentChunked = False
        for hdr in data.split(b"\r\n\r\n")[0].splitlines()[1:]:
            if len(hdr):
                k, v = hdr.split(b":", 1)
                if k.lower() == b"content-length":
                    contentLenght = int(v)
                if k.lower() == b"transfer-encoding":
                    if v.lowert() == b"chunked":
                        contentChunked = True

                headers.append(hdr)

        http["headers"] = headers

        if len(http["body"]) != contentLenght:
            return None  # need more data
        return http

    def decodeHttpResponse(self, data):
        """
        Decode http response without body
        """
        http = {"type": "response"}
        lines = data.splitlines()
        try:
            status_line = lines[0]
        except Exception:
            self.error("unable to decode http response: %s" % lines)
            return None

        try:
            http["code"] = int(status_line.split(b" ")[1])
            http["phrase"] = status_line.split(b" ", 2)[2]
        except Exception:
            self.error(
                "unable to decode status code in the http response: %s" %
                status_line)
            return None

        http["headers"] = lines[1:]
        return http

    def readFileV2(self, fileName):
        """
        Read pcap file 
        Support pcap-ng too
        """
        fd = open(fileName, 'rb')
        fileFormat, fileHead = PcapParse.extractFormat(fd)
        if fileFormat == PcapParse.FileFormat.PCAP:
            self.trace("pcap file detected")
            pcapFile = PcapReader.PcapFile(fd, fileHead).read_packet
            self.readFilePacket(pcapFile=pcapFile)
        elif fileFormat == PcapParse.FileFormat.PCAP_NG:
            self.trace("pcap-png file detected")
            pcapFile = PcapngReader.PcapngFile(fd, fileHead).read_packet
            self.readFilePacket(pcapFile=pcapFile)
        else:
            self.addLogError(txt="<< Error to open the network trace")
            self.error('unable to open the network trace: file format = %s' %
                       fileFormat)
            QMessageBox.critical(self, "Import", "File not supported")

    def __readRequest(self, buffer, data, request, output):
        """
        Read request
        """
        buffer += data
        if b'\r\n\r\n' in data:
            reqDecoded = self.decodeHttpRequest(data=buffer)
            if reqDecoded is not None:
                output.append(request + (reqDecoded, ))
                buffer = b''
            else:
                print("need more data: decode request failed")
        else:
            print("need more data, no body separator detected on request")

    def readFilePacket(self, pcapFile):
        """
        Read file packet by packet
        """
        ip_expected = str(self.ipEdit.text())
        port_expected = int(self.portEdit.text())

        # read packet)
        packets = pcapFile()
        ethernetPackets = list(packets)
        self.addLogSuccess(txt="<< Number of packets detected: %s " %
                           len(ethernetPackets))

        # extract tcp packet according to the expected ip and port
        tcpPacketsSent = []
        tcpPacketsRecv = []
        i = 1
        self.progressBar.setMaximum(len(ethernetPackets))
        self.progressBar.setValue(0)
        for pkt in ethernetPackets:
            self.progressBar.setValue(i)
            i += 1
            pktDecoded = PcapParse.decodePacket(pkt, getTcp=True, getUdp=False)
            if pktDecoded is not None:
                (source, dest, source_port, dest_port, data) = pktDecoded
                # skip when no data exists
                if dest == ip_expected and int(dest_port) == int(
                        port_expected) and len(data) > 0:
                    tcpPacketsSent.append(pktDecoded)
                if source == ip_expected and int(source_port) == int(
                        port_expected) and len(data) > 0:
                    tcpPacketsRecv.append(pktDecoded)
        self.addLogSuccess(txt="<< Number of TCP packets sent: %s " %
                           len(tcpPacketsSent))
        self.addLogSuccess(txt="<< Number of TCP packets received: %s " %
                           len(tcpPacketsRecv))

        # decode https requests
        self.requests = []
        buf_req = b''
        i = 1
        self.progressBar.setMaximum(len(tcpPacketsSent))
        self.progressBar.setValue(0)
        # decode the complete packet
        for req in tcpPacketsSent:
            self.progressBar.setValue(i)
            i += 1
            (source, dest, source_port, dest_port, data) = req
            if buf_req:
                buf_req += data
                if b'\r\n\r\n' in data:
                    reqDecoded = self.decodeHttpRequest(data=buf_req)
                    if reqDecoded is not None:
                        self.requests.append((source, dest, source_port,
                                              dest_port, buf_req, reqDecoded))
                        buf_req = b''
            else:
                if isRequest(data):
                    buf_req += data
                    if b'\r\n\r\n' in data:
                        reqDecoded = self.decodeHttpRequest(data=buf_req)
                        if reqDecoded is not None:
                            self.requests.append(
                                (source, dest, source_port, dest_port, buf_req,
                                 reqDecoded))
                            buf_req = b''

        self.addLogSuccess(txt="<< Number of HTTP requests extracted: %s " %
                           len(self.requests))

        # decode https response
        self.responses = []
        buf_rsp = b''
        i = 1
        self.progressBar.setMaximum(len(tcpPacketsRecv))
        self.progressBar.setValue(0)
        # decode just headers for response
        for req in tcpPacketsRecv:
            self.progressBar.setValue(i)
            i += 1
            (source, dest, source_port, dest_port, data) = req
            if buf_rsp:
                buf_rsp += data
                # try to decode response without body
                if b'\r\n\r\n' in data:
                    rspDecoded = self.decodeHttpResponse(data=buf_rsp)
                    if rspDecoded is not None:
                        self.responses.append((source, dest, source_port,
                                               dest_port, buf_rsp, rspDecoded))
                        buf_rsp = b''
            else:
                # is http response ?
                if data.startswith(b'HTTP/'):
                    buf_rsp += data
                    if b'\r\n\r\n' in data:
                        rspDecoded = self.decodeHttpResponse(data=buf_rsp)
                        if rspDecoded is not None:
                            self.responses.append(
                                (source, dest, source_port, dest_port, buf_rsp,
                                 rspDecoded))
                            buf_rsp = b''
        self.addLogSuccess(txt="<< Number of HTTP responses extracted: %s " %
                           len(self.responses))

        if self.requests:
            self.addLogSuccess("<< Read the file finished with success!")
            self.addLogWarning(
                "<< Click on the export button to generate the test!")
            self.exportToAction.setEnabled(True)
        else:
            self.addLogWarning("<< No http extracted!")

    def readFile(self, fileName):
        """
        Read the file passed as argument
        Old function with dtpkt and python2.7
        """
        self.requests = []
        self.responses = []

        ip_expected = socket.inet_aton(str(self.ipEdit.text()))
        port_expected = str(self.portEdit.text())

        try:
            f = open(fileName, 'rb')
            pcap = dpkt.pcap.Reader(f)
            tot_pkts = len(list(pcap))
        except Exception as e:
            self.addLogError(txt="<< Error to open the network trace")
            self.error('unable to open the network trace: %s' % str(e))
            QMessageBox.critical(self, "Import", "File not supported")
            return
        else:
            self.addLogSuccess(txt="<< Total packets detected: %s " % tot_pkts)
            self.progressBar.setMaximum(tot_pkts)

            # decode http request
            i = 1
            buf_req = ''
            for ts, buf in pcap:
                self.progressBar.setValue(i)
                i += 1

                # read ethernet layer
                eth = dpkt.ethernet.Ethernet(buf)
                if eth.type == dpkt.ethernet.ETH_TYPE_IP:
                    # continue with ip decoding layer
                    ip = eth.data
                    if ip.dst == ip_expected:
                        ip_layer = (ip.src, ip.dst)
                        if ip.p == dpkt.ip.IP_PROTO_TCP:
                            tcp = ip.data
                            if tcp.dport == int(port_expected) and len(
                                    tcp.data) > 0:
                                tcp_layer = (tcp.sport, tcp.dport)
                                buf_req += tcp.data
                                try:
                                    http_req = dpkt.http.Request(buf_req)
                                except dpkt.dpkt.NeedData as e:
                                    pass
                                except dpkt.UnpackError as e:
                                    pass
                                else:
                                    self.requests.append({
                                        'ip-src': ip.src,
                                        'ip-dst': ip.dst,
                                        'port-src': tcp.sport,
                                        'port-dst': tcp.dport,
                                        'tcp-data': buf_req,
                                        'tcp-object': http_req
                                    })
                                    self.addLogWarning(
                                        txt="<< %s http request(s) extracted" %
                                        len(self.requests))
                                    buf_req = ''

            # decode http responses
            i = 1
            self.progressBar.setValue(0)
            for ts, buf in pcap:
                self.progressBar.setValue(i)
                i += 1

                # read ethernet layer
                eth = dpkt.ethernet.Ethernet(buf)
                if eth.type == dpkt.ethernet.ETH_TYPE_IP:
                    # continue with ip decoding layer
                    ip = eth.data
                    if ip.src == ip_expected:
                        ip_layer = (ip.src, ip.dst)
                        if ip.p == dpkt.ip.IP_PROTO_TCP:
                            tcp = ip.data
                            if tcp.sport == int(port_expected) and len(
                                    tcp.data) > 0:
                                tcp_layer = (tcp.sport, tcp.dport)
                                if (tcp.data).startswith('HTTP/'):
                                    try:
                                        new_res = "%s\r\n\r\n" % (
                                            tcp.data).splitlines()[0]
                                        http_res = dpkt.http.Response(new_res)
                                    except dpkt.dpkt.NeedData as e:
                                        pass
                                    except dpkt.UnpackError as e:
                                        pass
                                    else:
                                        self.responses.append({
                                            'ip-src':
                                            ip.src,
                                            'ip-dst':
                                            ip.dst,
                                            'port-src':
                                            tcp.sport,
                                            'port-dst':
                                            tcp.dport,
                                            'tcp-data':
                                            new_res,
                                            'tcp-object':
                                            http_res
                                        })
                                        self.addLogWarning(
                                            txt=
                                            "<< %s http response(s) extracted"
                                            % len(self.responses))
            if self.requests:
                self.addLogSuccess("<< File decoded with success!")
                self.addLogWarning(
                    "<< Click on the export button to generate the test!")
                self.exportToAction.setEnabled(True)
            else:
                self.addLogWarning("<< No http extracted!")
Example #24
0
class TermWidget(QWidget):
    """Widget wich represents terminal. It only displays text and allows to enter text.
    All highlevel logic should be implemented by client classes
    """

    def __init__(self, font, *args):
        QWidget.__init__(self, *args)
        self._browser = QTextEdit(self)
        self._browser.setReadOnly(True)
        document = self._browser.document()
        document.setDefaultStyleSheet(document.defaultStyleSheet() +
                                      "span {white-space:pre;}")

        self._browser.setFont(font)
        self._edit = _TextEdit(self, font)

        lowLevelWidget = self._edit.focusProxy()
        if lowLevelWidget is None:
            lowLevelWidget = self._edit
        lowLevelWidget.installEventFilter(self)

        self._edit.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
        self.setFocusProxy(self._edit)

        layout = QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._browser)
        layout.addWidget(self._edit)

        self._history = ['']  # current empty line
        self._historyIndex = 0

        self._edit.setFocus()

    def eventFilter(self, obj, event):
        pass # suppress docsting for non-public method
        """QWidget.eventFilter implementation. Catches _edit key pressings. Processes some of them
        """
        if event.type() == QEvent.KeyPress:
            if event.matches(QKeySequence.MoveToNextLine):
                if self._edit.cursorPosition[0] == (len(self._edit.lines) - 1):
                    self._onHistoryNext()
                    return True
            elif event.matches(QKeySequence.MoveToPreviousLine):
                if self._edit.cursorPosition[0] == 0:
                    self._onHistoryPrev()
                    return True
            elif event.matches(QKeySequence.MoveToNextPage) or \
                 event.matches(QKeySequence.MoveToPreviousPage):
                self._browser.keyPressEvent(event)
                return True
            elif event.matches(QKeySequence.InsertParagraphSeparator):
                 return self._editNewLineEvent()

        return QWidget.eventFilter(self, obj, event)

    def _appendToBrowser(self, style, text):
        """Convert text to HTML for inserting it to browser. Insert the HTML
        """
        text = cgi.escape(text)

        text = text.replace('\n', '<br/>')

        defBg = self._browser.palette().color(QPalette.Base)

        h, s, v, a = defBg.getHsvF()

        if style == 'out':
            pass
        elif style == 'in':
            if v > 0.5:  # white background
                v = v - (v / 8)  # make darker
            else:
                v = v + ((1 - v) / 4)  # make ligher
        elif style == 'err':
            if v < 0.5:  # dark background
                v = v + ((1 - v) / 4)  # make ligher

            h = 0
            s = .4
        elif style == 'hint':
            if v < 0.5:  # dark background
                v = v + ((1 - v) / 4)  # make ligher

            h = 0.33
            s = .4
        else:
            assert 0

        bg = QColor.fromHsvF(h, s, v)
        text = '<span style="background-color: %s;">%s</span>' % (bg.name(), text)

        scrollBar = self._browser.verticalScrollBar()
        oldValue = scrollBar.value()

        if False:
            # hlamer: It seems, it is more comfortant, if text is always scrolled
            scrollAtTheEnd = oldValue == scrollBar.maximum()
        else:
            scrollAtTheEnd = True

        self._browser.moveCursor(QTextCursor.End)
        self._browser.insertHtml(text)

        if scrollAtTheEnd:
            scrollBar.setValue(scrollBar.maximum())
        else:
            scrollBar.setValue(oldValue)

        while self._browser.document().characterCount() > 1024 * 1024:
            cursor = self._browser.cursorForPosition(QPoint(0, 0))
            cursor.select(cursor.LineUnderCursor)
            if not cursor.selectedText():
                cursor.movePosition(cursor.Down, cursor.KeepAnchor)
                cursor.movePosition(cursor.EndOfLine, cursor.KeepAnchor)
            cursor.removeSelectedText()

    def setLanguage(self, language):
        """Set highlighting language for input widget
        """
        self._edit.detectSyntax(language=language)

    def execCommand(self, text):
        """Save current command in the history. Append it to the log. Execute child's method. Clear edit line.
        """
        self._appendToBrowser('in', text + '\n')

        if len(self._history) < 2 or\
           self._history[-2] != text:  # don't insert duplicating items
            self._history.insert(-1, text)

        self._historyIndex = len(self._history) - 1

        self._history[-1] = ''
        self._edit.text = ''

        if not text.endswith('\n'):
            text += '\n'

        self.childExecCommand(text)

    def childExecCommand(self, text):
        """Reimplement in the child classes to execute enterred commands
        """
        pass

    def appendOutput(self, text):
        """Appent text to output widget
        """
        self._appendToBrowser('out', text)

    def appendError(self, text):
        """Appent error text to output widget. Text is drawn with red background
        """
        self._appendToBrowser('err', text)

    def appendHint(self, text):
        """Appent error text to output widget. Text is drawn with red background
        """
        self._appendToBrowser('hint', text)

    def clear(self):
        """Clear the widget"""
        self._browser.clear()

    def isCommandComplete(self, text):
        """Executed when Enter is pressed to check if widget should execute the command, or insert newline.

        Implement this function in the child classes.
        """
        return True

    def _editNewLineEvent(self):
        """Handler of Enter pressing in the edit
        """
        text = self._edit.text

        if self.isCommandComplete(text):
            self.execCommand(text)
            return True # processing finished
        else:
            return False  # let the editor process the event

    def _onHistoryNext(self):
        """Down pressed, show next item from the history
        """
        if (self._historyIndex + 1) < len(self._history):
            self._historyIndex += 1
            self._edit.text = self._history[self._historyIndex]
            self._edit.absCursorPosition = len(self._edit.text)

    def _onHistoryPrev(self):
        """Up pressed, show previous item from the history
        """
        if self._historyIndex > 0:
            if self._historyIndex == (len(self._history) - 1):
                self._history[-1] = self._edit.text
            self._historyIndex -= 1
            self._edit.text = self._history[self._historyIndex]
            self._edit.absCursorPosition = len(self._edit.text)