Example #1
0
    def login(self):
        myMovie = QMovie("icons/loading.gif")
        myMovie.setScaledSize(QSize(18, 18))
        self.loginMsg.setMovie(myMovie)
        myMovie.start()

        coreLogic = Core()
        args = {}
        args['userid'] = self.userIDTxt.text()
        args['password'] = self.passTxt.text()
        args['entity'] = self.sysChoice.currentText()

        result, msg = coreLogic.login(args)
        if result == True:
            alert = QMessageBox()
            alert.setText('You have successfully logged in!')
            alert.exec_()

            # update parent window = login and session message
            self.parent().checkLogin()
            # close login gui
            self.closingThread = threading.Thread(
                target=self.__closeGui).start()

        else:
            self.loginMsg.setMovie(None)
            self.loginMsg.setText(msg)
            self.loginMsg.setStyleSheet("color:red")
Example #2
0
def main():
    core = Core()

    if len(sys.argv) == 2:
        core.loadEditor(sys.argv[1])
    else:
        print '\033[31mUsage: ./editor.py new_map\033[m'
Example #3
0
File: fdf.py Project: MaxiCom/Fdf
def main():
    core = Core()

    if len(sys.argv) == 2:
        core.loadMap(sys.argv[1])
    else:
        print '\033[31mUsage: ./fdf.py valid_map\033[m'
Example #4
0
def test_failed_connect():
	print("Test a failed connection to a server.")
	core = Core(config)
	try:
		core.connect()
	except SystemExit as iSE:
		if iSE.code > 0:
			assert True
		else:
			assert False
Example #5
0
    def __init__(self, parent=None):
        super(MainFrame, self).__init__(parent)

        # intialize the gui
        self.originalPalette = QApplication.palette()
        self.createTopGroupBox()
        self.createLeftGroupBox()
        self.createMiddleTabWidget()
        self.createProgressBar()
        self.createMenubar()
        self.createToolbar()

        # set gui layout
        mainLayout = QGridLayout()
        mainLayout.setMenuBar(self.leftMenuBar)
        mainLayout.addWidget(self.toolbar, 0, 0, 1, 3)
        mainLayout.addWidget(self.topBox, 1, 0, 1, 3)
        mainLayout.addWidget(self.leftGroupBox, 2, 0)
        mainLayout.addWidget(self.middleGroupBox, 2, 1)
        mainLayout.addWidget(self.progressBar, 3, 0, 1, 3)
        mainLayout.setRowStretch(2, 2)
        mainLayout.setColumnStretch(0, 2)
        mainLayout.setColumnStretch(1, 6)
        self.setLayout(mainLayout)
        self.setWindowTitle("ISPAPI-CLI Tool")

        # set app gui style
        QApplication.setStyle(QStyleFactory.create("Fusion"))

        # create core login instnace
        self.coreLogic = Core()

        # scrap instance
        self.scrap = Scrap()

        # check user session upon start
        self.checkLogin()

        # set focus on command input field
        self.cmdTxt.setFocus()

        # initilaize command line completer
        self.initialiseCommandCompleter()

        # initialize subuser completer
        self.initialiseSubuserCompleter()

        # command to execute
        self.commandToExecute = ""

        # set app icon
        self.setWindowIcon(QIcon(self.getIcon("logo-bgw.jpg")))
Example #6
0
def test_success_connect():
	print("Test a successful connection to a server.")
	test_config = config
	test_config['nick'] = 'MIRTravis'
	test_config['name'] = 'MIRTravis'
	test_config['server'] = 'irc.freenode.org'
	test_config['channels'] = ['#pyrat']
	test_config['sqlite_db'] = 'Travis.db'
	test_config['logging'] = True
	test_config['logging_trim'] = True
	test_config['welcome_new'] = False
	test_config['say_online'] = False
	test_config['owner'] = 'MIRbot'
	test_config['commands'] = ["QUIT :Testing Complete"]

	test_core = Core(test_config)
	try:
		test_core.connect()
		time.sleep(2)

		for connectCommand in test_config['commands']:
			test_core.send(connectCommand)

		test_core.listen()
	except SystemExit as iSE:
		if iSE.code > 0:
			assert False
		else:
			assert True
def run():
    # Destruction of the temporary directory on completion
    with tempfile.TemporaryDirectory() as tmp_dir:

        # Create core object instace
        core = Core(tmp_dir)

        # Checks
        file_checks(core.argv.input_file)
        file_checks(core.argv.metadata)
        path_checks(core.argv.output_folder)
        dependencies_checks()

        # Retrieve ISBN
        json_file = os.path.abspath(core.argv.metadata)
        with open(json_file) as json_data:
            isbn = json.load(json_data)['isbn'].replace('-', '')

        # Create object instaces
        metadata = Metadata(isbn)
        pdf = Pdf(core.argv.input_file, tmp_dir)

        page_ranges = []
        output_file_names = []

        # Iterate over chapters metadata
        for chapter_data in metadata.chapters_data:
            page_ranges.append(chapter_data['page'].split('-'))
            output_file_names.append(chapter_data['DOI'].split('/')[1] +
                                     '.pdf')

        # Merge PDFs
        with concurrent.futures.ProcessPoolExecutor() as executor:
            executor.map(pdf.merge_pdfs, page_ranges, output_file_names)

        # Write metadata
        for output_file_name, chapter_data in zip(output_file_names,
                                                  metadata.chapters_data):
            output_file_path = os.path.join(tmp_dir, output_file_name)
            Metadata.write_metadata(chapter_data, output_file_path)

        # PDFs are temporarely stored in tmp_dir
        if core.argv.compress:
            # Output a zip archive
            core.output_archive(metadata.get_doi_suffix())
        else:
            # Output loose PDFs
            core.output_pdfs()
Example #8
0
cors = CORS(app) # Needed to make us CORS compatible

""" Create the various cogs of the machinery """
parser   = SetupParser()
setup = {}
if not parser.load("conf/setup.conf", setup):
  logging.error('Failed to load "setup.conf"')
  sys.exit(255)

if cmdline.host is not None:
  if (":%d" % cmdline.port) not in setup['OPTIONS']["ux-server"] or not setup['OPTIONS']["ux-server"].endswith('/ux') or not setup['OPTIONS']["ux-server"].endswith('/ux/'):
    logging.warning("You're using hosted UX, make sure \"%s\" points to the right server", setup['OPTIONS']["ux-server"])
    logging.warning('It should use port %d and end with /ux/' % cmdline.port)

remotes = RemoteManager()
core    = Core(setup, remotes)
router  = Router(core)
ssdp    = SSDPHandler(setup['OPTIONS']["ux-server"], cmdline.port)


""" Tracking information """
event_subscribers = []

def notifySubscribers(zone, message):
  for subscriber in event_subscribers:
    if zone is None or core.getRemoteZone(subscriber.remoteId) == zone:
      logging.info("Informing remote %s about \"%s\"", subscriber.remoteId, message)
      subscriber.write_message(message)
    else:
      logging.info("Skipped remote %s", subscriber.remoteId)
Example #9
0
def test_core_functions():
	print("Test some of our vital core functions.")
	test_config = config
	test_config['nick'] = 'MIRTravis'
	test_config['name'] = 'MIRTravis'
	test_config['server'] = 'irc.freenode.org'
	test_config['channels'] = ['#pyrat']
	test_config['sqlite_db'] = 'Travis.db'
	test_config['logging'] = True
	test_config['logging_trim'] = True
	test_config['welcome_new'] = False
	test_config['say_online'] = False
	test_config['owner'] = 'MIRbot'
	test_config['commands'] = [
		"NOTICE #pyrat :Testing Complete: Python %s.%s.%s."
			% sys.version_info[:3],
		"QUIT :Testing Complete."
	]

	test_core = Core(test_config)

	test_core.connect()
	time.sleep(2)

	print("Rejoin channels")
	test_core.rejoin()
	if len(test_core.joined_channels) < 1:
		assert False

	time.sleep(2)

	print("Peform a core config clean.")
	test_core.clean()
	if len(test_core.joined_channels) > 0:
		assert False

	time.sleep(2)

	print("Check modules unloaded.")
	print(len(test_core.loaded_modules))
	if len(test_core.loaded_modules) > 0:
		assert False

	time.sleep(2)

	print("Perform a core config clean with module reload.")
	test_core.clean(True)

	print("Check modules reloaded.")
	print(len(test_core.loaded_modules))
	if len(test_core.loaded_modules) < 1:
		assert False

	time.sleep(2)

	print("Check method function: Found Method")
	if test_core.methodExistsInClass("u_help") == False:
		assert False

	time.sleep(2)

	print("Check method function: Missing Method")
	if test_core.methodExistsInClass("u_missing") == True:
		assert False

	time.sleep(2)

	print("Check method in module function: Found Method")
	if test_core.methodExists("u_afk") == False:
		assert False

	time.sleep(2)

	print("Check method in module function: Missing Method")
	if test_core.methodExists("u_missing_module") == True:
		assert False

	time.sleep(2)

	print("Call a test method")
	if test_core.callMethodInClass("u_pytest") == False:
		assert False

	time.sleep(2)

	print("Get Variable from SQLite database")
	test_salt = test_core.get_variable('salt')
	if test_salt == False or test_salt == None:
		assert False
	else:
		print(test_salt)

	time.sleep(2)

	print("Set Variable to SQLite database")
	test_var = test_core.set_variable('travis', test_core.unixtime())
	test_var_read = test_core.get_variable('travis', False)
	if test_var == False or test_var_read == False:
		assert False
	else:
		print(test_var_read)

	time.sleep(2)
	test_core.connect()

	for connectCommand in test_config['commands']:
		test_core.send(connectCommand)

	try:
		test_core.listen()
	except SystemExit as iSE:
		if iSE.code > 0:
			assert False
		else:
			assert True
