Example #1
0
    def getPasswordsAlert(self):
        self.dialog = QDialog()
        self.dialog.setWindowIcon(QIcon('images/icon.ico'))
        self.dialog.setWindowTitle("Login Details")
        self.dialog.setStyleSheet("background-color: rgb(69,90,100);")
        self.dialog.setWindowFlags(Qt.WindowCloseButtonHint
                                   | Qt.WindowContextHelpButtonHint)
        mainLayout = QVBoxLayout(self.dialog)

        loginHeadLayout = QVBoxLayout()
        loginHeadLayout.setContentsMargins(25, 25, 25, 25)
        loginHeadLayout.addStretch()
        loginHeadLayout.setSpacing(0)
        loginLabel = ImageLable("images/tick.png", "  Login Credentials")
        loginLabel.setWhatsThis(
            "To use the application we need to access the FTP directories & the database you set up"
        )
        loginLabel.setStyleSheet(
            "background-color: rgb(0,188,212);font-size:16px;")
        loginLabel.setContentsMargins(25, 25, 25, 25)
        loginHeadLayout.addWidget(loginLabel.getWidget())

        detailsFrame = QFrame()
        detailsFrame.setContentsMargins(25, 25, 25, 25)
        detailsLayout = QVBoxLayout()
        detailsLayout.setSpacing(10)

        self.databasePasswordField = IconLineEdit('./images/key.png',
                                                  "Database Password", True)
        detailsLayout.addWidget(self.databasePasswordField.getWidget())

        self.ftpPasswordField = IconLineEdit('./images/key.png',
                                             "FTP Password", True)
        detailsLayout.addWidget(self.ftpPasswordField.getWidget())

        loginButton = QPushButton("Login")
        loginButton.setObjectName("loginButton")
        loginButton.setStyleSheet(
            "background-color: rgb(0,188,212); font-size:16px;")
        loginButton.clicked.connect(self.closeWindow)
        detailsLayout.addWidget(loginButton)

        settingsButton = QPushButton("Edit Settings")
        settingsButton.setObjectName("loginButton")
        settingsButton.setStyleSheet(
            "background-color: rgb(192,192,192); font-size:16px;")
        settingsButton.clicked.connect(self.initialiseSettings)
        detailsLayout.addWidget(settingsButton)

        detailsFrame.setLayout(detailsLayout)
        detailsFrame.setStyleSheet(
            "border: 1px solid black; background-color: rgb(96,125,139);")
        loginHeadLayout.addWidget(detailsFrame)
        mainLayout.addLayout(loginHeadLayout)

        self.dialog.setAttribute(Qt.WA_DeleteOnClose)
        self.dialog.exec_()
Example #2
0
    def maintenanceUI(self, window):
        try:
            verticalContainer = QVBoxLayout()
            verticalContainer.setObjectName("verticalContainer")

            #layout for top bar
            topBarLayout = getTopBarLayout(self, window)
            verticalContainer.addLayout(topBarLayout)

            innerContainerFrame = QFrame()
            innerContainer = QHBoxLayout()

            #layout for login detail section
            commitDetailsLayout = QVBoxLayout()
            commitDetailsFrame = QFrame()
            self.openFileButton = QPushButton("Select File")
            self.openFileButton.setWhatsThis(
                "Select the file you're going to compare/push")
            self.openFileButton.setObjectName("openFile")
            self.openFileButton.setStyleSheet(
                "background-color: rgb(255,255,255); font-size:16px;")
            self.openFileButton.clicked.connect(self.openExplorer)
            commitDetailsLayout.addWidget(self.openFileButton)

            #spacing
            spacing = QLabel()
            spacing.setText("")
            spacing.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid rgb(96,125,139);"
            )
            commitDetailsLayout.addWidget(spacing)

            self.commitTitle = IconLineEdit('./images/file.png',
                                            "Commit Title", False)
            self.commitTitle.setWhatsThis(
                "Choose a suitable title to give to the commit you're making")
            commitDetailsLayout.addWidget(self.commitTitle.getWidget())
            self.commitDescription = QTextEdit()
            self.commitDescription.setWhatsThis(
                "Choose a suitable description to give to the commit you're making"
            )
            self.commitDescription.setPlaceholderText("Commit Description...")
            self.commitDescription.setStyleSheet(
                "background-color: rgb(255,255,255); font-size:16px;")
            commitDetailsLayout.addWidget(self.commitDescription)
            addToRepoButton = QPushButton("Add to Repository")
            addToRepoButton.setObjectName("openFile")
            addToRepoButton.setWhatsThis(
                "Click this to push the file you selected to the chosen timeline"
            )
            addToRepoButton.setStyleSheet(
                "background-color: rgb(0,188,212); font-size:16px;")
            addToRepoButton.clicked.connect(self.startPush)
            commitDetailsLayout.addWidget(addToRepoButton)

            commitDetailsFrame.setFixedWidth(200)
            commitDetailsFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            commitDetailsFrame.setLayout(commitDetailsLayout)
            innerContainer.addWidget(commitDetailsFrame)

            #bar to seperate 2 side
            lineLayout = QVBoxLayout()
            lineFrame = QFrame()
            lineFrame.setLayout(lineLayout)
            lineFrame.setStyleSheet(
                "background-color: rgb(0,188,212); border: 1px solid rgb(96,125,139);"
            )
            lineFrame.setFixedWidth(10)
            innerContainer.addWidget(lineFrame)

            #Config comparison layout
            configLayout = QVBoxLayout()

            self.selectedConfig = QComboBox()
            self.selectedConfig.setWhatsThis(
                "This is a list of all the configs made to the devices you've deployed on this application"
            )
            self.selectedConfig.setStyleSheet(getComboxboxStyle())
            self.selectedConfig.activated.connect(self.getFileHistory)
            configLayout.addWidget(self.selectedConfig)
            self.startGrabber()  #grab files from database

            self.whatsAdded = QTextEdit()
            self.whatsAdded.setWhatsThis(
                "This will show you what has been added to the file you've selected compared to what's on record"
            )
            self.whatsAdded.setPlaceholderText("What's been added")
            self.whatsAdded.setReadOnly(True)
            self.whatsAdded.setStyleSheet(
                "QTextEdit {background-color: rgb(255,255,255); font-size:16px; color:green}"
                + getVerticalScrollStyle())
            configLayout.addWidget(self.whatsAdded)
            self.whatsRemoved = QTextEdit()
            self.whatsRemoved.setWhatsThis(
                "This will show you what has been removed from the file that's on record"
            )
            self.whatsRemoved.setPlaceholderText("What's been removed")
            self.whatsRemoved.setReadOnly(True)
            self.whatsRemoved.setStyleSheet(
                "QTextEdit {background-color: rgb(255,255,255); font-size:16px; color:red}"
                + getVerticalScrollStyle())
            configLayout.addWidget(self.whatsRemoved)
            innerContainer.addLayout(configLayout)

            # Commit dot layout
            commitDotHeadingFrame = QFrame()
            commitDotHeadingFrame.setFixedWidth(250)
            commitDotHeadingFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            commitDotHeading = QVBoxLayout()
            commitDotHeading.setContentsMargins(0, 0, 0, 0)
            commitDotHeading.setSpacing(0)
            heading = QLabel()
            heading.setText("Commits")
            heading.setWhatsThis(
                "This will list out the timeline of commits made to files over time"
            )
            heading.setStyleSheet(
                "background-color: rgb(0,188,212); font-size:12px;")
            commitDotHeading.addWidget(heading)

            self.commitDotLayout = QVBoxLayout()

            dot = QRadioButton()
            dot.setText("Commits Appear Here")
            dot.setStyleSheet("border: 1px solid rgb(96,125,139);")
            self.commitDotLayout.addWidget(dot)
            self.dots.append(dot)

            self.commitDotFrame = QFrame()
            self.commitDotFrame.setFixedWidth(230)
            self.commitDotFrame.setContentsMargins(0, 0, 0, 0)
            self.commitDotFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            self.commitDotFrame.setLayout(self.commitDotLayout)

            self.scrollArea = QScrollArea()
            self.scrollArea.setWidget(self.commitDotFrame)
            self.scrollArea.setStyleSheet(getHorizontalScrollStyle() +
                                          getVerticalScrollStyle())

            commitDotHeading.addWidget(self.scrollArea)
            commitDotHeadingFrame.setLayout(commitDotHeading)
            innerContainer.addWidget(commitDotHeadingFrame)

            #entire inner window file config to layout
            innerContainerFrame.setLayout(innerContainer)
            innerContainerFrame.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; "
            )
            innerContainerEffect = QGraphicsDropShadowEffect()
            innerContainerEffect.setBlurRadius(15)
            innerContainerFrame.setGraphicsEffect(innerContainerEffect)

            verticalContainer.addWidget(innerContainerFrame)
            self.layout.setLayout(verticalContainer)
            self.canUseCombobox = True

            self.getFileHistory()

        except Exception as e:
            print(str(e))