Example #10
0
class MainFrame(QWidget):
    def __init__(self, parent=None):
        super(MainFrame, self).__init__(parent)

        # intialize the gui
        self.originalPalette = QApplication.palette()
        self.createTopGroupBox()
        self.createLeftGroupBox()
        self.createMiddleTabWidget()
        self.createProgressBar()
        self.createMenubar()
        self.createToolbar()

        # set gui layout
        mainLayout = QGridLayout()
        mainLayout.setMenuBar(self.menuBar)
        mainLayout.addWidget(self.toolbar, 0, 0, 1, 3)
        mainLayout.addWidget(self.topBox, 1, 0, 1, 3)
        mainLayout.addWidget(self.leftGroupBox, 2, 0)
        mainLayout.addWidget(self.middleGroupBox, 2, 1)
        mainLayout.addWidget(self.progressBar, 3, 0, 1, 3)
        mainLayout.setRowStretch(2, 2)
        mainLayout.setColumnStretch(0, 2)
        mainLayout.setColumnStretch(1, 6)
        self.setLayout(mainLayout)
        self.setWindowTitle("ISPAPI-CLI Tool")

        # set app gui style
        QApplication.setStyle(QStyleFactory.create('Fusion'))

        # create core login instnace
        self.coreLogic = Core()

        # check user session upon start
        self.checkLogin()

        # set focus on command input field
        self.cmdTxt.setFocus()

        # initilaize command line completer
        self.initialiseCommandCompleter()

        # command to execute
        self.commandToExecute = ''

        # set app icon
        self.setWindowIcon(QIcon(self.getIcon("logo-bgw.jpg")))

    def checkLogin(self):
        result = self.coreLogic.checkSession()
        if result == 'valid':
            self.sessionTime.setText("Your session is valid. ")
            self.sessionTime.setStyleSheet("color:green")
            self.loginBtn.setIcon(QIcon(self.getIcon("logout.png")))
            self.loginBtn.setText('Logout')
            self.loginBtn.clicked.connect(self.logout)
            self.reconnectBtnAction(self.loginBtn.clicked, self.logout)
            # enable gui
            self.disableEnableGui('enable')

        else:
            self.sessionTime.setText("Session expired! ")
            self.sessionTime.setStyleSheet("color:red")
            self.loginBtn.setIcon(QIcon(self.getIcon("login.png")))
            self.loginBtn.setText('Login')
            self.reconnectBtnAction(self.loginBtn.clicked,
                                    self.openLoginWindow)
            # diable gui
            self.disableEnableGui('disable')

    def reconnectBtnAction(self, signal, newhandler=None, oldhandler=None):
        """
        Reconnecting login btn action to either login or logout
        """
        while True:
            try:
                if oldhandler is not None:
                    signal.disconnect(oldhandler)
                else:
                    signal.disconnect()
            except TypeError:
                break
        if newhandler is not None:
            signal.connect(newhandler)

    def logout(self):
        msg = self.coreLogic.logout()
        alert = QMessageBox()
        alert.setText(msg)
        alert.exec_()
        # update login
        self.checkLogin()

    def disableEnableGui(self, status=None):
        """
        If session is expired then disable gui
        """
        if status is not None:
            if status == 'enable':
                self.leftGroupBox.setEnabled(True)
                self.topBox.setEnabled(True)
                # focus on command input field
                self.cmdTxt.setFocus()
            else:
                self.leftGroupBox.setDisabled(True)
                self.topBox.setDisabled(True)
        else:
            pass

    def advanceProgressBar(self):
        curVal = self.progressBar.value()
        if curVal <= 99:
            self.progressBar.setValue(curVal + 1)
        else:
            self.timer.stop()
            self.progressBar.setValue(0)

    def createProgressBar(self, ):
        self.progressBar = QProgressBar()
        self.progressBar.setRange(0, 100)
        self.progressBar.setValue(0)
        self.progressBar.setMaximumHeight(5)
        self.progressBar.setTextVisible(False)

        # create a timer for the progress bar

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.advanceProgressBar)

        # call timer with speed of 5
        self.progressBarSpeed(5)

    def progressBarSpeed(self, speed):
        self.timer.start(speed)

    def onMyToolBarButtonClick(self, s):
        print("click", s)

    def executeCommand(self):
        # start progressbar
        self.progressBarSpeed(5)
        # get args from the GUI
        commandToExecute = self.commandText.toPlainText()
        if commandToExecute.startswith('-', 0, 1):
            original_args = commandToExecute.splitlines()
        else:
            original_args = ("--" + commandToExecute).splitlines()
        original_args = ' '.join(original_args)
        # remove extra spaces around the = cases are ' =', '= ', ' = '
        original_args = original_args.replace(" = ", "=")
        original_args = original_args.replace(" =", "=")
        original_args = original_args.replace("= ", "=")
        splitted_args = original_args.split()
        # intialize the parser
        core_obj = self.coreLogic
        parser = core_obj.initParser()
        # overwrite defualt error function with our local function to show on the GUI
        parser.error = self.errorFunction

        try:
            args = vars(parser.parse_args(splitted_args))
            reminderargs = args['args']
            # parse command args
            result, data = core_obj.parseArgs(args)
            # case gui started
            if result == 'gui':
                self.plainResponse.setText("GUI already started")
            # case of help command
            elif result == 'help':
                helpText = ''
                preHelp = textwrap.dedent('''\
                    ISPAPI - Commandline Tool
                    ------------------------------------------------------------
                    The tool can be used in two modes:
                    - By using '=' sign e.g. --command=QueryDomainList limit=5
                    - By using spaces e.g. --command QueryDomainList limit 5
                    ------------------------------------------------------------

                    ''')
                # redirect stdout
                stringio = StringIO()
                previous_stdout = sys.stdout
                sys.stdout = stringio

                # trigger parser help
                parser.print_help()

                # set back stdout
                sys.stdout = previous_stdout
                stdoutValue = stringio.getvalue()

                # show output on the GUI
                helpText = preHelp + stdoutValue
                self.plainResponse.setText(helpText)

            elif result == 'cmd':
                # append reminder args with the command
                params_list = core_obj.parseParameters(reminderargs)
                cmd = data
                # add them to data which is the command list
                cmd.update(params_list)
                self.response = core_obj.request(cmd)
                # set reult values to gui
                self.populateResults(self.response)

            # case update commands
            elif result == 'update':
                # create scrap object
                # scrap = Scrap()
                msg = "Please run this command in the terminal, use: ./ispapicli --update"
                self.plainResponse.setText(msg)
            else:
                self.plainResponse.setText(data)

            # 1 end the progress bar
            # self.progressBarSpeed(5)
            # 2
            # check user session, in case of sesssion is expired
            self.checkLogin()
        except Exception as e:
            self.plainResponse.setText("Command failed due to: " + str(e))

    def errorFunction(self, message):
        self.plainResponse.setText('An error happend: ' + message + '\n')

    def updateCommandView(self, e):
        cmdTxt = self.cmdTxt.text()
        # check if the command is related to other actions
        if cmdTxt.startswith('-', 0, 1):
            self.commandText.setText(cmdTxt)
            self.commandToExecute = cmdTxt
            return 0
        else:
            args = 'command '
            args += cmdTxt
            args = args.split()
            # clean extra spaces, leave only single spaces among commands
            original_args = ' '.join(args)
            # remove extra spaces around the = cases are ' =', '= ', ' = '
            original_args = original_args.replace(" = ", "=")
            original_args = original_args.replace(" =", "=")
            original_args = original_args.replace("= ", "=")
            # split args in an array
            parameters = original_args.split()
            # split commands if = used
            params_len = len(parameters)
            params = {}
            try:
                if params_len > 1:
                    i = 0
                    while i < params_len:
                        if '=' in parameters[i]:
                            key, value = parameters[i].split('=')
                            params[key] = value
                        else:
                            key = parameters[i]
                            i += 1
                            value = parameters[i]
                            params[key] = value
                        i += 1
                    self.commandText.setText()
            except Exception as e:
                pass
            commandView = "\n".join(
                ("{}={}".format(*i) for i in params.items()))
            self.commandText.setText(commandView)
            self.commandToExecute = '--' + commandView

    def createToolbar(self):
        self.toolbar = QToolBar("My main toolbar")
        self.toolbar.setIconSize(QSize(20, 20))
        saveAction = QAction(QIcon(self.getIcon("save.png")),
                             "Save results to a file", self)
        saveAction.triggered.connect(lambda: self.saveCommandToFile())

        copyAction = QAction(QIcon(self.getIcon("copy.png")),
                             "Copy the results to clipboard", self)
        copyAction.triggered.connect(self.copyToClipboard)

        helpAction = QAction(QIcon(self.getIcon("help.png")),
                             "See help documentation", self)
        helpAction.triggered.connect(self.showHelp)

        openAction = QAction(QIcon(self.getIcon("new.png")),
                             "Open another window", self)

        self.sessionTime = QLabel("Checking your session... ")
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        self.loginBtn = QPushButton("Login")
        self.loginBtn.setIcon(QIcon(self.getIcon("login.png")))
        self.loginBtn.setStyleSheet("padding: 2px; padding-left: 6px")
        self.loginBtn.setIconSize(QSize(12, 12))
        self.loginBtn.setLayoutDirection(Qt.RightToLeft)

        seperator = QAction(self)
        seperator.setSeparator(True)
        # create a new window -TODO
        # self.toolbar.addAction(openAction)
        self.toolbar.addAction(saveAction)
        self.toolbar.addAction(copyAction)
        self.toolbar.addAction(seperator)
        self.toolbar.addAction(helpAction)
        self.toolbar.addWidget(spacer)
        self.toolbar.addWidget(self.sessionTime)
        self.toolbar.addWidget(self.loginBtn)

    def createMenubar(self):

        self.menuBar = QMenuBar()
        file = self.menuBar.addMenu("File")
        new = QAction("New window", self)
        new.setShortcut("Ctrl+n")
        save = QAction("Save to file", self)
        save.setShortcut("Ctrl+S")
        quit = QAction("Quit", self)
        quit.setShortcut("Ctrl+q")

        # create a new window - TODO
        # file.addAction(new)
        file.addAction(save)
        file.addAction(quit)

        edit = self.menuBar.addMenu("Edit")
        copy = QAction("Copy", self)
        copy.setShortcut("Ctrl+c")

        edit.addAction(copy)

        help = self.menuBar.addMenu("Help")
        help.addAction("About ISPAPI tool")
        help.addAction("How to start?")

        file.triggered[QAction].connect(self.menuBarActions)
        edit.triggered[QAction].connect(self.menuBarActions)
        help.triggered[QAction].connect(self.menuBarActions)

    def createTopGroupBox(self):
        self.topBox = QGroupBox((""))
        executeBtn = QPushButton("Execute")
        executeBtn.setIcon(QIcon(self.getIcon("execute.png")))
        executeBtn.clicked.connect(self.executeCommand)
        executeBtn.setIconSize(QSize(14, 14))
        # executeBtn.setLayoutDirection(Qt.RightToLeft)

        clearBtn = QPushButton("Clear")
        clearBtn.setIcon(QIcon(self.getIcon("cross.png")))
        clearBtn.setIconSize(QSize(14, 14))
        # clearBtn.setLayoutDirection(Qt.RightToLeft)
        clearBtn.clicked.connect(self.__clearCMDfield)

        self.cmdTxt = QLineEdit()
        self.cmdTxt.setPlaceholderText("Enter command here...")
        self.cmdTxt.textEdited.connect(self.updateCommandView)
        #qSpaceEvent = QKeyEvent(QEvent.KeyPress, Qt.Key_Backspace, Qt.NoModifier)
        # self.cmdTxt.keyPressEvent(qSpaceEvent)
        self.cmdTxt.installEventFilter(self)
        self.cmdTxt.returnPressed.connect(self.executeCommand)

        # set command completer
        self.completer = QCompleter()
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.cmdTxt.setCompleter(self.completer)

        self.minParameter = QLabel(self)
        self.minParameter.setText('Min parameters: ')
        self.minParameter.setStyleSheet("color:gray")
        f = QFont("Arial", 9)
        self.minParameter.setFont(f)

        gridLayout = QGridLayout()
        gridLayout.addWidget(self.cmdTxt, 0, 1, 1, 1)
        gridLayout.addWidget(executeBtn, 0, 2, 1, 1)
        gridLayout.addWidget(clearBtn, 0, 3, 1, 1)
        gridLayout.addWidget(self.minParameter, 1, 1, 1, 1)
        gridLayout.setContentsMargins(5, 0, 5, 10)
        self.topLayout = gridLayout
        self.topBox.setLayout(gridLayout)

    def createLeftGroupBox(self):
        self.leftGroupBox = QGroupBox("Command extracted")
        self.commandText = QTextEdit()
        self.commandText.setPlaceholderText(
            "Extracted command will be shown here")

        tab2hbox = QHBoxLayout()
        tab2hbox.setContentsMargins(5, 5, 5, 5)
        tab2hbox.addWidget(self.commandText)

        self.leftGroupBox.setLayout(tab2hbox)

    def createMiddleTabWidget(self):
        self.middleGroupBox = QGroupBox("Results")
        middleTabWidget = QTabWidget()
        middleTabWidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Ignored)

        tab1 = QWidget()
        self.plainResponse = QTextEdit()
        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(5, 5, 5, 5)
        tab1hbox.addWidget(self.plainResponse)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        self.tableResponse = QTableWidget(1, 2)
        self.tableResponse.setHorizontalHeaderLabels(['Property', 'Value'])
        self.tableResponse.horizontalHeader().setStretchLastSection(True)
        tableLayout = QGridLayout()
        tableLayout.setContentsMargins(5, 5, 5, 5)
        tableLayout.addWidget(self.tableResponse, 0, 0)
        tab2.setLayout(tableLayout)

        tab3 = QWidget()
        self.listResponse = QTextEdit()
        tab3hbox = QHBoxLayout()
        tab3hbox.addWidget(self.listResponse)
        tab3.setLayout(tab3hbox)

        middleTabWidget.addTab(tab1, "Plain")
        middleTabWidget.addTab(tab2, "Properties")
        middleTabWidget.addTab(tab3, 'List')

        layout = QGridLayout()
        layout.addWidget(middleTabWidget, 0, 0, 1, 1)

        self.middleGroupBox.setLayout(layout)

    def openLoginWindow(self):
        """
        Start login window
        """
        loginGui = LoginWindow(self)
        loginGui.startGui()

    def menuBarActions(self, q):
        action = q.text()
        if action == 'New Window':
            pass
        if action == 'Save to file':
            self.saveCommandToFile()
        if action == 'Quit':
            self.closeApplication()
        if action == 'Copy':
            self.copyToClipboard()
        if action == 'Help':
            self.showHelp()
        if action == 'About ISPAPI tool':
            self.showAbout()
        if action == 'How to start?':
            self.showHelp()

    def closeApplication(self):
        print("exiting")
        sys.exit()

    def startNewWindow(self):
        app = QApplication(sys.argv)
        appGui = MainFrame()
        appGui.startGui()
        sys.exit(app.exec_())

    def startGui(self):
        geo = QDesktopWidget().availableGeometry()

        screenWidth = geo.width()
        screenHeight = geo.height()
        width = int(screenWidth * 0.5)
        height = int(screenHeight * 0.5)
        self.resize(width, height)

        frameGeo = self.frameGeometry()
        cp = geo.center()
        frameGeo.moveCenter(cp)
        self.move(frameGeo.topLeft())

        # start gui
        self.show()

    def initialiseCommandCompleter(self):
        model = QStringListModel()
        # get all possible autocomplete strings
        stringsSuggestion = []
        stringsSuggestion = (self.coreLogic.getCommandList()).splitlines()
        # set suggestion to the model
        model.setStringList(stringsSuggestion)
        # set model to the completer
        self.completer.setModel(model)

    def __clearCMDfield(self):
        self.cmdTxt.clear()
        self.cmdTxt.setFocus(True)

    def populateResults(self, response):
        # get reulsts
        plainResult = response.getPlain()
        listResult = response.getListHash()

        # delete any previous content of the list
        self.listResponse.setText('')

        # set plain results
        self.plainResponse.setText(plainResult)

        # set properties and list
        resultLists = listResult['LIST']
        counter = 0
        for row in resultLists:
            for col in row:
                counter += 1
        # set the number of rows
        self.tableResponse.setRowCount(counter)

        # populate the table
        rownumber = 0
        for row in resultLists:
            for i, (key, value) in enumerate(row.items()):
                keyWidget = QTableWidgetItem(key)
                valueWidget = QTableWidgetItem(value)
                self.tableResponse.setItem(rownumber, 0, keyWidget)
                self.tableResponse.setItem(rownumber, 1, valueWidget)
                # update the list
                if key not in ('TOTAL', 'FIRST', 'LAST', 'LIMIT', 'COUNT'):
                    self.listResponse.append(value)
                # incerate rownumber
                rownumber += 1
        # order table content
        self.tableResponse.sortItems(Qt.AscendingOrder)

    def saveCommandToFile(self):
        try:
            textToWrite = self.commandAndResponsePlain()
            options = QFileDialog.Options()
            # options |= QFileDialog.DontUseNativeDialog # Qt's builtin File Dialogue
            fileName, _ = QFileDialog.getSaveFileName(self,
                                                      "Open",
                                                      "report.txt",
                                                      "All Files (*.*)",
                                                      options=options)
            if fileName:
                try:
                    with open(fileName, 'w') as file:
                        file.write(textToWrite)
                    alert = QMessageBox()
                    alert.setText("'" + fileName +
                                  "' \n\nFile Saved Successfully!")
                    alert.setIcon(QMessageBox.Information)
                    alert.exec_()
                except Exception as e:
                    alert = QMessageBox()
                    alert.setIcon(QMessageBox.Critical)
                    alert.setText("Couldn't save the file due to: " + str(e))
                    alert.exec_()
        except Exception as e:
            alert = QMessageBox()
            alert.setIcon(QMessageBox.Critical)
            alert.setText("Request a command first!")
            alert.setWindowTitle("Error")
            alert.exec_()

    def commandAndResponsePlain(self):
        result = self.plainResponse.toPlainText()
        command = self.response.getCommandPlain()
        textToWrite = command + '\n' + result
        return textToWrite

    def copyToClipboard(self):
        try:
            newText = self.commandAndResponsePlain()
            clipboard = QApplication.clipboard()
            clipboard.setText(newText)
        except Exception as e:
            print(e)
            pass  # in the case where there is not command requested

    def showHelp(self):
        box = QMessageBox(self)
        msg = """<p align='center'>
        <b style='font-size:20px'>Help Information</b>. <br><br><br>
        This window provides a simple help view, more detailed help can be found at: 
        <a href="https://hexonet.github.io/ispapicli/">ISPAPI CLI Tool Documentation</a>
        <br><br>
        Quick start:
        <br>
        To show help, type the command: -h | --help
        <br>
        From there you will find all information about using the command line in both the GUI and terminal
        <br><br>
        <span style="color:orange">Note</span>: Commands executed in terminal are similar to commands used in the GUI, except for the "--update" command which is only possible to trigger in the terminal
        <br><br><br>
        Copyright 2020 @Hexonet
        <br><br>
        </p>
        """
        box.setStandardButtons(QMessageBox.Ok)
        box.setIcon(QMessageBox.Information)
        box.setWindowTitle("Help")
        box.setText(msg)
        box.show()

    def showAbout(self):

        box = QMessageBox(self)
        msg = """<p align='center'>
        <b style='font-size:20px'>ISPAPI Tool</b>. <br><br><br>
        Version: %s <br><br>
        A simple command line interface to connect you to your account on Hexonet
        <br><br>
        Technical Support:
        <br>
        Email: [email protected] 
        <br>
        Website: <a href="https://hexonet.github.io/ispapicli/">ISPAPI CLI Tool</a>
        <br><br><br>
        Copyright 2020 @Hexonet
        <br><br>
        </p>
        """

        box.setStandardButtons(QMessageBox.Ok)
        # box.setIcon(QMessageBox.Information)
        box.setWindowTitle("About")
        box.setText(msg % __version__)
        box.show()

    def eventFilter(self, source, event):

        # this function to handle autocomplete for command line
        if (event.type() == QEvent.KeyRelease and source is self.cmdTxt):
            if event.key() == Qt.Key_Space:
                # show min paramters suggestions
                try:
                    cmd = self.cmdTxt.text()
                    m = re.match('^(\w+)\s$', cmd)
                    if m:
                        minParams = self.coreLogic.getMinParameters(
                            cmd.strip())
                        if len(minParams) > 0:
                            minParamsLabel = ', '.join(minParams)
                            minParamsInput = '= '.join(minParams)
                            cursorPosition = len(
                                self.cmdTxt.text() +
                                minParams[0]) + 1  # for the '=' char
                            self.cmdTxt.setText(cmd + minParamsInput + '=')
                            self.minParameter.setText('Min parameters: ' +
                                                      minParamsLabel)
                            self.cmdTxt.setCursorPosition(cursorPosition)
                        else:
                            self.minParameter.setText('Min parameters:')
                except Exception as e:
                    print(e)
        # must return bool value
        return super(MainFrame, self).eventFilter(source, event)

    def getIcon(self, iconName):
        ##
        # This function checks if the app is executable or in development and return the path

        if getattr(sys, 'frozen', False):
            self.absolute_dirpath = os.path.dirname(sys.executable)
        elif __file__:
            self.absolute_dirpath = os.path.dirname(__file__)

        path = self.command_path = os.path.join(self.absolute_dirpath,
                                                '../icons/' + iconName)
        return path
Example #11
0
class MainFrame(QWidget):

    BATCH_COMMANDLINE_ID = 300
    BATCH_PARAMETER_ID = 400
    BATCH_LIST_ID = 500
    BATCH_PARAMS = [
        "Select",
        "CONTACT",
        "DNSZONE",
        "DOMAIN",
        "DOMAINAUTH",
        "HOST",
        "NAMESERVER",
        "OBJECTID",
        "SSLCERTID",
    ]

    def __init__(self, parent=None):
        super(MainFrame, self).__init__(parent)

        # intialize the gui
        self.originalPalette = QApplication.palette()
        self.createTopGroupBox()
        self.createLeftGroupBox()
        self.createMiddleTabWidget()
        self.createProgressBar()
        self.createMenubar()
        self.createToolbar()

        # set gui layout
        mainLayout = QGridLayout()
        mainLayout.setMenuBar(self.leftMenuBar)
        mainLayout.addWidget(self.toolbar, 0, 0, 1, 3)
        mainLayout.addWidget(self.topBox, 1, 0, 1, 3)
        mainLayout.addWidget(self.leftGroupBox, 2, 0)
        mainLayout.addWidget(self.middleGroupBox, 2, 1)
        mainLayout.addWidget(self.progressBar, 3, 0, 1, 3)
        mainLayout.setRowStretch(2, 2)
        mainLayout.setColumnStretch(0, 2)
        mainLayout.setColumnStretch(1, 6)
        self.setLayout(mainLayout)
        self.setWindowTitle("ISPAPI-CLI Tool")

        # set app gui style
        QApplication.setStyle(QStyleFactory.create("Fusion"))

        # create core login instnace
        self.coreLogic = Core()

        # scrap instance
        self.scrap = Scrap()

        # check user session upon start
        self.checkLogin()

        # set focus on command input field
        self.cmdTxt.setFocus()

        # initilaize command line completer
        self.initialiseCommandCompleter()

        # initialize subuser completer
        self.initialiseSubuserCompleter()

        # command to execute
        self.commandToExecute = ""

        # set app icon
        self.setWindowIcon(QIcon(self.getIcon("logo-bgw.jpg")))

    def checkLogin(self):
        result = self.coreLogic.checkSession()
        if result == "valid":
            self.sessionTime.setText("Your session is valid. ")
            self.sessionTime.setStyleSheet("color:green")
            self.loginBtn.setIcon(QIcon(self.getIcon("logout.png")))
            self.loginBtn.setText("Logout")
            self.loginBtn.clicked.connect(self.logout)
            self.reconnectBtnAction(self.loginBtn.clicked, self.logout)
            # enable gui
            self.disableEnableGui("enable")

        else:
            self.sessionTime.setText("Session expired! ")
            self.sessionTime.setStyleSheet("color:red")
            self.loginBtn.setIcon(QIcon(self.getIcon("login.png")))
            self.loginBtn.setText("Login")
            self.reconnectBtnAction(self.loginBtn.clicked,
                                    self.openLoginWindow)
            # diable gui
            self.disableEnableGui("disable")

    def reconnectBtnAction(self, signal, newhandler=None, oldhandler=None):
        """
        Reconnecting login btn action to either login or logout
        """
        while True:
            try:
                if oldhandler is not None:
                    signal.disconnect(oldhandler)
                else:
                    signal.disconnect()
            except TypeError:
                break
        if newhandler is not None:
            signal.connect(newhandler)

    def logout(self):
        msg = self.coreLogic.logout()
        alert = QMessageBox()
        alert.setText(msg)
        alert.exec_()
        # update login
        self.checkLogin()

    def disableEnableGui(self, status=None):
        """
        If session is expired then disable gui
        """
        if status is not None:
            if status == "enable":
                self.leftGroupBox.setEnabled(True)
                self.topBox.setEnabled(True)
                # focus on command input field
                self.cmdTxt.setFocus()
            else:
                self.leftGroupBox.setDisabled(True)
                self.topBox.setDisabled(True)
        else:
            pass

    def advanceProgressBar(self):
        curVal = self.progressBar.value()
        if curVal <= 99:
            self.progressBar.setValue(curVal + 1)
        else:
            self.timer.stop()
            self.progressBar.setValue(0)

    def createProgressBar(self, ):
        self.progressBar = QProgressBar()
        self.progressBar.setRange(0, 100)
        self.progressBar.setValue(0)
        self.progressBar.setMaximumHeight(5)
        self.progressBar.setTextVisible(False)

        # create a timer for the progress bar

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.advanceProgressBar)

        # call timer with speed of 5
        self.progressBarSpeed(5)

    def progressBarSpeed(self, speed):
        self.timer.start(speed)

    def onMyToolBarButtonClick(self, s):
        print("click", s)

    def executeCommand(self):
        # start progressbar
        self.progressBarSpeed(5)
        # get args from the GUI
        commandToExecute = self.commandText.toPlainText().lower()
        if commandToExecute.startswith("-", 0, 1):
            original_args = commandToExecute.splitlines()
        else:
            original_args = ("--" + commandToExecute).splitlines()
        original_args = " ".join(original_args)
        # remove extra spaces around the = cases are ' =', '= ', ' = '
        original_args = original_args.replace(" = ", "=")
        original_args = original_args.replace(" =", "=")
        original_args = original_args.replace("= ", "=")
        splitted_args = original_args.split()
        # intialize the parser
        core_obj = self.coreLogic
        parser = core_obj.initParser()
        # overwrite defualt error function with our local function to show on the GUI
        parser.error = self.errorFunction

        try:
            args = vars(parser.parse_args(splitted_args))
            reminderargs = args["args"]
            # parse command args
            result, data = core_obj.parseArgs(args)
            # case gui started
            if result == "gui":
                self.plainResponse.setText("GUI already started")
            # case of help command
            elif result == "help":
                helpText = ""
                preHelp = textwrap.dedent("""\
                    ISPAPI - Commandline Tool
                    ------------------------------------------------------------
                    The tool can be used in two modes:
                    - By using '=' sign e.g. --command=QueryDomainList limit=5
                    - By using spaces e.g. --command QueryDomainList limit 5
                    ------------------------------------------------------------

                    """)
                # redirect stdout
                stringio = StringIO()
                previous_stdout = sys.stdout
                sys.stdout = stringio

                # trigger parser help
                parser.print_help()

                # set back stdout
                sys.stdout = previous_stdout
                stdoutValue = stringio.getvalue()

                # show output on the GUI
                helpText = preHelp + stdoutValue
                self.plainResponse.setText(helpText)

            elif result == "cmd":
                # append reminder args with the command
                params_list = core_obj.parseParameters(reminderargs)
                cmd = data
                # add them to data which is the command list
                cmd.update(params_list)
                # check if subuser
                subuser = self.subuser.text()
                if len(subuser) > 1:
                    core_obj.cl.setUserView(subuser)  # set subuser
                else:
                    core_obj.cl.resetUserView()  # remove subuser
                # check for batches
                batch_param = self.batchParams.currentText()
                batch_params_list = self.batchParamsList.toPlainText()
                if batch_param != "Select" and batch_params_list != "":
                    lines = batch_params_list.split("\n")
                    for line in lines:
                        if line != "":
                            cmd[batch_param] = line
                            # request call
                            self.response = core_obj.request(cmd)
                            # set reult values to gui
                            self.populateResults(self.response)
                else:
                    # request call
                    self.response = core_obj.request(cmd)
                    # set reult values to gui
                    self.populateResults(self.response)

            # case update commands
            elif result == "update":
                # create scrap object
                # msg = "Please run this command in the terminal, use: ./ispapicli --update"
                # self.plainResponse.setText(msg)
                self.showUpdating()
            else:
                self.plainResponse.setText(data)

            # 1 end the progress bar
            # self.progressBarSpeed(5)
            # 2
            # check user session, in case of sesssion is expired
            self.checkLogin()
        except Exception as e:
            self.plainResponse.setText("Command failed due to: " + str(e))

    def errorFunction(self, message):
        self.plainResponse.setText("An error happend: " + message + "\n")

    def updateCommandView(self, e):
        cmdTxt = self.cmdTxt.text()
        # check if the command is related to other actions
        if cmdTxt.startswith("-", 0, 1):
            self.commandText.setText(cmdTxt)
            self.commandToExecute = cmdTxt
            return 0
        else:
            args = "command "
            args += cmdTxt
            args = args.split()
            # clean extra spaces, leave only single spaces among commands
            original_args = " ".join(args)
            # remove extra spaces around the = cases are ' =', '= ', ' = '
            original_args = original_args.replace(" = ", "=")
            original_args = original_args.replace(" =", "=")
            original_args = original_args.replace("= ", "=")
            # split args in an array
            parameters = original_args.split()
            # split commands if = used
            params_len = len(parameters)
            params = {}
            try:
                if params_len > 1:
                    i = 0
                    while i < params_len:
                        if "=" in parameters[i]:
                            key, value = parameters[i].split("=")
                            params[key] = value
                        else:
                            key = parameters[i]
                            i += 1
                            value = parameters[i]
                            params[key] = value
                        i += 1
                    self.commandText.setText()
            except Exception as e:
                pass
            commandView = "\n".join(
                ("{}={}".format(*i) for i in params.items()))
            self.commandText.setText(commandView)
            self.commandToExecute = "--" + commandView

    def createToolbar(self):
        self.toolbar = QToolBar("My main toolbar")
        self.toolbar.setIconSize(QSize(20, 20))
        saveAction = QAction(QIcon(self.getIcon("save.png")),
                             "Save results to a file", self)
        saveAction.triggered.connect(lambda: self.saveCommandToFile())

        copyAction = QAction(QIcon(self.getIcon("copy.png")),
                             "Copy the results to clipboard", self)
        copyAction.triggered.connect(self.copyToClipboard)

        helpAction = QAction(QIcon(self.getIcon("help.png")),
                             "See help documentation", self)
        helpAction.triggered.connect(self.showHelp)

        updateAction = QAction(QIcon(self.getIcon("refresh.png")),
                               "Update the tool API's commands", self)
        updateAction.triggered.connect(self.showUpdating)

        updateToolAction = QAction(QIcon(self.getIcon("direct-download.png")),
                                   "Update the tool", self)
        updateToolAction.triggered.connect(self.checkForUpdate)

        self.sessionTime = QLabel("Checking your session... ")
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        self.loginBtn = QPushButton("Login")
        self.loginBtn.setIcon(QIcon(self.getIcon("login.png")))
        self.loginBtn.setStyleSheet("padding: 2px; padding-left: 6px")
        self.loginBtn.setIconSize(QSize(12, 12))
        self.loginBtn.setLayoutDirection(Qt.RightToLeft)

        seperator = QAction(self)
        seperator.setSeparator(True)
        # create a new window -TODO
        # self.toolbar.addAction(openAction)
        self.toolbar.addAction(saveAction)
        self.toolbar.addAction(seperator)
        self.toolbar.addAction(copyAction)
        self.toolbar.addAction(seperator)
        self.toolbar.addAction(helpAction)
        self.toolbar.addAction(seperator)
        self.toolbar.addAction(updateAction)
        self.toolbar.addAction(updateToolAction)
        self.toolbar.addWidget(spacer)
        self.toolbar.addWidget(self.sessionTime)
        self.toolbar.addWidget(self.loginBtn)

    def createMenubar(self):
        self.rightMenuBar = QMenuBar()
        self.currentVersion = QLabel(__version__)

        self.leftMenuBar = QMenuBar()
        file = self.leftMenuBar.addMenu("File")
        new = QAction("New window", self)
        new.setShortcut("Ctrl+n")
        save = QAction("Save to file", self)
        save.setShortcut("Ctrl+S")
        quit = QAction("Quit", self)
        quit.setShortcut("Ctrl+q")

        # create a new window - TODO
        # file.addAction(new)
        file.addAction(save)
        file.addAction(quit)

        edit = self.leftMenuBar.addMenu("Edit")
        copy = QAction("Copy", self)
        copy.setShortcut("Ctrl+c")

        edit.addAction(copy)

        help = self.leftMenuBar.addMenu("Help")
        help.addAction("About ISPAPI tool")
        help.addAction("How to start?")

        file.triggered[QAction].connect(self.menuBarActions)
        edit.triggered[QAction].connect(self.menuBarActions)
        help.triggered[QAction].connect(self.menuBarActions)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        check = QAction("Current version: " + __version__, self)
        self.rightMenuBar.addAction(check)

        self.leftMenuBar.setCornerWidget(self.rightMenuBar)
        self.leftMenuBar.setStyleSheet("padding: 0px 0px 0px 5px")

    def createTopGroupBox(self):
        self.topBox = QGroupBox((""))
        executeBtn = QPushButton("Execute")
        executeBtn.setIcon(QIcon(self.getIcon("execute.png")))
        executeBtn.clicked.connect(self.executeCommand)
        executeBtn.setIconSize(QSize(14, 14))
        # executeBtn.setLayoutDirection(Qt.RightToLeft)

        clearBtn = QPushButton("Clear")
        clearBtn.setIcon(QIcon(self.getIcon("cross.png")))
        clearBtn.setIconSize(QSize(14, 14))
        # clearBtn.setLayoutDirection(Qt.RightToLeft)
        clearBtn.clicked.connect(self.__clearCMDfield)

        self.cmdTxt = QLineEdit()
        self.cmdTxt.setPlaceholderText("Enter command here...")
        self.cmdTxt.textEdited.connect(self.updateCommandView)
        # qSpaceEvent = QKeyEvent(QEvent.KeyPress, Qt.Key_Backspace, Qt.NoModifier)
        # self.cmdTxt.keyPressEvent(qSpaceEvent)
        self.cmdTxt.installEventFilter(self)
        self.cmdTxt.returnPressed.connect(self.executeCommand)

        # set command completer
        self.completer = QCompleter()
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.cmdTxt.setCompleter(self.completer)

        # subuser
        self.subuser = QLineEdit()
        self.subuser.setPlaceholderText("Type a subuser")

        self.subuser.returnPressed.connect(self.executeCommand)

        # set command completer
        self.subUsercompleter = QCompleter()
        self.subUsercompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.subuser.setCompleter(self.subUsercompleter)

        self.minParameter = QLabel(self)
        self.minParameter.setText("Min parameters: ")
        self.minParameter.setStyleSheet("color:gray")
        f = QFont("Arial", 9)
        self.minParameter.setFont(f)

        gridLayout = QGridLayout()
        gridLayout.addWidget(self.cmdTxt, 0, 1, 1, 1)
        gridLayout.addWidget(self.subuser, 0, 2, 1, 1)
        gridLayout.addWidget(executeBtn, 0, 3, 1, 1)
        gridLayout.addWidget(clearBtn, 0, 4, 1, 1)
        gridLayout.addWidget(self.minParameter, 1, 1, 1, 1)
        gridLayout.setColumnStretch(1, 6)
        gridLayout.setColumnStretch(2, 2)
        gridLayout.setColumnStretch(3, 1)
        gridLayout.setColumnStretch(4, 1)
        gridLayout.setContentsMargins(5, 0, 5, 10)
        self.topLayout = gridLayout
        self.topBox.setLayout(gridLayout)

    def createLeftGroupBox(self):
        self.leftGroupBox = QGroupBox("Command")
        leftTabWidget = QTabWidget()
        leftTabWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored)

        tab1 = QWidget()
        self.commandText = QTextEdit()
        self.commandText.setPlaceholderText(
            "Extracted command will be shown here")
        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(5, 5, 5, 5)
        tab1hbox.addWidget(self.commandText)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        # params label
        self.batchParamsLabel = QLabel()
        self.batchParamsLabel.setText("Select parameter:")
        # params list
        self.batchParams = QComboBox()
        self.batchParams.addItems(self.BATCH_PARAMS)
        self.batchParams.setEditable(True)
        # params text label
        self.batchParamsListLabel = QLabel()
        self.batchParamsListLabel.setText("Insert the list:")
        self.batchParamsListLabel.setContentsMargins(0, 10, 0, 0)

        # params text
        self.batchParamsList = QTextEdit()
        self.batchParamsList.setPlaceholderText("Enter each item in new line")
        self.batchParamsList.setFrameStyle(QFrame.Box)
        tableLayout = QGridLayout()
        tableLayout.setContentsMargins(15, 5, 5, 5)
        tableLayout.addWidget(self.batchParamsLabel, 0, 0)
        tableLayout.addWidget(self.batchParams, 1, 0)
        tableLayout.addWidget(self.batchParamsListLabel, 2, 0)
        tableLayout.addWidget(self.batchParamsList, 3, 0)
        tab2.setLayout(tableLayout)

        leftTabWidget.addTab(tab1, "Extracted Command")
        leftTabWidget.addTab(tab2, "Batch")

        layout = QGridLayout()
        layout.addWidget(leftTabWidget, 0, 0, 1, 1)

        self.leftGroupBox.setLayout(layout)

    def createMiddleTabWidget(self):
        self.middleGroupBox = QGroupBox("Results")
        middleTabWidget = QTabWidget()
        middleTabWidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Ignored)

        tab1 = QWidget()
        self.plainResponse = QTextEdit()
        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(5, 5, 5, 5)
        tab1hbox.addWidget(self.plainResponse)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        self.tableResponse = QTableWidget(1, 2)
        self.tableResponse.setHorizontalHeaderLabels(["Property", "Value"])
        self.tableResponse.horizontalHeader().setStretchLastSection(True)
        tableLayout = QGridLayout()
        tableLayout.setContentsMargins(5, 5, 5, 5)
        tableLayout.addWidget(self.tableResponse, 0, 0)
        tab2.setLayout(tableLayout)

        tab3 = QWidget()
        self.listResponse = QTextEdit()
        tab3hbox = QHBoxLayout()
        tab3hbox.addWidget(self.listResponse)
        tab3.setLayout(tab3hbox)

        middleTabWidget.addTab(tab1, "Plain")
        middleTabWidget.addTab(tab2, "Properties")
        middleTabWidget.addTab(tab3, "List")

        layout = QGridLayout()
        layout.addWidget(middleTabWidget, 0, 0, 1, 1)

        self.middleGroupBox.setLayout(layout)

    def openLoginWindow(self):
        """
        Start login window
        """
        loginGui = LoginWindow(self)
        loginGui.startGui()

    def menuBarActions(self, q):
        action = q.text()
        if action == "New Window":
            pass
        if action == "Save to file":
            self.saveCommandToFile()
        if action == "Quit":
            self.closeApplication()
        if action == "Copy":
            self.copyToClipboard()
        if action == "Help":
            self.showHelp()
        if action == "About ISPAPI tool":
            self.showAbout()
        if action == "How to start?":
            self.showHelp()

    def closeApplication(self):
        print("exiting")
        sys.exit()

    def startNewWindow(self):
        app = QApplication(sys.argv)
        appGui = MainFrame()
        appGui.startGui()
        sys.exit(app.exec_())

    def startGui(self):
        geo = QDesktopWidget().availableGeometry()

        screenWidth = geo.width()
        screenHeight = geo.height()
        width = int(screenWidth * 0.5)
        height = int(screenHeight * 0.5)
        self.resize(width, height)

        frameGeo = self.frameGeometry()
        cp = geo.center()
        frameGeo.moveCenter(cp)
        self.move(frameGeo.topLeft())

        # start gui
        self.show()

    def initialiseCommandCompleter(self):
        model = QStringListModel()
        # get all possible autocomplete strings
        stringsSuggestion = []
        stringsSuggestion = (self.coreLogic.getCommandList()).splitlines()
        # set suggestion to the model
        model.setStringList(stringsSuggestion)
        # set model to the completer
        self.completer.setModel(model)

    def initialiseSubuserCompleter(self):
        model = QStringListModel()
        # get all possible autocomplete strings
        stringsSuggestion = []
        stringsSuggestion = (self.coreLogic.getSubUserList()).splitlines()
        # set suggestion to the model
        model.setStringList(stringsSuggestion)
        # set model to the completer
        self.subUsercompleter.setModel(model)

    def __clearCMDfield(self):
        self.cmdTxt.clear()
        self.cmdTxt.setFocus(True)

    def populateResults(self, response, mode="normal"):
        # get reulsts
        plainResult = response.getPlain()
        listResult = response.getListHash()

        # set plain results
        if mode == "iterative":
            self.plainResponse.append(plainResult)
            print("iternative")
        else:
            self.plainResponse.setText(plainResult)
            # delete any previous content of the list
            self.listResponse.setText("")

        # set properties and list
        resultLists = listResult["LIST"]
        counter = 0
        for row in resultLists:
            for col in row:
                counter += 1
        # set the number of rows
        self.tableResponse.setRowCount(counter)

        # populate the table
        rownumber = 0
        for row in resultLists:
            for i, (key, value) in enumerate(row.items()):
                keyWidget = QTableWidgetItem(key)
                valueWidget = QTableWidgetItem(value)
                self.tableResponse.setItem(rownumber, 0, keyWidget)
                self.tableResponse.setItem(rownumber, 1, valueWidget)
                # update the list
                if key not in ("TOTAL", "FIRST", "LAST", "LIMIT", "COUNT"):
                    self.listResponse.append(value)
                # incerate rownumber
                rownumber += 1
        # order table content
        self.tableResponse.sortItems(Qt.AscendingOrder)

    def saveCommandToFile(self):
        try:
            textToWrite = self.commandAndResponsePlain()
            options = QFileDialog.Options()
            # options |= QFileDialog.DontUseNativeDialog # Qt's builtin File Dialogue
            fileName, _ = QFileDialog.getSaveFileName(self,
                                                      "Open",
                                                      "report.txt",
                                                      "All Files (*.*)",
                                                      options=options)
            if fileName:
                try:
                    with open(fileName, "w") as file:
                        file.write(textToWrite)
                    alert = QMessageBox()
                    alert.setText("'" + fileName +
                                  "' \n\nFile Saved Successfully!")
                    alert.setIcon(QMessageBox.Information)
                    alert.exec_()
                except Exception as e:
                    alert = QMessageBox()
                    alert.setIcon(QMessageBox.Critical)
                    alert.setText("Couldn't save the file due to: " + str(e))
                    alert.exec_()
        except Exception as e:
            alert = QMessageBox()
            alert.setIcon(QMessageBox.Critical)
            alert.setText("Request a command first!")
            alert.setWindowTitle("Error")
            alert.exec_()

    def commandAndResponsePlain(self):
        result = self.plainResponse.toPlainText()
        command = self.response.getCommandPlain()
        textToWrite = command + "\n" + result
        return textToWrite

    def copyToClipboard(self):
        try:
            newText = self.commandAndResponsePlain()
            clipboard = QApplication.clipboard()
            clipboard.setText(newText)
        except Exception as e:
            print(e)
            pass  # in the case where there is not command requested

    def showHelp(self):
        box = QMessageBox(self)
        msg = """<p align='center'>
        <b style='font-size:20px'>Help Information</b>. <br><br><br>
        This window provides a simple help view, more detailed help can be found at: 
        <a href="https://hexonet.github.io/ispapicli/">ISPAPI CLI Tool Documentation</a>
        <br><br>
        Quick start:
        <br>
        To show help, type the command: -h | --help
        <br>
        From there you will find all information about using the command line in both the GUI and terminal
        <br><br>
        <span style="color:orange">Note</span>: Commands executed in terminal are similar to commands used in the GUI, except for the "--update" command which is only possible to trigger in the terminal
        <br><br><br>
        Copyright 2020 @Hexonet
        <br><br>
        </p>
        """
        box.setStandardButtons(QMessageBox.Ok)
        box.setIcon(QMessageBox.Information)
        box.setWindowTitle("Help")
        box.setText(msg)
        box.show()

    def showUpdating(self):
        box = QMessageBox(self)
        msg = """
        <p>Updating is done!</p>
        """
        box.setStandardButtons(QMessageBox.Ok)
        box.setIcon(QMessageBox.Information)
        box.setWindowTitle("Updating...")
        box.setText(msg)
        box.show()
        self.scrap.scrapCommands()
        # init tool dropdown autocomplete
        self.initialiseCommandCompleter()

    def Handle_Progress(self, blocknum, blocksize, totalsize):

        ## calculate the progress
        readed_data = blocknum * blocksize

        if totalsize > 0:
            download_percentage = readed_data * 100 / totalsize
            self.progressBar.setValue(download_percentage)
            QApplication.processEvents()

    def checkForUpdate(self):
        try:
            preBox = QMessageBox(self)
            msgNo = """<p align='center'>
                            Checking for update...
                        </p>
                    """
            # preBox.setStandardButtons(QMessageBox.Ok)
            preBox.setWindowTitle("Checking...")
            preBox.setText(msgNo)
            preBox.show()
            QApplication.processEvents()
            currentVersion = __version__
            url = "https://github.com/hexonet/ispapicli/releases/latest"
            r = requests.get(url)
            if r.ok:
                preBox.close()
                box = QMessageBox(self)
                # check if there is a new version available
                # increase the current version by 1 as it was not added in the semantic versioning
                # the bin generated before modifying the version files
                latestVersion = r.url.split("/")[-1]
                latestVersion = version.parse(latestVersion[1:])
                currentVersion = currentVersion.split(".")
                currentVersion[2] = str(int(currentVersion[2]) + 1)
                currentVersion = ".".join(currentVersion)
                currentVersion = version.parse(currentVersion)
                if currentVersion == latestVersion:
                    msgNo = """<p align='center'>
                            You have the latest version installed.
                            </p>
                            """
                    box.setStandardButtons(QMessageBox.Ok)
                    box.setWindowTitle("Updating")
                    box.setText(msgNo)
                    box.show()
                elif latestVersion > currentVersion:
                    msgYes = """<p align='center'>
                        New version available, update now?
                    </p>
                    """
                    ret = box.question(self, "Updating", msgYes,
                                       box.No | box.Yes, box.Yes)
                    if ret == box.Yes:
                        # updating the tool
                        self.updateTool(latestVersion)
                    else:
                        box.close()
                else:
                    return
            else:
                raise Exception
        except Exception:
            preBox = QMessageBox(self)
            msgNo = """<p align='center'>
                            Please check your internet connection.
                        </p>
                    """
            # preBox.setStandardButtons(QMessageBox.Ok)
            preBox.setWindowTitle("No Internet")
            preBox.setText(msgNo)
            preBox.show()

    def updateTool(self, latestVersion):
        fileName = ""
        if sys.platform == "win32":
            fileName = "win-binary-%s.zip" % str(latestVersion)
        elif sys.platform == "linux" or sys.platform == "darwin":
            fileName = "linux-binary-%s.zip" % str(latestVersion)
        else:
            return

        # init download
        url = "https://github.com/hexonet/ispapicli/releases/download/v%s/%s" % (
            latestVersion,
            fileName,
        )
        print(url)
        import urllib

        # Copy a network object to a local file
        try:
            # dwonload our zipped tool
            fileDownloaded, response = urllib.request.urlretrieve(
                url, fileName, self.Handle_Progress)
            if response and fileDownloaded:
                # unzip the tool
                import zipfile

                with zipfile.ZipFile(fileName, "r") as zip_ref:
                    result = zip_ref.extractall("tmp")
                    # start the new tool
                    if sys.platform == "win32" and result is None:
                        # updating the tool
                        newToolName = "ispapicli-%s" % str(
                            latestVersion) + ".exe"
                        # rename the newly donwloaded tool
                        os.rename(r"tmp/ispapicli.exe", newToolName)
                        # clean the directoy
                        os.remove(fileDownloaded)
                        os.rmdir("tmp")
                        # start the new tool
                        os.system("" + newToolName)
                        self.closeApplication()
                    elif (sys.platform == "linux"
                          or sys.platform == "darwin") and result is None:
                        newToolName = "ispapicli-%s" % str(latestVersion)
                        # rename the newly donwloaded tool
                        os.rename(r"tmp/ispapicli", newToolName)
                        # clean the directoy
                        os.remove(fileDownloaded)
                        os.rmdir("tmp")
                        # updating the tool
                        os.system("sudo chmod +x " + newToolName)
                        os.system("./" + newToolName + " &")
                        self.closeApplication()
                        # TODO clean the old version by sending an argument
                        # process = subprocess.Popen(
                        #    ["sudo chmod +x " + newToolName, "./" + newToolName]
                        # )
                    else:
                        return

                    # upon success
                    # finalBox = QMessageBox(self)
                    # msgYes = """<p align='center'>
                    #     Update finished, close now?
                    # </p>
                    # """
                    # ret = finalBox.question(
                    #     self,
                    #     "Updating",
                    #     msgYes,
                    #     finalBox.No | finalBox.Yes,
                    #     finalBox.Yes,
                    # )
                    # if ret == finalBox.Yes:
                    #     # updating the tool
                    #     self.closeApplication()
                    # else:
                    #     finalBox.close()
            else:
                raise Exception
        except Exception as e:
            msgBox = QMessageBox(self)
            msgNo = ("""<p align='center'>
                            Problem to download: %s
                        </p>
                    """ % e)
            # preBox.setStandardButtons(QMessageBox.Ok)
            msgBox.setWindowTitle("Download")
            msgBox.setText(msgNo)
            msgBox.show()
            # os.system(
            #     "gnome-terminal -- bash -c './" + scriptPath + latestVersion + ";bash'"
            # )

    def showAbout(self):

        box = QMessageBox(self)
        msg = """<p align='center'>
        <b style='font-size:20px'>ISPAPI Tool</b>. <br><br><br>
        Version: %s <br><br>
        A simple command line interface to connect you to your account on Hexonet
        <br><br>
        Technical Support:
        <br>
        Email: [email protected] 
        <br>
        Website: <a href="https://hexonet.github.io/ispapicli/">ISPAPI CLI Tool</a>
        <br><br><br>
        Copyright 2020 @Hexonet
        <br><br>
        </p>
        """

        box.setStandardButtons(QMessageBox.Ok)
        # box.setIcon(QMessageBox.Information)
        box.setWindowTitle("About")
        box.setText(msg % __version__)
        box.show()

    def eventFilter(self, source, event):

        # this function to handle autocomplete for command line
        if event.type() == QEvent.KeyRelease and source is self.cmdTxt:
            if event.key() == Qt.Key_Space:
                # show min paramters suggestions
                try:
                    cmd = self.cmdTxt.text()
                    m = re.match("^(\w+)\s$", cmd)
                    if m:
                        minParams = self.coreLogic.getMinParameters(
                            cmd.strip())
                        if len(minParams) > 0:
                            minParamsLabel = ", ".join(minParams)
                            minParamsInput = "= ".join(minParams)
                            cursorPosition = (
                                len(self.cmdTxt.text() + minParams[0]) + 1
                            )  # for the '=' char
                            self.cmdTxt.setText(cmd + minParamsInput + "=")
                            self.minParameter.setText("Min parameters: " +
                                                      minParamsLabel)
                            self.cmdTxt.setCursorPosition(cursorPosition)
                        else:
                            self.minParameter.setText("Min parameters:")
                except Exception as e:
                    print(e)
        # must return bool value
        return super(MainFrame, self).eventFilter(source, event)

    def getIcon(self, iconName):
        ##
        # This function checks if the app is executable or in development and return the path

        if getattr(sys, "frozen", False):
            self.absolute_dirpath = os.path.dirname(sys.executable)
            try:
                self.absolute_dirpath = sys._MEIPASS
            except Exception:
                self.absolute_dirpath = os.path.abspath(".")
            path = self.command_path = os.path.join(self.absolute_dirpath,
                                                    "data/icons/" + iconName)
        elif __file__:
            self.absolute_dirpath = os.path.dirname(__file__)
            path = self.command_path = os.path.join(self.absolute_dirpath,
                                                    "../icons/" + iconName)
        return path

    def getScriptsPath(self, system):
        """
        Return the script path
        """
        path = "scripts/"
        # scripts/linux-download.sh
        # check which platform
        if system == "linux":
            path = path + "linux-download.sh"
        elif system == "windows":
            path = path + "win-download.ps1"
        else:
            raise Exception
        return path