Example #3
0
class LoginManager():
    def __init__(self, passwordManager):
        super(LoginManager, self).__init__()
        self.passwordManager = passwordManager
        self.dialog = None
        self.databasePasswordField = None
        self.ftpPasswordField = None
        self.passwordsEntered = False
        self.wantsSettings = False

    def getPasswordsAlert(self):
        self.dialog = QDialog()
        self.dialog.setWindowIcon(QIcon('images/icon.ico'))
        self.dialog.setWindowTitle("Login Details")
        self.dialog.setStyleSheet("background-color: rgb(69,90,100);")
        self.dialog.setWindowFlags(Qt.WindowCloseButtonHint
                                   | Qt.WindowContextHelpButtonHint)
        mainLayout = QVBoxLayout(self.dialog)

        loginHeadLayout = QVBoxLayout()
        loginHeadLayout.setContentsMargins(25, 25, 25, 25)
        loginHeadLayout.addStretch()
        loginHeadLayout.setSpacing(0)
        loginLabel = ImageLable("images/tick.png", "  Login Credentials")
        loginLabel.setWhatsThis(
            "To use the application we need to access the FTP directories & the database you set up"
        )
        loginLabel.setStyleSheet(
            "background-color: rgb(0,188,212);font-size:16px;")
        loginLabel.setContentsMargins(25, 25, 25, 25)
        loginHeadLayout.addWidget(loginLabel.getWidget())

        detailsFrame = QFrame()
        detailsFrame.setContentsMargins(25, 25, 25, 25)
        detailsLayout = QVBoxLayout()
        detailsLayout.setSpacing(10)

        self.databasePasswordField = IconLineEdit('./images/key.png',
                                                  "Database Password", True)
        detailsLayout.addWidget(self.databasePasswordField.getWidget())

        self.ftpPasswordField = IconLineEdit('./images/key.png',
                                             "FTP Password", True)
        detailsLayout.addWidget(self.ftpPasswordField.getWidget())

        loginButton = QPushButton("Login")
        loginButton.setObjectName("loginButton")
        loginButton.setStyleSheet(
            "background-color: rgb(0,188,212); font-size:16px;")
        loginButton.clicked.connect(self.closeWindow)
        detailsLayout.addWidget(loginButton)

        settingsButton = QPushButton("Edit Settings")
        settingsButton.setObjectName("loginButton")
        settingsButton.setStyleSheet(
            "background-color: rgb(192,192,192); font-size:16px;")
        settingsButton.clicked.connect(self.initialiseSettings)
        detailsLayout.addWidget(settingsButton)

        detailsFrame.setLayout(detailsLayout)
        detailsFrame.setStyleSheet(
            "border: 1px solid black; background-color: rgb(96,125,139);")
        loginHeadLayout.addWidget(detailsFrame)
        mainLayout.addLayout(loginHeadLayout)

        self.dialog.setAttribute(Qt.WA_DeleteOnClose)
        self.dialog.exec_()

    def initialiseSettings(self):
        self.wantsSettings = True
        self.dialog.close()

    # when closing the window, check if the passwords are legal ones and if so then allow us to continue
    def closeWindow(self):
        tmpDbPassword = self.databasePasswordField.text()
        tmpFtpPassword = self.ftpPasswordField.text()
        if checkDatabaseConnection(tmpDbPassword):
            if checkFTPConnection(tmpFtpPassword):
                self.passwordManager.setDatabasePassword(
                    self.databasePasswordField.text())
                self.passwordManager.setFtpPassword(
                    self.ftpPasswordField.text())
                self.passwordsEntered = True
                self.dialog.close()
            else:
                messageWindow(
                    "FTP: Connection Error",
                    "Error raised when connecting to FTP, please check your details and try again",
                    True)
                self.databasePasswordField.setText("")
                self.ftpPasswordField.setText("")
        else:
            messageWindow(
                "Database: Connection Error",
                "Error raised when connecting to Database server, please check your details and try again",
                True)
            self.databasePasswordField.setText("")
            self.ftpPasswordField.setText("")
Example #4
0
class MaintenanceModule:
    def __init__(self, window, layout):
        self.window = window
        self.layout = layout
        self.blocked = False
        self.fileToPush = None
        self.pulledFilesContents = None
        self.fileToPull = None

        self.canUseCombobox = False  # ensures combo box doesn't fire when not wanted

        self.confFiles = None
        self.currentFilesHistory = None
        self.dots = []
        self.filesLinkedToDots = []
        self.ftpPassword = window.passwordManager.getFtpPassword()
        self.databasePassword = window.passwordManager.getDatabasePassword()

        self.changed = None
        self.removed = None

    # Creating the maintenance window GUI
    def maintenanceUI(self, window):
        try:
            verticalContainer = QVBoxLayout()
            verticalContainer.setObjectName("verticalContainer")

            #layout for top bar
            topBarLayout = getTopBarLayout(self, window)
            verticalContainer.addLayout(topBarLayout)

            innerContainerFrame = QFrame()
            innerContainer = QHBoxLayout()

            #layout for login detail section
            commitDetailsLayout = QVBoxLayout()
            commitDetailsFrame = QFrame()
            self.openFileButton = QPushButton("Select File")
            self.openFileButton.setWhatsThis(
                "Select the file you're going to compare/push")
            self.openFileButton.setObjectName("openFile")
            self.openFileButton.setStyleSheet(
                "background-color: rgb(255,255,255); font-size:16px;")
            self.openFileButton.clicked.connect(self.openExplorer)
            commitDetailsLayout.addWidget(self.openFileButton)

            #spacing
            spacing = QLabel()
            spacing.setText("")
            spacing.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid rgb(96,125,139);"
            )
            commitDetailsLayout.addWidget(spacing)

            self.commitTitle = IconLineEdit('./images/file.png',
                                            "Commit Title", False)
            self.commitTitle.setWhatsThis(
                "Choose a suitable title to give to the commit you're making")
            commitDetailsLayout.addWidget(self.commitTitle.getWidget())
            self.commitDescription = QTextEdit()
            self.commitDescription.setWhatsThis(
                "Choose a suitable description to give to the commit you're making"
            )
            self.commitDescription.setPlaceholderText("Commit Description...")
            self.commitDescription.setStyleSheet(
                "background-color: rgb(255,255,255); font-size:16px;")
            commitDetailsLayout.addWidget(self.commitDescription)
            addToRepoButton = QPushButton("Add to Repository")
            addToRepoButton.setObjectName("openFile")
            addToRepoButton.setWhatsThis(
                "Click this to push the file you selected to the chosen timeline"
            )
            addToRepoButton.setStyleSheet(
                "background-color: rgb(0,188,212); font-size:16px;")
            addToRepoButton.clicked.connect(self.startPush)
            commitDetailsLayout.addWidget(addToRepoButton)

            commitDetailsFrame.setFixedWidth(200)
            commitDetailsFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            commitDetailsFrame.setLayout(commitDetailsLayout)
            innerContainer.addWidget(commitDetailsFrame)

            #bar to seperate 2 side
            lineLayout = QVBoxLayout()
            lineFrame = QFrame()
            lineFrame.setLayout(lineLayout)
            lineFrame.setStyleSheet(
                "background-color: rgb(0,188,212); border: 1px solid rgb(96,125,139);"
            )
            lineFrame.setFixedWidth(10)
            innerContainer.addWidget(lineFrame)

            #Config comparison layout
            configLayout = QVBoxLayout()

            self.selectedConfig = QComboBox()
            self.selectedConfig.setWhatsThis(
                "This is a list of all the configs made to the devices you've deployed on this application"
            )
            self.selectedConfig.setStyleSheet(getComboxboxStyle())
            self.selectedConfig.activated.connect(self.getFileHistory)
            configLayout.addWidget(self.selectedConfig)
            self.startGrabber()  #grab files from database

            self.whatsAdded = QTextEdit()
            self.whatsAdded.setWhatsThis(
                "This will show you what has been added to the file you've selected compared to what's on record"
            )
            self.whatsAdded.setPlaceholderText("What's been added")
            self.whatsAdded.setReadOnly(True)
            self.whatsAdded.setStyleSheet(
                "QTextEdit {background-color: rgb(255,255,255); font-size:16px; color:green}"
                + getVerticalScrollStyle())
            configLayout.addWidget(self.whatsAdded)
            self.whatsRemoved = QTextEdit()
            self.whatsRemoved.setWhatsThis(
                "This will show you what has been removed from the file that's on record"
            )
            self.whatsRemoved.setPlaceholderText("What's been removed")
            self.whatsRemoved.setReadOnly(True)
            self.whatsRemoved.setStyleSheet(
                "QTextEdit {background-color: rgb(255,255,255); font-size:16px; color:red}"
                + getVerticalScrollStyle())
            configLayout.addWidget(self.whatsRemoved)
            innerContainer.addLayout(configLayout)

            # Commit dot layout
            commitDotHeadingFrame = QFrame()
            commitDotHeadingFrame.setFixedWidth(250)
            commitDotHeadingFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            commitDotHeading = QVBoxLayout()
            commitDotHeading.setContentsMargins(0, 0, 0, 0)
            commitDotHeading.setSpacing(0)
            heading = QLabel()
            heading.setText("Commits")
            heading.setWhatsThis(
                "This will list out the timeline of commits made to files over time"
            )
            heading.setStyleSheet(
                "background-color: rgb(0,188,212); font-size:12px;")
            commitDotHeading.addWidget(heading)

            self.commitDotLayout = QVBoxLayout()

            dot = QRadioButton()
            dot.setText("Commits Appear Here")
            dot.setStyleSheet("border: 1px solid rgb(96,125,139);")
            self.commitDotLayout.addWidget(dot)
            self.dots.append(dot)

            self.commitDotFrame = QFrame()
            self.commitDotFrame.setFixedWidth(230)
            self.commitDotFrame.setContentsMargins(0, 0, 0, 0)
            self.commitDotFrame.setStyleSheet(
                "border: 1px solid rgb(96,125,139);")
            self.commitDotFrame.setLayout(self.commitDotLayout)

            self.scrollArea = QScrollArea()
            self.scrollArea.setWidget(self.commitDotFrame)
            self.scrollArea.setStyleSheet(getHorizontalScrollStyle() +
                                          getVerticalScrollStyle())

            commitDotHeading.addWidget(self.scrollArea)
            commitDotHeadingFrame.setLayout(commitDotHeading)
            innerContainer.addWidget(commitDotHeadingFrame)

            #entire inner window file config to layout
            innerContainerFrame.setLayout(innerContainer)
            innerContainerFrame.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; "
            )
            innerContainerEffect = QGraphicsDropShadowEffect()
            innerContainerEffect.setBlurRadius(15)
            innerContainerFrame.setGraphicsEffect(innerContainerEffect)

            verticalContainer.addWidget(innerContainerFrame)
            self.layout.setLayout(verticalContainer)
            self.canUseCombobox = True

            self.getFileHistory()

        except Exception as e:
            print(str(e))

    def findLast(self, s, ch):
        #builds a list of all the occurences of a character
        list = [
            index for index, currentChar in enumerate(s) if currentChar == ch
        ]
        #returns the last index
        return list[-1]

    # Pull file information form the database & start file comparing
    def displayFile(self):
        try:
            if not self.currentFilesHistory is None:
                timestampText = ""
                for i in range(len(self.dots)):
                    if self.dots[i].isChecked():
                        timestampText = self.dots[i].text()
                if not "Commit" in timestampText:
                    if not self.fileToPush is None:
                        path = self.currentFilesHistory[timestampText]
                        self.fileToPull = path
                        # thread to compare files
                        thread = FileComparer(self.window)
                        thread.setup(self)
                        thread.trigger.connect(self.updateChanges)
                        thread.start()
                    else:
                        secondaryWindows.messageWindow(
                            "Select File",
                            "Please select a file first to compare them",
                            False)
        except Exception as e:
            print(str(e))

    # Get file timestamps and the FTP path
    def getFileHistory(self):
        if self.canUseCombobox:
            if not self.confFiles is None:
                nameList = list(self.confFiles.keys())
                nameList.sort()
                self.startHistoryGrabber(
                    nameList[self.selectedConfig.currentIndex()])

    # Compares two configuration files
    def compareFiles(self):
        if self.canUseCombobox:
            self.getContentsOfFile(
            )  # first get the contents of the selected file
            if self.fileToPush is None:
                secondaryWindows.messageWindow(
                    "No local file selected",
                    "Need a local file to compare against", False)
                return
            else:
                try:
                    '''
                    every line that changes means another has been removed
                    we go through both files and compare them, keeping track
                    of line numbers as we go for readibility
                    '''
                    changed = []
                    removed = []
                    currentFile = self.pulledFilesContents.split("\n")
                    newFile = self.fileToPush
                    lineCount = 1
                    with open(newFile, 'r', encoding='utf-8') as f:
                        for line in f:
                            line = line.strip("\n")
                            line = line.replace("\\\\", "")
                            if len(currentFile) > 1:
                                for i in range(0, len(currentFile)):
                                    if not line == currentFile[i]:
                                        changed.append("@" + str(lineCount) +
                                                       ": " + line)
                                        removed.append("@" + str(lineCount) +
                                                       ": " + currentFile[i])
                                        del currentFile[i]
                                        break
                                    else:
                                        del currentFile[i]
                                        break
                            else:
                                changed.append("@" + str(lineCount) + ": " +
                                               line)
                            lineCount += 1

                    if len(currentFile) > 1:
                        for i in range(0, len(currentFile)):
                            removed.append("@" + str(lineCount) + ": " +
                                           currentFile[i])
                            lineCount += 1

                    # go through and make sure it's not just moved to another line
                    if len(changed) > 1 and len(removed) > 1:
                        i = 0
                        while i < len(changed):
                            line = changed[i]
                            if len(line) > 1:
                                start = line.index(":")
                                line = line[start + 2:]
                            for j in range(0, len(removed)):
                                if line in removed[j]:
                                    del changed[i]
                                    del removed[j]
                                    i -= 1
                                    break
                            i += 1

                    self.changed = changed
                    self.removed = removed
                except Exception as e:
                    print(str(e))

    # Checks if changes have been made based on a code passed
    def updateChanges(self, code):
        if code == 0 and not self.changed is None and not self.removed is None:
            self.whatsAdded.setText("")
            self.whatsRemoved.setText("")

            if len(self.changed) == 0:
                self.whatsAdded.append("Nothing Has Been Added!")

            else:
                for i in range(0, len(self.changed)):
                    self.whatsAdded.append("+ " + self.changed[i])

            if len(self.removed) == 0:
                self.whatsRemoved.append("Nothing Has Been Removed!")
            else:
                for i in range(0, len(self.removed)):
                    self.whatsRemoved.append("- " + self.removed[i])
        elif code == 1:
            secondaryWindows.messageWindow("Error", "Error comparing files",
                                           True)

    # Connect to the database
    def startDatabaseGrabber(self):
        # connect to database to pull down primary files
        thread = DatabaseGrabber(self.window)
        thread.setup(self, getDatabaseAddress(), getDatabaseUsername(),
                     self.databasePassword, getDatabase())
        thread.trigger.connect(self.fillComboBox)
        thread.start()

    # Get file timestamps
    def startHistoryGrabber(self, selectedFile):
        thread = SelectedFileGrabber(self.window)
        thread.setup(self, getDatabaseAddress(), getDatabaseUsername(),
                     self.databasePassword, getDatabase(), selectedFile)
        thread.trigger.connect(self.updateDots)
        thread.start()

    # Refreshes the maintenance page
    def refreshPage(self):
        self.canUseCombobox = False
        if self.blocked:
            secondaryWindows.messageWindow("Process is currently running",
                                           "Cannot refresh", False)
        else:
            # clear fields
            self.commitDescription.setText("")
            self.commitTitle.setText("")
            self.whatsRemoved.setText("")
            self.whatsAdded.setText("")
            self.selectedConfig.clear()
            self.openFileButton.setText("Select File")
            self.fileToPush = None
            self.dots.clear()

            layout = self.commitDotLayout.layout()
            self.clearLayout(layout)
            dot = QRadioButton()
            dot.setText("Commits Appear Here")
            dot.setStyleSheet("border: 1px solid rgb(96,125,139);")
            layout.insertWidget(0, dot)
            self.dots.append(dot)

            self.startDatabaseGrabber()

            self.getFileHistory()

    # Gets the file from the FTP Server
    def startGrabber(self):
        self.selectedConfig.clear()
        # this is the users first step so get the password if we don't already have it for later
        # start the database grabber
        self.startDatabaseGrabber()

    def fillComboBox(self, code):
        self.canUseCombobox = False
        if code == 0 and not self.confFiles == None:  # only deal with conf code from deployment class
            nameList = list(self.confFiles.keys())
            nameList.sort()
            for index in range(len(nameList)):
                self.selectedConfig.addItem(nameList[index])
        elif code == 1:  # only deal with conf code from deployment class
            self.selectedConfig.addItem("None Present")
        elif code == -1:
            secondaryWindows.messageWindow(
                "Error",
                "An error occured pulling down info from the database, check your details and try again",
                True)
        elif self.confFiles == None:
            secondaryWindows.messageWindow(
                "Error",
                "An error occured pulling down info from the database, check your details and try again",
                True)
        self.canUseCombobox = True

    #clears the widgets out of the current layout
    def clearLayout(self, layout):
        while layout.count():  # while there are still widgets
            child = layout.takeAt(0)  # take widget
            if child.widget() is not None:
                child.widget().deleteLater(
                )  # if there was one to take then delete it

    def swapIndexes(self, list, a, b):
        tmp = list[b]
        list[b] = list[a]
        list[a] = tmp

    def dateLessThan(self, a, b):
        # is the current year less than the min?
        if int(a[2]) < int(b[2]):
            return True
        # is the current month less than the min?
        if int(a[1]) < int(b[1]):
            return True
        # is the current date less than the min?
        if int(a[1]) == int(b[1]):
            if int(a[0]) < int(b[0]):
                return True

        return False

    def timeLessThan(self, a, b):
        # is the current hour less than the min?
        if int(a[0]) < int(b[0]):
            return True
        # is the current minute less than the min?
        if int(a[0]) == int(b[0]):
            if int(a[1]) < int(b[1]):
                return True
            # is the current second less than the min?
            if int(a[1]) == int(b[1]):
                if float(a[2]) < float(b[2]):
                    return True
            return False

    # sort the timestamp list based on date/time
    def sortTimeStamps(self, timeStamps):
        if len(timeStamps) == 1:
            return timeStamps

        for j in range(0, len(timeStamps)):
            for i in range(1, len(timeStamps) - j):
                timeOne = timeStamps[i - 1]
                spaceIndex = timeOne.index(" ")
                timeOneDate = timeOne[:spaceIndex]
                timeOneDateData = timeOne[:spaceIndex].split('-')

                timeTwo = timeStamps[i]
                spaceIndex = timeTwo.index(" ")
                timeTwoDate = timeTwo[:spaceIndex]
                timeTwoDateData = timeTwo[:spaceIndex].split('-')

                if self.dateLessThan(timeTwoDateData, timeOneDateData):
                    self.swapIndexes(timeStamps, i, i - 1)
                #are they the same date? Compare the time
                elif timeTwoDate == timeOneDate:
                    currentTime = timeTwo[spaceIndex + 1:].split(':')
                    minTime = timeOne[spaceIndex + 1:].split(':')
                    if self.timeLessThan(currentTime, minTime):
                        self.swapIndexes(timeStamps, i, i - 1)

        return timeStamps

    def updateDots(self, code):
        try:
            #first clear out layout
            #self.commitDotLayout
            self.dots.clear()
            layout = self.commitDotLayout.layout()
            self.clearLayout(layout)
            self.scrollArea.setWidgetResizable(True)
            if code == 0 and not self.currentFilesHistory == None:  # only deal with conf code from deployment class
                historyList = list(self.currentFilesHistory.keys())
                historyList = self.sortTimeStamps(historyList)
                for index in range(0, len(historyList)):
                    dot = QRadioButton()
                    dot.setText(historyList[index])
                    dot.setStyleSheet("border: 1px solid rgb(96,125,139);")
                    dot.clicked.connect(self.displayFile)
                    layout.insertWidget(0, dot)
                    self.dots.append(dot)

            elif code == 1:  # only deal with conf code from deployment class
                secondaryWindows.messageWindow(
                    "Error",
                    "An error occured pulling down info from the database, check your details and try again",
                    True)
            elif self.currentFilesHistory == None:
                secondaryWindows.messageWindow(
                    "Error",
                    "An error occured pulling down info from the database, check your details and try again",
                    True)

        except Exception as e:
            print(str(e))

    def getContentsOfFile(self):
        returnString = StringIO()  # IO object to be written to like a file
        ftpAddress = getFtpAddress()
        selectedFile = self.fileToPull
        ftp = FTP(ftpAddress)
        ftp.login(getFtpUsername(), self.ftpPassword)
        # write contents of file to object with new lines
        ftp.retrlines('RETR ' + selectedFile,
                      lambda line: returnString.write(line + '\n'))
        self.pulledFilesContents = returnString.getvalue()

    #  opens the explorer to get the file specified
    def openExplorer(self):
        try:
            #path returned as tuple though we just want the actual path
            name, _ = QFileDialog.getOpenFileName(
                self.window,
                'Open File',
                options=QFileDialog.DontUseNativeDialog)
            if len(name) < 1:
                return
            start = self.findLast(name, "/") + 1
            filename = name[start:]
            extension = filename[len(filename) - 5:]
            if not ".conf" == extension:
                secondaryWindows.messageWindow(
                    "Not a configuration file",
                    "Please select a configuration file to push", False)
                return
            self.openFileButton.setText(name[start:])
            self.fileToPush = name
        except Exception:
            secondaryWindows.messageWindow(
                "Error", "Error parsing file, please ensure "
                "it's a .conf file with a suitable filename", True)

    def startPush(self):
        if not self.blocked:
            if self.fileToPush is None:
                secondaryWindows.messageWindow("No File Selected",
                                               "Please select a file to push",
                                               False)
                return
            elif len(self.commitTitle.text()) < 1:
                secondaryWindows.messageWindow(
                    "No Commit Title", "Please enter a title for your commit",
                    False)
                return
            elif len(self.commitDescription.toPlainText()) < 1:
                secondaryWindows.messageWindow(
                    "No Commit description",
                    "Please enter a description for your commit", False)
                return

            selectedTimeline = self.selectedConfig.currentText()

            #see if they want to commit to that files timeline
            reply = QMessageBox.question(
                self.window, 'Confirmation',
                "Are you sure you want to push to " + selectedTimeline +
                "'s timeline?", QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.blocked = True
                thread = RepoInterface(self.window)
                thread.setup(self)
                thread.trigger.connect(self.finishedPushingToRepo)
                thread.start()
            else:
                return
        else:
            secondaryWindows.messageWindow(
                "Process is currently running",
                "There is still a file being pushed", False)

    def finishedPushingToRepo(self, code):
        self.blocked = False
        if code == 0:
            self.refreshPage()
            secondaryWindows.messageWindow(
                "Success!", "Updated the repository successfully", False)
        else:
            secondaryWindows.messageWindow(
                "Error", "Error pushing the files to the repository", False)
Example #5
0
    def deploymentUI(self, window):
        try:
            self.consolePasswordField = IconLineEdit('./images/key.png', "Console Server Password",True)
            self.consolePasswordField.setWhatsThis("""This is the password for your console server it's required for the application to integrate with devices""")
            self.initialDevicePassword = IconLineEdit('./images/key.png', "Initial Device Password", True)
            self.initialDevicePassword.setWhatsThis("""You can choose what the initial password of each device will be, you can change individual device's password later on""")
            self.fromPortNo = IconLineEdit('./images/from.png', "From Port No.",False)
            self.fromPortNo.setWhatsThis("This is the FIRST port the devices are plugged into")
            self.toPortNo = IconLineEdit('./images/to.png', "To Port No.",False)
            self.toPortNo.setWhatsThis("This is the LAST port the devices are plugged into")
            self.willCloneToBackup = QCheckBox("Clone to Backup Partition")
            self.willCloneToBackup.setWhatsThis("If you would like to have each device clone the os to the backup partition then click here, if it's not available on the device then leave this box unchecked")
            self.osVersions = QComboBox()
            self.osVersions.setWhatsThis("Use this to select the OS you want to put on each device. it will be copied over from your FTP server to each device")
            self.fromConfiguration = QComboBox()
            self.fromConfiguration.setWhatsThis("Choose the FIRST in the list of configurations to apply to the devices")
            self.toConfiguration = QComboBox()
            self.fromConfiguration.setWhatsThis("Choose the LAST in the list of configurations to apply to the devices")
            verticalContainer = QVBoxLayout()
            verticalContainer.setObjectName("verticalContainer")

            topBarLayout = getTopBarLayout(self, window)
            verticalContainer.addLayout(topBarLayout)

            innerContainer = QHBoxLayout()
            innerContainer.setContentsMargins(0, 0, 0, 0)
            innerContainer.setObjectName("innerContainer")

            loginHeadLayout = QVBoxLayout()
            loginHeadLayout.addStretch()
            loginHeadLayout.setSpacing(0)
            loginLabel = ImageLable("images/hexagon.png", "Device Deployment Information           ")
            loginLabel.setStyleSheet("background-color: rgb(0,188,212);font-size:16px;")
            loginHeadLayout.addWidget(loginLabel.getWidget())

            loginFrame = QFrame()
            loginDetailsLayout = QGridLayout()
            loginDetailsLayout.setObjectName("loginDetailsLayout")
            loginDetailsLayout.setSpacing(36)

            self.osVersions.setObjectName("self.osVersions")
            self.osVersions.setStyleSheet(getComboxboxStyle())

            # Connect to ftp and get files for updating os
            self.osVersions.clear()
            self.osVersions.addItem("Loading")
            thread = FileGrabber(self.window)
            thread.setup(self, ".tgz",self.ftpPassword)
            thread.trigger.connect(self.fillComboBox)
            thread.start()
            self.threads.append(thread)

            loginDetailsLayout.addWidget(self.osVersions, 0, 0, 1, 1)

            portNoLayout = QGridLayout()
            portNoLayout.setObjectName("portNoLayout")
            label = QLabel("   TO   ")
            label.setObjectName("label")
            label.setStyleSheet("color:white; font-size:16px; border: 1px solid rgb(96,125,139);")
            portNoLayout.addWidget(label, 0, 1, 1, 1)

            portNoLayout.addWidget(self.fromPortNo.getWidget(), 0, 0, 1, 1)

            portNoLayout.addWidget(self.toPortNo.getWidget(), 0, 2, 1, 1)
            loginDetailsLayout.addLayout(portNoLayout, 1, 0, 1, 1)

            loginDetailsLayout.addWidget(self.consolePasswordField.getWidget(), 2, 0, 1, 1)

            loginDetailsLayout.addWidget(self.initialDevicePassword.getWidget(), 3, 0, 1, 1)

            checkboxLayout = QVBoxLayout()

            self.willCloneToBackup.setStyleSheet("color:white; font-size:16px; border: 1px solid rgb(96,125,139);")
            checkboxLayout.addWidget(self.willCloneToBackup)
            loginDetailsLayout.addLayout(checkboxLayout, 4, 0, 1, 1)

            configurationRangeFrame = QFrame()
            configurationRangeFrame.setContentsMargins(10, 1, 10, 1)
            configurationRangeLayout = QVBoxLayout()
            configurationRangeLayout.setObjectName("configurationRangeLayout")
            configurationRangeLayout.setSpacing(10)
            configurationRangeHeading = QLabel("Inital Configuration Range")
            configurationRangeHeading.setObjectName("configurationRangeHeading")
            configurationRangeHeading.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            configurationRangeLayout.addWidget(configurationRangeHeading)

            self.fromConfiguration.setObjectName("fromConfiguration")
            self.fromConfiguration.setStyleSheet(getComboxboxStyle())

            self.toConfiguration.setObjectName("toConfiguration")
            self.toConfiguration.setStyleSheet(getComboxboxStyle())

            # connect to ftp and get any files from ftp
            self.fromConfiguration.clear()
            self.toConfiguration.clear()
            self.fromConfiguration.addItem("Loading")
            self.toConfiguration.addItem("Loading")
            thread = FileGrabber(self.window)
            thread.setup(self, ".conf",self.ftpPassword)
            thread.trigger.connect(self.fillComboBox)
            thread.start()
            self.threads.append(thread)

            configurationRangeLayout.addWidget(self.fromConfiguration)
            configurationRangeLayout.addWidget(self.toConfiguration)
            configurationRangeFrame.setLayout(configurationRangeLayout)
            configurationRangeFrame.setStyleSheet("background-color: white; border: 1px solid black; font-size:16px; ")
            loginDetailsLayout.addWidget(configurationRangeFrame, 5, 0, 1, 1)
            loginDetailsLayout.setAlignment(Qt.AlignCenter)

            deploymentButton = QPushButton("Begin Deployment")
            deploymentButton.setObjectName("deploymentButton")
            deploymentButton.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            deploymentButton.clicked.connect(self.beginDeployment)
            loginDetailsLayout.addWidget(deploymentButton, 6, 0, 1, 1)

            displayDbButton = QPushButton("Display Database")
            displayDbButton.setObjectName("displayDbButton")
            displayDbButton.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            displayDbButton.clicked.connect(self.checkDatabase)
            loginDetailsLayout.addWidget(displayDbButton, 7, 0, 1, 1)

            loginFrame.setLayout(loginDetailsLayout)
            loginFrame.setStyleSheet("background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; ")
            loginEffect = QGraphicsDropShadowEffect()
            loginEffect.setBlurRadius(15)
            loginFrame.setGraphicsEffect(loginEffect)

            loginHeadLayout.addWidget(loginFrame)
            innerContainer.addLayout(loginHeadLayout)

            progressBarLayout = QGridLayout()
            progressBarLayout.setObjectName("progressBarLayout")

            self.progressBar = QProgressBar()
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
            self.progressBar.setSizePolicy(sizePolicy)
            self.progressBar.setProperty("value", 0)
            self.progressBar.setOrientation(Qt.Vertical)
            self.progressBar.setInvertedAppearance(True)
            self.progressBar.setTextVisible(False)
            self.progressBar.setTextDirection(QProgressBar.TopToBottom)
            self.progressBar.setObjectName("self.progressBar")
            self.progressBar.setStyleSheet("QProgressBar::chunk:vertical { background-color: rgb(0,188,212)}")

            progressBarLayout.addWidget(self.progressBar, 0, 0, 1, 1)

            progressBarLayout.setContentsMargins(50, 0, 50, 0)
            innerContainer.addLayout(progressBarLayout)

            progressTextFrame = QFrame()
            progressTextLayout = QGridLayout()

            progressTextLayout.setObjectName("progressTextLayout")
            progressTextLayout.setSpacing(43)
            deploymentProgressHeaderLayout = QVBoxLayout()
            deploymentProgressHeaderLayout.setSpacing(0)
            deploymentProgressHeaderLayout.addStretch()
            deploymentProgressHeader = ImageLable('./images/tick.png', "Deployment Progress")
            deploymentProgressHeader.setObjectName("deploymentProgressHeader")
            deploymentProgressHeader.setStyleSheet(
                "background-color: rgb(0,188,212);font-size:16px; height: 20px;")
            deploymentProgressHeaderLayout.addWidget(deploymentProgressHeader.getWidget())

            self.connectedToDevice = QLabel("Connect to the device")
            self.connectedToDevice.setObjectName("self.connectedToDevice")
            self.connectedToDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.connectedToDevice, 2, 0, 1, 1)

            self.loggedIn = QLabel("Log in")
            self.loggedIn.setObjectName("self.loggedIn")
            self.loggedIn.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.loggedIn, 3, 0, 1, 1)

            self.downloadingOS = QLabel("Downloading OS")
            self.downloadingOS.setObjectName("self.downloadingOS")
            self.downloadingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.downloadingOS, 4, 0, 1, 1)

            self.installingOS = QLabel("Installing OS")
            self.installingOS.setObjectName("self.installingOS")
            self.installingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.installingOS, 5, 0, 1, 1)

            self.rebootingDevice = QLabel("Rebooting the device")
            self.rebootingDevice.setObjectName("self.rebootingDevice")
            self.rebootingDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.rebootingDevice, 6, 0, 1, 1)

            self.loggedInAgain = QLabel("Logging into the device")
            self.loggedInAgain.setObjectName("self.loggedInAgain")
            self.loggedInAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.loggedInAgain, 7, 0, 1, 1)

            self.applyingConfig = QLabel("Applying the configuration file")
            self.applyingConfig.setObjectName("self.applyingConfig")
            self.applyingConfig.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.applyingConfig, 8, 0, 1, 1)

            self.rebootingTheDeviceAgain = QLabel("Rebooting the device")
            self.rebootingTheDeviceAgain.setObjectName("self.rebootingTheDeviceAgain")
            self.rebootingTheDeviceAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.rebootingTheDeviceAgain, 9, 0, 1, 1)

            self.deploymentSuccessful = QLabel("Deployment Successful")
            self.deploymentSuccessful.setObjectName("self.deploymentSuccessful")
            self.deploymentSuccessful.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.deploymentSuccessful, 10, 0, 1, 1)

            progressTextFrame.setLayout(progressTextLayout)
            progressTextFrame.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; ")
            progressTextEffect = QGraphicsDropShadowEffect()
            progressTextEffect.setBlurRadius(15)
            progressTextFrame.setGraphicsEffect(progressTextEffect)
            deploymentProgressHeaderLayout.addWidget(progressTextFrame)
            innerContainer.addLayout(deploymentProgressHeaderLayout)
            verticalContainer.addLayout(innerContainer)

            self.layout.setLayout(verticalContainer)
        except Exception as e:
            print(str(e))