Example #12
0
#!/usr/bin/env python3
import argparse

from modules.core import Core
from interfaces.cmdline import Cmdline

from config import CONFIG

if __name__ == "__main__":
    c = Core(**CONFIG)

    parser = argparse.ArgumentParser()
    parser.add_argument("-g",
                        "--gui",
                        help="Run with graphical interface",
                        action="store_true")
    args = parser.parse_args()

    if args.gui:
        from interfaces.gtk3.gtk3_fault_analyzer import Gtk3FaultAnalyzer
        interface = Gtk3FaultAnalyzer(c)
        interface.start_interface()
    else:
        interface = Cmdline(c)
        interface.cmdloop()
Example #13
0
def main(args):

    # create core logic object
    core_obj = Core()
    # get the python standard parser initialised
    parser = core_obj.initParser()
    # overwrite defualt error function of the parser with our local function
    parser.error = errorFunction
    # clean extra spaces, leave only single spaces among commands
    original_args = ' '.join(args)
    # remove extra spaces around the = cases are ' =', '= ', ' = '
    original_args = original_args.replace(" = ", "=")
    original_args = original_args.replace(" =", "=")
    original_args = original_args.replace("= ", "=")
    print("Command entered: " + original_args)
    print("----------------")
    # split args in an array
    splitted_args = original_args.split()
    try:
        # get main commands such as "-c checkdomain"
        args = vars(parser.parse_args(splitted_args))
        # get other parameters such as "limit=5"
        reminderargs = args['args']
        # execute the command and show the results
        result, data = core_obj.parseArgs(args)

        # case gui requested
        if result == 'gui':
            startGUI()

        # case show help requested
        elif result == 'help':
            print('\n')
            print(
                textwrap.dedent('''\
                ISPAPI - Commandline Tool
                ------------------------------------------------------------
                The tool can be used in two modes:
                 - By using '=' sign e.g. --command=QueryDomainList limit=5
                 - By using spaces e.g. --command QueryDomainList limit 5
                ------------------------------------------------------------

                '''))
            parser.print_help()

        # case command requested
        elif result == 'cmd':
            # append reminder args with the command
            params_list = core_obj.parseParameters(reminderargs)
            cmd = data
            # add them to data which is the command list
            cmd.update(params_list)
            response = core_obj.request(cmd)
            result = response.getPlain()
            print(result)
        # update current commands
        elif result == 'update':
            scraper = Scrap()
            scraper.scrapCommands()
        # cases for msg
        else:
            print(data)

        sys.exit(0)

    except Exception as e:
        print("Command failed due to: " + str(e))