Example #6
0
class DeploymentModule:
    def __init__(self, window, layout):
        self.layout = layout
        self.window = window
        self.blocked = False
        self.threads = []
        global deploymentWindow
        deploymentWindow = self

        self.ftpPassword = window.passwordManager.getFtpPassword()
        self.databasePassword = window.passwordManager.getDatabasePassword()

    #PyQt5 GUI setup
    def deploymentUI(self, window):
        try:
            self.consolePasswordField = IconLineEdit('./images/key.png', "Console Server Password",True)
            self.consolePasswordField.setWhatsThis("""This is the password for your console server it's required for the application to integrate with devices""")
            self.initialDevicePassword = IconLineEdit('./images/key.png', "Initial Device Password", True)
            self.initialDevicePassword.setWhatsThis("""You can choose what the initial password of each device will be, you can change individual device's password later on""")
            self.fromPortNo = IconLineEdit('./images/from.png', "From Port No.",False)
            self.fromPortNo.setWhatsThis("This is the FIRST port the devices are plugged into")
            self.toPortNo = IconLineEdit('./images/to.png', "To Port No.",False)
            self.toPortNo.setWhatsThis("This is the LAST port the devices are plugged into")
            self.willCloneToBackup = QCheckBox("Clone to Backup Partition")
            self.willCloneToBackup.setWhatsThis("If you would like to have each device clone the os to the backup partition then click here, if it's not available on the device then leave this box unchecked")
            self.osVersions = QComboBox()
            self.osVersions.setWhatsThis("Use this to select the OS you want to put on each device. it will be copied over from your FTP server to each device")
            self.fromConfiguration = QComboBox()
            self.fromConfiguration.setWhatsThis("Choose the FIRST in the list of configurations to apply to the devices")
            self.toConfiguration = QComboBox()
            self.fromConfiguration.setWhatsThis("Choose the LAST in the list of configurations to apply to the devices")
            verticalContainer = QVBoxLayout()
            verticalContainer.setObjectName("verticalContainer")

            topBarLayout = getTopBarLayout(self, window)
            verticalContainer.addLayout(topBarLayout)

            innerContainer = QHBoxLayout()
            innerContainer.setContentsMargins(0, 0, 0, 0)
            innerContainer.setObjectName("innerContainer")

            loginHeadLayout = QVBoxLayout()
            loginHeadLayout.addStretch()
            loginHeadLayout.setSpacing(0)
            loginLabel = ImageLable("images/hexagon.png", "Device Deployment Information           ")
            loginLabel.setStyleSheet("background-color: rgb(0,188,212);font-size:16px;")
            loginHeadLayout.addWidget(loginLabel.getWidget())

            loginFrame = QFrame()
            loginDetailsLayout = QGridLayout()
            loginDetailsLayout.setObjectName("loginDetailsLayout")
            loginDetailsLayout.setSpacing(36)

            self.osVersions.setObjectName("self.osVersions")
            self.osVersions.setStyleSheet(getComboxboxStyle())

            # Connect to ftp and get files for updating os
            self.osVersions.clear()
            self.osVersions.addItem("Loading")
            thread = FileGrabber(self.window)
            thread.setup(self, ".tgz",self.ftpPassword)
            thread.trigger.connect(self.fillComboBox)
            thread.start()
            self.threads.append(thread)

            loginDetailsLayout.addWidget(self.osVersions, 0, 0, 1, 1)

            portNoLayout = QGridLayout()
            portNoLayout.setObjectName("portNoLayout")
            label = QLabel("   TO   ")
            label.setObjectName("label")
            label.setStyleSheet("color:white; font-size:16px; border: 1px solid rgb(96,125,139);")
            portNoLayout.addWidget(label, 0, 1, 1, 1)

            portNoLayout.addWidget(self.fromPortNo.getWidget(), 0, 0, 1, 1)

            portNoLayout.addWidget(self.toPortNo.getWidget(), 0, 2, 1, 1)
            loginDetailsLayout.addLayout(portNoLayout, 1, 0, 1, 1)

            loginDetailsLayout.addWidget(self.consolePasswordField.getWidget(), 2, 0, 1, 1)

            loginDetailsLayout.addWidget(self.initialDevicePassword.getWidget(), 3, 0, 1, 1)

            checkboxLayout = QVBoxLayout()

            self.willCloneToBackup.setStyleSheet("color:white; font-size:16px; border: 1px solid rgb(96,125,139);")
            checkboxLayout.addWidget(self.willCloneToBackup)
            loginDetailsLayout.addLayout(checkboxLayout, 4, 0, 1, 1)

            configurationRangeFrame = QFrame()
            configurationRangeFrame.setContentsMargins(10, 1, 10, 1)
            configurationRangeLayout = QVBoxLayout()
            configurationRangeLayout.setObjectName("configurationRangeLayout")
            configurationRangeLayout.setSpacing(10)
            configurationRangeHeading = QLabel("Inital Configuration Range")
            configurationRangeHeading.setObjectName("configurationRangeHeading")
            configurationRangeHeading.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            configurationRangeLayout.addWidget(configurationRangeHeading)

            self.fromConfiguration.setObjectName("fromConfiguration")
            self.fromConfiguration.setStyleSheet(getComboxboxStyle())

            self.toConfiguration.setObjectName("toConfiguration")
            self.toConfiguration.setStyleSheet(getComboxboxStyle())

            # connect to ftp and get any files from ftp
            self.fromConfiguration.clear()
            self.toConfiguration.clear()
            self.fromConfiguration.addItem("Loading")
            self.toConfiguration.addItem("Loading")
            thread = FileGrabber(self.window)
            thread.setup(self, ".conf",self.ftpPassword)
            thread.trigger.connect(self.fillComboBox)
            thread.start()
            self.threads.append(thread)

            configurationRangeLayout.addWidget(self.fromConfiguration)
            configurationRangeLayout.addWidget(self.toConfiguration)
            configurationRangeFrame.setLayout(configurationRangeLayout)
            configurationRangeFrame.setStyleSheet("background-color: white; border: 1px solid black; font-size:16px; ")
            loginDetailsLayout.addWidget(configurationRangeFrame, 5, 0, 1, 1)
            loginDetailsLayout.setAlignment(Qt.AlignCenter)

            deploymentButton = QPushButton("Begin Deployment")
            deploymentButton.setObjectName("deploymentButton")
            deploymentButton.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            deploymentButton.clicked.connect(self.beginDeployment)
            loginDetailsLayout.addWidget(deploymentButton, 6, 0, 1, 1)

            displayDbButton = QPushButton("Display Database")
            displayDbButton.setObjectName("displayDbButton")
            displayDbButton.setStyleSheet("background-color: rgb(0,188,212); font-size:16px;")
            displayDbButton.clicked.connect(self.checkDatabase)
            loginDetailsLayout.addWidget(displayDbButton, 7, 0, 1, 1)

            loginFrame.setLayout(loginDetailsLayout)
            loginFrame.setStyleSheet("background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; ")
            loginEffect = QGraphicsDropShadowEffect()
            loginEffect.setBlurRadius(15)
            loginFrame.setGraphicsEffect(loginEffect)

            loginHeadLayout.addWidget(loginFrame)
            innerContainer.addLayout(loginHeadLayout)

            progressBarLayout = QGridLayout()
            progressBarLayout.setObjectName("progressBarLayout")

            self.progressBar = QProgressBar()
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
            self.progressBar.setSizePolicy(sizePolicy)
            self.progressBar.setProperty("value", 0)
            self.progressBar.setOrientation(Qt.Vertical)
            self.progressBar.setInvertedAppearance(True)
            self.progressBar.setTextVisible(False)
            self.progressBar.setTextDirection(QProgressBar.TopToBottom)
            self.progressBar.setObjectName("self.progressBar")
            self.progressBar.setStyleSheet("QProgressBar::chunk:vertical { background-color: rgb(0,188,212)}")

            progressBarLayout.addWidget(self.progressBar, 0, 0, 1, 1)

            progressBarLayout.setContentsMargins(50, 0, 50, 0)
            innerContainer.addLayout(progressBarLayout)

            progressTextFrame = QFrame()
            progressTextLayout = QGridLayout()

            progressTextLayout.setObjectName("progressTextLayout")
            progressTextLayout.setSpacing(43)
            deploymentProgressHeaderLayout = QVBoxLayout()
            deploymentProgressHeaderLayout.setSpacing(0)
            deploymentProgressHeaderLayout.addStretch()
            deploymentProgressHeader = ImageLable('./images/tick.png', "Deployment Progress")
            deploymentProgressHeader.setObjectName("deploymentProgressHeader")
            deploymentProgressHeader.setStyleSheet(
                "background-color: rgb(0,188,212);font-size:16px; height: 20px;")
            deploymentProgressHeaderLayout.addWidget(deploymentProgressHeader.getWidget())

            self.connectedToDevice = QLabel("Connect to the device")
            self.connectedToDevice.setObjectName("self.connectedToDevice")
            self.connectedToDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.connectedToDevice, 2, 0, 1, 1)

            self.loggedIn = QLabel("Log in")
            self.loggedIn.setObjectName("self.loggedIn")
            self.loggedIn.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.loggedIn, 3, 0, 1, 1)

            self.downloadingOS = QLabel("Downloading OS")
            self.downloadingOS.setObjectName("self.downloadingOS")
            self.downloadingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.downloadingOS, 4, 0, 1, 1)

            self.installingOS = QLabel("Installing OS")
            self.installingOS.setObjectName("self.installingOS")
            self.installingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.installingOS, 5, 0, 1, 1)

            self.rebootingDevice = QLabel("Rebooting the device")
            self.rebootingDevice.setObjectName("self.rebootingDevice")
            self.rebootingDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.rebootingDevice, 6, 0, 1, 1)

            self.loggedInAgain = QLabel("Logging into the device")
            self.loggedInAgain.setObjectName("self.loggedInAgain")
            self.loggedInAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.loggedInAgain, 7, 0, 1, 1)

            self.applyingConfig = QLabel("Applying the configuration file")
            self.applyingConfig.setObjectName("self.applyingConfig")
            self.applyingConfig.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.applyingConfig, 8, 0, 1, 1)

            self.rebootingTheDeviceAgain = QLabel("Rebooting the device")
            self.rebootingTheDeviceAgain.setObjectName("self.rebootingTheDeviceAgain")
            self.rebootingTheDeviceAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.rebootingTheDeviceAgain, 9, 0, 1, 1)

            self.deploymentSuccessful = QLabel("Deployment Successful")
            self.deploymentSuccessful.setObjectName("self.deploymentSuccessful")
            self.deploymentSuccessful.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
            progressTextLayout.addWidget(self.deploymentSuccessful, 10, 0, 1, 1)

            progressTextFrame.setLayout(progressTextLayout)
            progressTextFrame.setStyleSheet(
                "background-color: rgb(96,125,139); border: 1px solid black; font-size:16px; ")
            progressTextEffect = QGraphicsDropShadowEffect()
            progressTextEffect.setBlurRadius(15)
            progressTextFrame.setGraphicsEffect(progressTextEffect)
            deploymentProgressHeaderLayout.addWidget(progressTextFrame)
            innerContainer.addLayout(deploymentProgressHeaderLayout)
            verticalContainer.addLayout(innerContainer)

            self.layout.setLayout(verticalContainer)
        except Exception as e:
            print(str(e))

    def clearProgressText(self):
        self.connectedToDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.loggedIn.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.downloadingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.installingOS.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.rebootingDevice.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.loggedInAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.applyingConfig.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.rebootingTheDeviceAgain.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")
        self.deploymentSuccessful.setStyleSheet("color:white; font-size:16px;border: 1px solid rgb(96,125,139);")

    def updateProgress(self, percentage):
        self.progressBar.setValue(percentage)
        if percentage == 11:
            self.connectedToDevice.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 22:
            self.loggedIn.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 44:
            self.downloadingOS.setStyleSheet("color:white; font-size:16px;")
            self.installingOS.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 55:
            self.rebootingDevice.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 66:
            self.loggedInAgain.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 77:
            self.applyingConfig.setStyleSheet("color:white; font-size:16px;")
        elif percentage == 88:
            self.rebootingTheDeviceAgain.setStyleSheet("color:white; font-size:16px;")
        else:
            self.blocked = False
            self.deploymentSuccessful.setStyleSheet("color:white; font-size:16px;")

    # fill appropriate combo box when code from thread is returned
    def fillComboBox(self, code):
        # deal with conf or tgz depending on code
        if code == 0:
            self.fromConfiguration.clear()
            self.toConfiguration.clear()
            for index in range(len(self.confFiles)):
                self.fromConfiguration.addItem(QIcon("images/from.png"),self.confFiles[index])
                self.toConfiguration.addItem(QIcon("images/to.png"),self.confFiles[index])
        elif code == 1:
            self.osVersions.clear()
            for index in range(len(self.osFiles)):
                self.osVersions.addItem(QIcon("images/device.png"),self.osFiles[index])

    # Refresh current page
    def refreshPage(self):
        try:
            if self.blocked:
                secondaryWindows.messageWindow("Process is currently running", "Cannot refresh page when units are being updated",
                                  False)
            else:
                self.fromConfiguration.addItem("Loading")
                self.toConfiguration.addItem("Loading")
                self.osVersions.addItem("Loading")
                self.clearProgressText()
                self.fromConfiguration.clear()
                self.toConfiguration.clear()
                thread = FileGrabber(self.window)
                thread.setup(self, ".conf",self.ftpPassword)
                thread.trigger.connect(self.fillComboBox)
                thread.start()
                self.threads.append(thread)

                thread = FileGrabber(self.window)
                thread.setup(self, ".tgz",self.ftpPassword)
                thread.trigger.connect(self.fillComboBox)
                thread.start()
                self.threads.append(thread)

                self.initialDevicePassword.setText("")
                self.consolePasswordField.setText("")
                self.willCloneToBackup.setChecked(False)
                self.toPortNo.setText("")
                self.fromPortNo.setText("")
        except Exception as e:
            print(str(e))
            secondaryWindows.messageWindow("Error Refreshing",
                              "An error occured clearing page and connecting to FTP server, try again later", True)

    def checkDatabase(self):
        if self.blocked:
            secondaryWindows.messageWindow("Process Running",
                                           "You're currently runnning an update, wait till this is finished",
                                           True)
            return

        if not checkDatabaseConnection(self.databasePassword):
            secondaryWindows.messageWindow("Database: Connection Error",
                                           "Error raised when connecting to Database, please check your details and try again",
                                           True)
            return

        listing = getDatabaseListing(self.databasePassword)
        if not listing is None:
            secondaryWindows.displayDatabaseWindow(listing)
        elif listing is None:
            secondaryWindows.messageWindow("Database is empty",
                                           "There is no data to pull from your database",
                                           False)
            return
        elif listing is "Error":
            secondaryWindows.messageWindow("Database Error",
                                           "There was an error pulling data from your database",
                                           True)

    def isNumber(self,s):
        try:
            int(s)
            return True
        except ValueError:
            return False

    # makes sure there is at least one number in the password adn the length is > 6
    def checkValidity(self,string):
        if len(string) < 6:
            return False
        for i in range(0,len(string)):
            if self.isNumber(string[i]):
                return True
            elif string[i].isupper():
                return True

        return False

    def beginDeployment(self):
        try:
            # if the window is pressed twice
            if self.blocked:
                secondaryWindows.messageWindow("Process running.", "Please wait for deployment to finish.", True)
                return
            self.threads.clear()
            # Make sure fields aren't empty
            if self.fieldsEmpty():
                secondaryWindows.messageWindow("Empty Fields", "Please ensure all the fields are filled", True)
                return
            # Make sure both port numbers are actually numbers
            if (not isNumber(self.toPortNo.text()) or not isNumber(self.fromPortNo.text())):
                secondaryWindows.messageWindow("Not a Number", "Please ensure ports are numbers", True)
                return

            # make sure configurations are the same amount as devices being updated
            fromConf = self.fromConfiguration.currentIndex()
            toConf = self.toConfiguration.currentIndex()
            fromPort = int(self.fromPortNo.text())
            toPort = int(self.toPortNo.text())
            if not (toConf >= fromConf):
                secondaryWindows.messageWindow("Config List Error",
                                               "Please ensure your starting configuration is before your final configuration",
                                               True)
                return
            if not ((toConf - fromConf) + 1 == (toPort - fromPort) + 1):
                secondaryWindows.messageWindow("Not Enough Configs",
                                               "Please ensure there are enough config files for each specified device",
                                               True)
                return

            devicePassword = self.initialDevicePassword.text()
            if not self.checkValidity(devicePassword):
                secondaryWindows.messageWindow("Password error",
                                               """
                                               Please ensure the password is at least 6 characters and contains
                                               either a number or an uppercase letter
                                               """,
                                               True)
                return

            # apply patch
            patch_crypto_be_discovery()
            configurationsToUse = []
            for index in range(fromConf, toConf + 1):
                configurationsToUse.append(self.confFiles[index])

            willBackup = self.willCloneToBackup.isChecked()
            OsFile = self.osVersions.currentText()
            ftpPassword = self.ftpPassword
            consolePassword = self.consolePasswordField.text()
            databasePassword = self.databasePassword
            self.progressBar.setValue(0)

            # check if connections are accessible
            if not checkFTPConnection(ftpPassword):
                secondaryWindows.messageWindow("FTP: Connection Error",
                                               "Error raised when connecting to FTP server, please check your details and try again",
                                               True)
                return

            if not checkConsoleConnection(getConsoleAddress(), getConsoleName(), consolePassword):
                secondaryWindows.messageWindow("Console Server: Connection Error",
                                               "Error raised when connecting to Console server, please check your details and try again",
                                               True)
                return

            if not checkDatabaseConnection(databasePassword):
                secondaryWindows.messageWindow("Database: Connection Error",
                                               "Error raised when connecting to Database, please check your details and try again",
                                               True)
                return

            self.blocked = True

            confIndex = 0

            # check to see how many devices we're updating
            if toPort - fromPort + 1 == 1:
                thread = Updater(self.window)
                thread.trigger.connect(self.updateProgress)
                thread.setup(toPort, ftpPassword, consolePassword, databasePassword, devicePassword,OsFile, configurationsToUse[confIndex],
                             willBackup,
                             True)
                thread.start()
                self.threads.append(thread)

            else:
                for index in range(fromPort, toPort):
                    thread = Updater(self.window)
                    thread.trigger.connect(self.updateProgress)
                    thread.setup(index, ftpPassword, consolePassword, databasePassword, devicePassword, OsFile, configurationsToUse[confIndex],
                                 willBackup,
                                 False)
                    thread.start()
                    self.threads.append(thread)
                    confIndex += 1
                    time.sleep(5)  # staggered threads to avoid collision

                # make final thread the one to update GUI
                thread = Updater(self.window)
                thread.trigger.connect(self.updateProgress)
                thread.setup(toPort, ftpPassword, consolePassword, databasePassword, devicePassword, OsFile, configurationsToUse[confIndex],
                             willBackup,
                             True)
                thread.start()
                self.threads.append(thread)
        except Exception as e:
            print(str(e))

    def fieldsEmpty(self):
        if len(self.fromPortNo.text()) < 1 or len(self.toPortNo.text()) < 1 or len(
                self.consolePasswordField.text()) < 1:
            return True
        else:
            return False
Example #7
0
    def settingsUI(self, window):
        effect = QGraphicsDropShadowEffect()
        effect.setBlurRadius(15)
        settingsVerticalContainer = QVBoxLayout()
        settingsVerticalContainer.setObjectName("verticalContainer")

        frame = QFrame()

        # Layout of top bar
        topBarLayout = QHBoxLayout()
        topBarLayout.setObjectName("topBarLayout")
        topBarLayout.setAlignment(Qt.AlignLeft)

        backButton = ImageButton(QPixmap("images/back.png"))
        backButton.setObjectName("backButton")
        backButton.clicked.connect(window.initialiseLauncher)
        topBarLayout.addWidget(backButton)
        frame.setLayout(topBarLayout)
        settingsVerticalContainer.addWidget(frame)

        # layout of below 3 boxes
        innerVerticalLayout = QVBoxLayout()
        innerVerticalLayout.setContentsMargins(0, 0, 0, 0)
        innerVerticalLayout.setObjectName("innerVerticalLayout")
        innerFrame = QFrame()
        innerContainer = QHBoxLayout()
        innerContainer.setContentsMargins(0, 0, 0, 0)
        innerContainer.setObjectName("innerContainer")

        ftpHeadingLayout = QVBoxLayout()
        ftpHeadingLayout.setSpacing(0)
        ftpHeadingLayout.addStretch()
        ftpConfigLabel = ImageLable('./images/hexagon.png',
                                    "FTP Configuration")
        ftpConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                         """))
        ftpHeadingLayout.addWidget(ftpConfigLabel.getWidget())

        ftpConfigLayout = QVBoxLayout()
        ftpConfigLayout.setObjectName("ftpConfigLayout")
        ftpConfigLayout.setSpacing(40)
        self.ftpServerAddress = IconLineEdit('./images/device.png',
                                             "Server Address", False)
        self.ftpServerAddress.setWhatsThis(
            "Input where you're FTP server is located")
        ftpConfigLayout.addWidget(self.ftpServerAddress.getWidget())
        self.ftpUsername = IconLineEdit('./images/user.png', "FTP Username",
                                        False)
        self.ftpUsername.setWhatsThis(
            "This is your username for the FTP server")
        ftpConfigLayout.addWidget(self.ftpUsername.getWidget())
        self.ftpOsPath = IconLineEdit('./images/device.png',
                                      "OS Directory Path", False)
        self.ftpOsPath.setWhatsThis(
            "Set the directory in your FTP server for where you keep your .tgz OS files so the application can point to them when deploying devices"
        )
        ftpConfigLayout.addWidget(self.ftpOsPath.getWidget())
        self.ftpConfPath = IconLineEdit('./images/device.png',
                                        "Configuration Path", False)
        self.ftpConfPath.setWhatsThis(
            "Set a directory in your FTP server for new .conf files to be pushed to"
        )
        ftpConfigLayout.addWidget(self.ftpConfPath.getWidget())
        self.ftpIniConfPath = IconLineEdit('./images/device.png',
                                           "Initial Config Path", False)
        self.ftpIniConfPath.setWhatsThis(
            "Set the directory in your FTP server for where you keep your .conf files that have yet to be applied to devices so the application can point to them when deploying devices"
        )
        ftpConfigLayout.addWidget(self.ftpIniConfPath.getWidget())
        ftpConfigLabel = QLabel(
            "*This will be used to push and pull config files for your device as you work"
        )
        ftpConfigLabel.setWordWrap(True)
        ftpConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        ftpConfigLayout.addWidget(ftpConfigLabel)
        ftpFrame = QFrame()
        ftpFrame.setObjectName("ftpFrame")
        ftpFrame.setLayout(ftpConfigLayout)
        ftpFrame.setStyleSheet("""
            QFrame#ftpFrame
            {
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        ftpFrame.setContentsMargins(25, 0, 25, 5)
        ftpFrame.setGraphicsEffect(effect)
        ftpHeadingLayout.addWidget(ftpFrame)
        innerContainer.addLayout(ftpHeadingLayout)

        consoleHeadingLayout = QVBoxLayout()
        consoleHeadingLayout.setSpacing(0)
        consoleHeadingLayout.addStretch()
        consoleConfigLabel = ImageLable('./images/hexagon.png',
                                        "Console Server Configuration")
        consoleConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                         """))
        consoleHeadingLayout.addWidget(consoleConfigLabel.getWidget())

        consoleConfigLayout = QVBoxLayout()
        consoleConfigLayout.setObjectName("consoleConfigLayout")
        consoleConfigLayout.setSpacing(146)
        self.consoleAddress = IconLineEdit('./images/device.png',
                                           "Full Console Address", False)
        self.consoleAddress.setWhatsThis(
            "Set the address for your console server")
        consoleConfigLayout.addWidget(self.consoleAddress.getWidget())
        self.consoleUsername = IconLineEdit('./images/user.png', "Username",
                                            False)
        self.consoleUsername.setWhatsThis(
            "Set the username for your console server")
        consoleConfigLayout.addWidget(self.consoleUsername.getWidget())

        consoleConfigLabel = QLabel(
            "*To allow for bulk updates your console server's info will be required here"
        )
        consoleConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        consoleConfigLabel.setWordWrap(True)
        consoleConfigLayout.addWidget(consoleConfigLabel)

        consoleFrame = QFrame()
        consoleFrame.setLayout(consoleConfigLayout)
        consoleFrame.setObjectName("consoleFrame")
        consoleFrame.setStyleSheet("""
            QFrame#consoleFrame
            {
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        consoleFrame.setContentsMargins(25, 0, 25, 5)
        consoleFrame.setGraphicsEffect(effect)
        consoleHeadingLayout.addWidget(consoleFrame)
        innerContainer.addLayout(consoleHeadingLayout)

        datbaseHeadingLayout = QVBoxLayout()
        datbaseHeadingLayout.setSpacing(0)
        datbaseHeadingLayout.addStretch()
        databaseConfigLabel = ImageLable('./images/hexagon.png',
                                         "Database Configuration")
        databaseConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                            """))
        datbaseHeadingLayout.addWidget(databaseConfigLabel.getWidget())

        databaseConfigLayout = QVBoxLayout()
        databaseConfigLayout.setObjectName("consoleConfigLayout")
        databaseConfigLayout.setSpacing(138)
        self.databseAddress = IconLineEdit('./images/device.png',
                                           "Full Database Address", False)
        self.databseAddress.setWhatsThis("Set the address for your database")
        databaseConfigLayout.addWidget(self.databseAddress.getWidget())
        self.databseUsername = IconLineEdit('./images/user.png', "Username",
                                            False)
        self.databseUsername.setWhatsThis("Set the username for your database")
        databaseConfigLayout.addWidget(self.databseUsername.getWidget())

        databaseConfigLabel = QLabel(
            "*This database will be used to track updated devices and their config files as you work"
        )
        databaseConfigLabel.setWordWrap(True)
        databaseConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        databaseConfigLayout.addWidget(databaseConfigLabel)

        databaseFrame = QFrame()
        databaseFrame.setLayout(databaseConfigLayout)
        databaseFrame.setObjectName("databaseFrame")
        databaseFrame.setStyleSheet("""
            QFrame#databaseFrame{
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        databaseFrame.setContentsMargins(25, 0, 25, 5)
        databaseFrame.setGraphicsEffect(effect)
        datbaseHeadingLayout.addWidget(databaseFrame)
        innerContainer.addLayout(datbaseHeadingLayout)

        innerFrame.setContentsMargins(25, 25, 25, 25)
        innerFrame.setObjectName("innerFrame")
        innerFrame.setStyleSheet(
            "QFrame#innerFrame{ background-color: rgb(96,125,139); border: 1px solid black; font-size:16px} "
        )

        innerVerticalLayout.addLayout(innerContainer)

        bottomLayout = QHBoxLayout()
        bottomLayout.setObjectName("bottomLayout")
        applySettingsButton = QPushButton("Apply Settings")
        applySettingsButton.setStyleSheet(
            "background-color: rgb(0,188,212); font-size:16px;")
        applySettingsButton.clicked.connect(self.applySettings)
        bottomLayout.addWidget(applySettingsButton)

        innerVerticalLayout.addLayout(bottomLayout)
        innerFrame.setLayout(innerVerticalLayout)
        innerFrame.setGraphicsEffect(effect)
        settingsVerticalContainer.addWidget(innerFrame)

        settingsVerticalContainer.addStretch()
        self.layout.setLayout(settingsVerticalContainer)
        self.fillSettingsFields()
Example #8
0
class SettingsModule:
    def __init__(self, window, layout):
        self.window = window
        self.layout = layout
        self.restart = False

    # Setting GUI
    def settingsUI(self, window):
        effect = QGraphicsDropShadowEffect()
        effect.setBlurRadius(15)
        settingsVerticalContainer = QVBoxLayout()
        settingsVerticalContainer.setObjectName("verticalContainer")

        frame = QFrame()

        # Layout of top bar
        topBarLayout = QHBoxLayout()
        topBarLayout.setObjectName("topBarLayout")
        topBarLayout.setAlignment(Qt.AlignLeft)

        backButton = ImageButton(QPixmap("images/back.png"))
        backButton.setObjectName("backButton")
        backButton.clicked.connect(window.initialiseLauncher)
        topBarLayout.addWidget(backButton)
        frame.setLayout(topBarLayout)
        settingsVerticalContainer.addWidget(frame)

        # layout of below 3 boxes
        innerVerticalLayout = QVBoxLayout()
        innerVerticalLayout.setContentsMargins(0, 0, 0, 0)
        innerVerticalLayout.setObjectName("innerVerticalLayout")
        innerFrame = QFrame()
        innerContainer = QHBoxLayout()
        innerContainer.setContentsMargins(0, 0, 0, 0)
        innerContainer.setObjectName("innerContainer")

        ftpHeadingLayout = QVBoxLayout()
        ftpHeadingLayout.setSpacing(0)
        ftpHeadingLayout.addStretch()
        ftpConfigLabel = ImageLable('./images/hexagon.png',
                                    "FTP Configuration")
        ftpConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                         """))
        ftpHeadingLayout.addWidget(ftpConfigLabel.getWidget())

        ftpConfigLayout = QVBoxLayout()
        ftpConfigLayout.setObjectName("ftpConfigLayout")
        ftpConfigLayout.setSpacing(40)
        self.ftpServerAddress = IconLineEdit('./images/device.png',
                                             "Server Address", False)
        self.ftpServerAddress.setWhatsThis(
            "Input where you're FTP server is located")
        ftpConfigLayout.addWidget(self.ftpServerAddress.getWidget())
        self.ftpUsername = IconLineEdit('./images/user.png', "FTP Username",
                                        False)
        self.ftpUsername.setWhatsThis(
            "This is your username for the FTP server")
        ftpConfigLayout.addWidget(self.ftpUsername.getWidget())
        self.ftpOsPath = IconLineEdit('./images/device.png',
                                      "OS Directory Path", False)
        self.ftpOsPath.setWhatsThis(
            "Set the directory in your FTP server for where you keep your .tgz OS files so the application can point to them when deploying devices"
        )
        ftpConfigLayout.addWidget(self.ftpOsPath.getWidget())
        self.ftpConfPath = IconLineEdit('./images/device.png',
                                        "Configuration Path", False)
        self.ftpConfPath.setWhatsThis(
            "Set a directory in your FTP server for new .conf files to be pushed to"
        )
        ftpConfigLayout.addWidget(self.ftpConfPath.getWidget())
        self.ftpIniConfPath = IconLineEdit('./images/device.png',
                                           "Initial Config Path", False)
        self.ftpIniConfPath.setWhatsThis(
            "Set the directory in your FTP server for where you keep your .conf files that have yet to be applied to devices so the application can point to them when deploying devices"
        )
        ftpConfigLayout.addWidget(self.ftpIniConfPath.getWidget())
        ftpConfigLabel = QLabel(
            "*This will be used to push and pull config files for your device as you work"
        )
        ftpConfigLabel.setWordWrap(True)
        ftpConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        ftpConfigLayout.addWidget(ftpConfigLabel)
        ftpFrame = QFrame()
        ftpFrame.setObjectName("ftpFrame")
        ftpFrame.setLayout(ftpConfigLayout)
        ftpFrame.setStyleSheet("""
            QFrame#ftpFrame
            {
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        ftpFrame.setContentsMargins(25, 0, 25, 5)
        ftpFrame.setGraphicsEffect(effect)
        ftpHeadingLayout.addWidget(ftpFrame)
        innerContainer.addLayout(ftpHeadingLayout)

        consoleHeadingLayout = QVBoxLayout()
        consoleHeadingLayout.setSpacing(0)
        consoleHeadingLayout.addStretch()
        consoleConfigLabel = ImageLable('./images/hexagon.png',
                                        "Console Server Configuration")
        consoleConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                         """))
        consoleHeadingLayout.addWidget(consoleConfigLabel.getWidget())

        consoleConfigLayout = QVBoxLayout()
        consoleConfigLayout.setObjectName("consoleConfigLayout")
        consoleConfigLayout.setSpacing(146)
        self.consoleAddress = IconLineEdit('./images/device.png',
                                           "Full Console Address", False)
        self.consoleAddress.setWhatsThis(
            "Set the address for your console server")
        consoleConfigLayout.addWidget(self.consoleAddress.getWidget())
        self.consoleUsername = IconLineEdit('./images/user.png', "Username",
                                            False)
        self.consoleUsername.setWhatsThis(
            "Set the username for your console server")
        consoleConfigLayout.addWidget(self.consoleUsername.getWidget())

        consoleConfigLabel = QLabel(
            "*To allow for bulk updates your console server's info will be required here"
        )
        consoleConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        consoleConfigLabel.setWordWrap(True)
        consoleConfigLayout.addWidget(consoleConfigLabel)

        consoleFrame = QFrame()
        consoleFrame.setLayout(consoleConfigLayout)
        consoleFrame.setObjectName("consoleFrame")
        consoleFrame.setStyleSheet("""
            QFrame#consoleFrame
            {
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        consoleFrame.setContentsMargins(25, 0, 25, 5)
        consoleFrame.setGraphicsEffect(effect)
        consoleHeadingLayout.addWidget(consoleFrame)
        innerContainer.addLayout(consoleHeadingLayout)

        datbaseHeadingLayout = QVBoxLayout()
        datbaseHeadingLayout.setSpacing(0)
        datbaseHeadingLayout.addStretch()
        databaseConfigLabel = ImageLable('./images/hexagon.png',
                                         "Database Configuration")
        databaseConfigLabel.setStyleSheet(("""
                                            background-color: rgb(0,188,212);
                                            font-size:16px;
                                            border-top-left-radius: 10px;
                                            border-top-right-radius: 10px;
                                            """))
        datbaseHeadingLayout.addWidget(databaseConfigLabel.getWidget())

        databaseConfigLayout = QVBoxLayout()
        databaseConfigLayout.setObjectName("consoleConfigLayout")
        databaseConfigLayout.setSpacing(138)
        self.databseAddress = IconLineEdit('./images/device.png',
                                           "Full Database Address", False)
        self.databseAddress.setWhatsThis("Set the address for your database")
        databaseConfigLayout.addWidget(self.databseAddress.getWidget())
        self.databseUsername = IconLineEdit('./images/user.png', "Username",
                                            False)
        self.databseUsername.setWhatsThis("Set the username for your database")
        databaseConfigLayout.addWidget(self.databseUsername.getWidget())

        databaseConfigLabel = QLabel(
            "*This database will be used to track updated devices and their config files as you work"
        )
        databaseConfigLabel.setWordWrap(True)
        databaseConfigLabel.setStyleSheet(
            "color: rgb(0,188,212); font-size:16px; background-color: rgb(255,255,255); border: 1px solid white;"
        )
        databaseConfigLayout.addWidget(databaseConfigLabel)

        databaseFrame = QFrame()
        databaseFrame.setLayout(databaseConfigLayout)
        databaseFrame.setObjectName("databaseFrame")
        databaseFrame.setStyleSheet("""
            QFrame#databaseFrame{
            background-color: rgb(255,255,255); border: 1px solid black; font-size:16px;
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px
            }
            """)
        databaseFrame.setContentsMargins(25, 0, 25, 5)
        databaseFrame.setGraphicsEffect(effect)
        datbaseHeadingLayout.addWidget(databaseFrame)
        innerContainer.addLayout(datbaseHeadingLayout)

        innerFrame.setContentsMargins(25, 25, 25, 25)
        innerFrame.setObjectName("innerFrame")
        innerFrame.setStyleSheet(
            "QFrame#innerFrame{ background-color: rgb(96,125,139); border: 1px solid black; font-size:16px} "
        )

        innerVerticalLayout.addLayout(innerContainer)

        bottomLayout = QHBoxLayout()
        bottomLayout.setObjectName("bottomLayout")
        applySettingsButton = QPushButton("Apply Settings")
        applySettingsButton.setStyleSheet(
            "background-color: rgb(0,188,212); font-size:16px;")
        applySettingsButton.clicked.connect(self.applySettings)
        bottomLayout.addWidget(applySettingsButton)

        innerVerticalLayout.addLayout(bottomLayout)
        innerFrame.setLayout(innerVerticalLayout)
        innerFrame.setGraphicsEffect(effect)
        settingsVerticalContainer.addWidget(innerFrame)

        settingsVerticalContainer.addStretch()
        self.layout.setLayout(settingsVerticalContainer)
        self.fillSettingsFields()

    # Set placeholder text
    def fillSettingsFields(self):
        try:
            with open("Settings.xml") as file:
                settingsDict = xmltodict.parse(file.read())

            self.ftpServerAddress.setText(
                settingsDict['Settings']['Ftp-Info']['ftpServerAddress'])
            self.ftpUsername.setText(
                settingsDict['Settings']['Ftp-Info']['ftpUsername'])
            self.ftpOsPath.setText(
                settingsDict['Settings']['Ftp-Info']['ftpOsPath'])
            self.ftpConfPath.setText(
                settingsDict['Settings']['Ftp-Info']['ftpConfPath'])
            self.ftpIniConfPath.setText(
                settingsDict['Settings']['Ftp-Info']['ftpIniConfPath'])

            self.consoleAddress.setText(
                settingsDict['Settings']['Console-Info']['consoleAddress'])
            self.consoleUsername.setText(
                settingsDict['Settings']['Console-Info']['consoleUsername'])

            self.databseAddress.setText(
                settingsDict['Settings']['Database-Info']['databseAddress'])
            self.databseUsername.setText(
                settingsDict['Settings']['Database-Info']['databseUsername'])
            file.close()
            return True
        except:
            return False

    # Check if all settings fiels have been filled
    def allSettingsFieldsFilled(self):
        if len(self.ftpServerAddress.text()) < 1 \
                or len(self.ftpUsername.text()) < 1 \
                or len(self.ftpOsPath.text()) < 1 \
                or len(self.ftpConfPath.text()) < 1 \
                or len(self.ftpIniConfPath.text()) < 1 \
                or len(self.consoleAddress.text()) < 1 \
                or len(self.consoleUsername.text()) < 1 \
                or len(self.databseAddress.text()) < 1 \
                or len(self.databseUsername.text()) < 1:
            return False
        else:
            return True

    # Save settings fields to a xml file
    def applySettings(self):
        if self.allSettingsFieldsFilled():
            try:
                #settings are saved in xml file
                settings_file = open("Settings.xml", "w")
                #ensure paths are "legal"
                osPath = self.makeLegalPath(self.ftpOsPath.text())
                confPath = self.makeLegalPath(self.ftpConfPath.text())
                iniconfPath = self.makeLegalPath(self.ftpIniConfPath.text())

                #construct dict to be translated into xml
                dict = {
                    'Settings': {
                        'Ftp-Info': {
                            'ftpServerAddress': self.ftpServerAddress.text(),
                            'ftpUsername': self.ftpUsername.text(),
                            'ftpOsPath': osPath,
                            'ftpConfPath': confPath,
                            'ftpIniConfPath': iniconfPath
                        },
                        'Console-Info': {
                            'consoleAddress': self.consoleAddress.text(),
                            'consoleUsername': self.consoleUsername.text()
                        },
                        'Database-Info': {
                            'databseAddress': self.databseAddress.text(),
                            'databseUsername': self.databseUsername.text()
                        }
                    }
                }
                #convert dict
                xml = xmltodict.unparse(dict, pretty=True)
                #write dict to file
                settings_file.write(xml)
                settings_file.close()
                #alert user to success
                if self.window.notSetup:
                    heading = "Settings Saved! Restarting in 3...."
                    message = "Your Settings are saved, The programme will restart and reload the changes"
                    self.restart = True
                else:
                    heading = "Settings Saved!"
                    message = "Your Settings are saved"
                secondaryWindows.messageWindow(heading, message, False)
                if self.window.notSetup:
                    time.sleep(3)
                    self.window.close()
                else:
                    self.window.initialiseLauncher()

            #catch any exceptions when writing to file and cope gracefully
            except Exception as e:
                secondaryWindows.messageWindow(
                    "An Error Occured",
                    "There was an error saving your settings the details are as follows: \n "
                    + str(e), True)
        else:
            secondaryWindows.messageWindow(
                "Empty Fields", "Please fill in all fields provided", True)

    #Ensure that the paths being put in are legal (ie. slash at the start and end)
    def makeLegalPath(self, path):
        if "/" in path[0] and "/" in path[len(path) - 1]:
            return path
        elif "/" in path[0]:
            return path + "/"
        elif "/" in path[len(path) - 1]:
            return "/" + path
        else:
            return "/" + path + "/"