Example #14
0
from modules.core import Core
import logging

# logging.basicConfig(level=logging.DEBUG)
Core(hostname_or_path="payment.rate-one.de", configuration="analysis_test.json")
Example #15
0
    def __start_analysis(self, args):
        """
        Starts the analysis of the TLSA module.

        :param args: the arguments provided to the module
        :type args: argparse.Namespace
        """
        logging.basicConfig(
            level=logging.DEBUG if args.verbosity else logging.INFO)
        self.__logging.debug("Started anaylsis with verbosity on.")
        self.__logging.debug("Initializing Core element.")
        if isinstance(args.configuration,
                      str) and args.configuration == "default":
            args.configuration = (
                f"default{'_android.json' if args.apk else '_server.json'}")
        config_or_modules = args.configuration

        if args.apply_fix or args.file:
            # checks for openssl and ignore-openssl flag
            if not args.ignore_openssl and not args.openssl:
                raise AssertionError(
                    f"\n{Color.WARNING}OpenSSL is required to fix the TLSA records.{Color.ENDC}"
                    f"\nIgnore the checks with \n\t{Color.CBEIGE}--ignore-openssl{Color.ENDC}\n"
                    f"or insert an openssl version with\n\t{Color.CBEIGE}--openssl [VERSION]{Color.ENDC}"
                )

        if args.server:
            Core(
                hostname_or_path=args.server,
                configuration=config_or_modules,
                output=args.output,
                output_type=self.__to_report_type(args.output_type),
                to_exclude=args.exclude,
                type_of_analysis=Core.Analysis.HOST,
                group_by=args.group_by,
                apply_fix=args.apply_fix,
            )
        elif args.apk:
            Core(
                hostname_or_path=args.apk,
                configuration=config_or_modules,
                output=args.output,
                output_type=self.__to_report_type(args.output_type),
                to_exclude=args.exclude,
                type_of_analysis=Core.Analysis.APK,
                group_by=args.group_by,
            )
        elif args.domain_file:
            Core(
                hostname_or_path=load_list_of_domains(args.domain_file),
                configuration=config_or_modules,
                output=args.output,
                output_type=self.__to_report_type(args.output_type),
                to_exclude=args.exclude,
                type_of_analysis=Core.Analysis.DOMAINS,
                group_by=args.group_by,
            )
        elif args.file:
            if isinstance(args.configuration, list):
                self.__logging.warning(
                    "Ignoring module list. Try to exclude the modules with -e module1 module2"
                )
            Core(
                hostname_or_path=args.file,
                configuration="default_file.json",
                output=args.output,
                output_type=self.__to_report_type(args.output_type),
                type_of_analysis=Core.Analysis.CONFIGURATION,
                to_exclude=args.exclude,
                group_by=args.group_by,
                apply_fix=args.apply_fix,
                openssl_version=args.openssl,
                ignore_openssl=args.ignore_openssl,
            )

        else:  # must be args.list, unless argparse throws error.
            self.__print_module(args.list)