def start_write_to_tango(self, loading_list, value_list):
        self.tango_applier = TangoApplier()

        self.num = 0
        loading_list, value_list, error_list = self.check_tango_loading_list(
            loading_list, value_list)
        if error_list:
            error_message = "Error:\n•  " + '\n•  '.join(error_list)
            QtWidgets.QMessageBox.critical(self.parent, "Mapping failed",
                                           error_message)
            return

        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_save_snapshot_signal.connect(
            self.stop_tango_snapshot_saving)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_loading_completed_signal.connect(
            self.tango_writing_completed)
        #self.tango_applier.writing_completed_signal.connect(self.tango_writing_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.save_snapshot(loading_list, value_list)
    def run_topics_analyser(self) -> None:
        if (len(self.ui.output_file_name_txt.text().strip()) == 0):
            self._show_message(['Please enter the output file name.'],
                               icon=QMessageBox.Warning)
            return

        get_wordlist = lambda text: [word.strip() for word in text.split(',')
                                     ] if (len(text) > 0) else []
        self.addl_stopwords = get_wordlist(self.ui.addl_stopwords_txt.text())
        self.groupby_cols = self._get_groupby_cols()
        self.data = self.data_reader.get_dataframe(
            self.ui.text_col_name_txt.text(), self.groupby_cols)
        self.output_filename = self.ui.output_file_name_txt.text()
        self.num_ngrams = self.ui.num_ngrams_spb.value()
        self.num_topics = self.ui.num_topics_spb.value()
        # use the input file name as the Optuna study name
        self.studyname = re.sub(r'[.]\w+', '',
                                ntpath.basename(self.ui.data_file_txt.text()))
        # log the analysis
        self.logger.info(
            f'Start Topics Analysis:\n{self._get_analysis_inputs_summary()}')
        # create a worker thread for the TopicsAnalyser
        worker = Worker(self.execute_analysis)
        # connect the signals to the slots (callback functions)
        worker.signals.progress.connect(self.on_analysis_progress)
        worker.signals.result.connect(self.on_analysis_success)
        worker.signals.error.connect(self.on_thread_error)
        # Execute the worker thread
        self.threadpool.start(worker)
        # show a progress dialog while the TopicsAnalyser is running
        self.analysis_progress = ProgressDialog(
            'Analysis is running, please wait...', self).progress
        self.analysis_progress.setValue(1)
        self.analysis_progress.show()
Beispiel #3
0
 def __init__(self):
     QObject.__init__(self)
     self._mywindow = loadWindowFromFile(r'mainwindow.ui')
     self._mywindow.le_expires.setText("90")
     self._width_of_vm_frame = 400
     self._connectWidgetSignals()
     self._progress_dlg = ProgressDialog()
Beispiel #4
0
    def start_write_to_tango(self, loading_list):
        self.tango_applier = TangoApplier()

        self.num = 0
        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_save_snapshot_signal.connect(
            self.stop_tango_snapshot_saving)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_applier.writing_completed_signal.connect(
            self.tango_writing_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.save_snapshot(loading_list)
Beispiel #5
0
 def __init__(self):
     QObject.__init__(self)
     self._mywindow = loadWindowFromFile(r'mainwindow.ui')
     self._mywindow.le_expires.setText("90")
     self._width_of_vm_frame = 400
     self._connectWidgetSignals()
     self._progress_dlg = ProgressDialog()
 def getfile(self) -> None:
     options = QFileDialog.Options()
     options |= QFileDialog.DontUseNativeDialog
     filename, _ = QFileDialog.getOpenFileName(self,
                                               "Open File",
                                               "",
                                               "Excel files (*.xlsx)",
                                               options=options)
     if (filename):
         self.ui.data_file_txt.setText(filename)
         # create a worker thread for data loading
         worker = Worker(self.execute_dataloading, filename)
         # connect the signals to the slots (callback functions)
         worker.signals.finished.connect(self.on_dataloading_success)
         worker.signals.error.connect(self.on_thread_error)
         # Execute the worker thread
         self.threadpool.start(worker)
         self.dataloading_progress = ProgressDialog(
             'Loading data, please wait...', self).progress
         self.dataloading_progress.setValue(1)
         self.dataloading_progress.show()
Beispiel #7
0
    def newTab(self, currentIndex):
        # File Dialog (uses csv directory)
        directory = os.path.dirname(os.path.realpath(__file__)) + "\csv"
        if not os.path.exists(directory):
            os.makedirs(directory)

        QApplication.beep()
        # Path to Selected CSV File
        path = QFileDialog.getOpenFileName(
            self, "Open CSV File", directory,
            "Comma-Separated Values File (*.csv)")[0]
        if not path:
            return
        filename = QUrl.fromLocalFile(path).fileName()

        # Dialog for user to select features and label
        progressDialog = ProgressDialog(None, None, 0, 100, self)
        progressDialog.setWindowTitle("Reading " + filename + "...")
        progressDialog.setValue(0)
        progressDialog.show()
        QApplication.processEvents()

        selectionFeaturesDialog = SelectionFeaturesDialog(path)

        progressDialog.setWindowTitle("Done")
        progressDialog.setValue(100)
        progressDialog.close()
        QApplication.processEvents()
        QApplication.beep()

        dialogCode = selectionFeaturesDialog.exec_()

        #If Dialog was cancelled, then avoid opening a new tab
        if dialogCode == 0:
            return

        features = selectionFeaturesDialog.getFeatures()
        label = selectionFeaturesDialog.getLabel()

        tabGroupBox = AlgorithmGroupBox(path, features, label)

        pathToNewCSVIcon = os.path.dirname(
            os.path.realpath(__file__)) + "\\assets" + "\\csv_icon.png"
        self.addTab(tabGroupBox, QIcon(pathToNewCSVIcon), filename)
        self.setCurrentWidget(tabGroupBox)
class Loading(QObject):
    """docstring for Loading"""
    def __init__(self,
                 loading_list=None,
                 tango_applier=None,
                 progBar=None,
                 parent=None):
        super(Loading, self).__init__()
        self.progBar = progBar
        self.loading_list = loading_list
        self.tango_applier = tango_applier
        self.num = 0
        self.count = 0
        self.parent = parent

        #self.tango_applier.begin_writing_signal.connect(self.begin_writing)
        #self.tango_applier.end_writing_signal.connect(self.end_writing)

        #self.progBar.

        #self.progBar.forceShow()

    reading_tango_completed_signal = pyqtSignal(dict)
    tango_loading_completed_signal = pyqtSignal()

    def check_tango_loading_list(self, loading_list, value_list=None):
        fixed_loading_list = {}
        fixed_value_list = {}
        error_list = []
        for name, path in loading_list.items():
            if not path:
                #error_list.append("No path for name: "+name)
                print("no path for name:", name)
                continue

            el = path.split('/')
            dev_name = '/'.join(el[:-1])
            attr = el[-1]
            if not dev_name or not attr:
                error_list.append("No attr or dev for name " + name)
                print("no attr or dev for name:", name)
                continue
            fixed_loading_list[name] = path

            if value_list is not None:
                fixed_value_list[name] = value_list[name]
        if value_list is None:
            return fixed_loading_list, error_list

        return fixed_loading_list, fixed_value_list, error_list

    def start_read_from_tango(self, loading_list):
        self.tango_applier = TangoApplier()

        loading_list, error_list = self.check_tango_loading_list(loading_list)
        if error_list:
            error_message = "Error:\n•  " + '\n•  '.join(error_list)
            QtWidgets.QMessageBox.critical(self.parent, "Mapping failed",
                                           error_message)
            return

        self.num = 0
        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        #self.progBar.stopButton.clicked.connect(self.stop_ta)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_load_snapshot_signal.connect(
            self.stop_tango_snapshot_loading)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_loading_completed_signal.connect(
            self.reading_tango_completed)
        #self.tango_applier.read_completed_signal.connect(self.reading_tango_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.load_snapshot(loading_list)

    def stop_tango_snapshot_loading(self):
        self.progBar.setValue(self.count)
        self.num = 0
        self.count = 0

    def reading_tango_completed(self):
        value_list = self.tango_applier.get_values()
        if self.num == self.count:
            msgBox = QMessageBox()
            if not self.error_list:
                msgBox.setText("Loading completed successfully.")
            else:
                detail_txt = self._create_tango_error_text(
                    "Next variables don't sending:")
                msgBox.setText("Loading completed with errors.")
                msgBox.setDetailedText(detail_txt)

            msgBox.exec()
        print(self.reverse_loading_list)
        self.reading_tango_completed_signal.emit(value_list)

    def start_write_to_tango(self, loading_list, value_list):
        self.tango_applier = TangoApplier()

        self.num = 0
        loading_list, value_list, error_list = self.check_tango_loading_list(
            loading_list, value_list)
        if error_list:
            error_message = "Error:\n•  " + '\n•  '.join(error_list)
            QtWidgets.QMessageBox.critical(self.parent, "Mapping failed",
                                           error_message)
            return

        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_save_snapshot_signal.connect(
            self.stop_tango_snapshot_saving)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_loading_completed_signal.connect(
            self.tango_writing_completed)
        #self.tango_applier.writing_completed_signal.connect(self.tango_writing_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.save_snapshot(loading_list, value_list)

    def begin_tango_dev_writing(self, dev):
        print(dev)
        self.progBar.set_loading_item(dev)

    def end_tango_dev_writing(self, dev):
        self.progBar.set_done_item(dev)
        self.num += 1
        self.progBar.setValue(self.num)
        if self.num == self.count:
            self.tango_loading_completed_signal.emit()

    def tango_error(self, dev, error):
        dev_name = '/'.join(dev.split('/')[:-1])
        attr = dev.split('/')[-1]
        name = self.reverse_loading_list[dev]
        self.error_list[name] = (dev_name, attr, error)
        self.progBar.set_loading_error(dev)
        self.num += 1
        self.progBar.setValue(self.num)
        if self.num == self.count:
            self.tango_loading_completed_signal.emit()

    def tango_writing_completed(self):
        if self.num == self.count:
            msgBox = QMessageBox()
            if not self.error_list:
                msgBox.setText("Sending completed successfully.")
            else:
                detail_txt = self._create_tango_error_text(
                    "Next variables don't sending:")
                msgBox.setText("Sending completed with errors.")
                msgBox.setDetailedText(detail_txt)

            msgBox.exec()

    def _create_tango_error_text(self, text):
        error_msg = text
        for name, inf in self.error_list.items():
            dev_name, dev_attr, error = inf
            error_msg += ("\n•  Variable name: %s\n    Device name: %s" %
                          (name, dev_name) +
                          "\n    Attribute name: %s\n    Reason: %s\n" %
                          (dev_attr, error))
        return error_msg

    def canel_write_to_tango(self):
        print("stop!")
        #self.tango_applier.stop_save_snapshot()

    def stop_tango_snapshot_saving(self):
        self.progBar.setValue(self.count)
        self.num = 0
        self.count = 0
Beispiel #9
0
class KvmUI(QObject):
    ''' UI Wrapper to kvm operations'''
    def __init__(self):
        QObject.__init__(self)
        self._mywindow = loadWindowFromFile(r'mainwindow.ui')
        self._mywindow.le_expires.setText("90")
        self._width_of_vm_frame = 400
        self._connectWidgetSignals()
        self._progress_dlg = ProgressDialog()

    def _connectWidgetSignals(self):
        '''Connect all the widget events with the appropriate slots'''
        self._mywindow.bt_refresh_templates.clicked.connect(
            self.loadTemplatesList)
        self._mywindow.bt_deploy.clicked.connect(self.deploySelectedTemplates)
        self._mywindow.bt_deploy_and_connect.clicked.connect(
            Curry(self.deploySelectedTemplates, True))
        self._mywindow.bt_reconnect.clicked.connect(self.connectToSelected)
        self._mywindow.bt_refresh_running_vms.clicked.connect(
            self.loadRunningVmsFromSelectedHost)
        self._mywindow.bt_show_running_vms.clicked.connect(
            self.showHideRunningVms)
        self._mywindow.bt_connect.clicked.connect(
            self.connectToSelectedFromRunning)
        self._mywindow.bt_deallocate.clicked.connect(self.deallocateSelected)
        self._mywindow.tw_deployed.itemDoubleClicked.connect(
            self.connectToSelected)
        self._mywindow.lv_templates.itemDoubleClicked.connect(
            Curry(self.deploySelectedFromDblClick, True))
        self._mywindow.tw_running_vms.itemDoubleClicked.connect(
            self.connectToSelectedFromRunning)

    def show(self):
        '''Shows the main ui'''
        self._mywindow.show()

    def setComment(self, comment):
        '''Sets the comment used when creating a vm'''
        self._mywindow.le_comment.setText(comment)

    @Slot()
    def showHideRunningVms(self):
        '''Shows / hides the running vm list'''
        if self._mywindow.gp_running_vm.isVisible():
            self._width_of_vm_frame = self._mywindow.gp_running_vm.width() + 5
            self._mywindow.gp_running_vm.hide()
            max_width = self._mywindow.maximumWidth()
            self._mywindow.setFixedWidth(self._mywindow.width() -
                                         self._width_of_vm_frame)
            self._mywindow.setMaximumWidth(max_width)
            self._mywindow.bt_show_running_vms.setText("Show Running vm's")
        else:
            self._mywindow.gp_running_vm.show()
            self._mywindow.resize(
                self._mywindow.width() + self._width_of_vm_frame,
                self._mywindow.height())
            self._mywindow.bt_show_running_vms.setText("Hide Running vm's")

    @Slot()
    def loadRunningVmsFromSelectedHost(self):
        '''Loads the running vm list from the hosts selected in the combobox'''
        if self._mywindow.cb_blades.currentText() == "Random":
            hostlist = HOSTS
        else:
            hostlist = {
                self._mywindow.cb_blades.currentText():
                HOSTS[self._mywindow.cb_blades.currentText()]
            }
        self.loadRunningVms(hostlist)

    def loadRunningVms(self, hosts):
        '''Loads the running vm list from the given hosts'''
        self._progress_dlg.reportProgress("Fetching running vm's list...")
        self._progress_dlg.show(cancellable=False)
        progress_msgs = Queue.Queue()
        running_vms = Queue.Queue()
        workers = []
        for host in hosts.values():
            work = Thread(target=listRunningVMWorker,
                          args=(
                              host,
                              progress_msgs,
                              running_vms,
                          ))
            work.start()
            workers.append(work)

        self._waitForTask(workers,
                          progress_msgs=progress_msgs,
                          abort_event=None)

        self._mywindow.tw_running_vms.clear()
        end_marks = 0
        while end_marks != len(workers):
            elem = running_vms.get()
            if not elem is None:
                self._addRunningVmToList(elem)
            else:
                end_marks += 1

        self._mywindow.tw_running_vms.sortByColumn(0,
                                                   Qt.SortOrder.AscendingOrder)
        self._progress_dlg.close()

    @Slot()
    def _addRunningVmToList(self, lst):
        '''adds a vm to the running vm list from a list of strings'''
        #FIXME: use a dict
        itm = QTreeWidgetItem()
        itm.setText(0, lst[0])
        itm.setText(1, lst[1])
        itm.setText(2, lst[2])
        itm.setText(3, lst[3])
        itm.setText(4, lst[4])
        itm.setText(5, lst[5])
        self._mywindow.tw_running_vms.addTopLevelItem(itm)

    @Slot()
    def deploySelectedFromDblClick(self, connect_after=False, item=None):
        '''Deploys machines using the selected template, invoked by
        double-click
        '''
        self.deploySelectedTemplates(connect_after)

    @Slot()
    def deploySelectedTemplates(self, connect_after=False):
        '''Deploys machines using the selected templates'''
        templates = []
        for item in self._mywindow.lv_templates.selectedItems():
            templates.append(item.text())

        if len(templates) == 0:
            QMessageBox.warning(self._mywindow, "Template",
                                "Please select a template to deploy")
            return

        comment = self._mywindow.le_comment.text()
        expires = int(self._mywindow.le_expires.text())
        host = resolveHost(self._mywindow.cb_blades.currentText())

        self.deployTemplates(templates, comment, expires, host, connect_after)

    def deployTemplates(self, templates, comment, expires, host,
                        connect_after):
        '''Deploys the provided templates as new vms'''
        for template in templates:
            self._progress_dlg.reportProgress("Deploying template...")
            self._progress_dlg.show(cancellable=False)
            ret_queue = Queue.Queue()
            work = Thread(target=deployWorker,
                          args=(
                              template,
                              expires,
                              comment,
                              host,
                              ret_queue,
                          ))
            work.start()
            self._waitForTask(work)
            self._progress_dlg.close()
            returned_ip = ret_queue.get()
            if returned_ip != None:
                self._addMachineToDeployedList(returned_ip, comment, host)
                if connect_after:
                    self.connect(returned_ip)
            else:
                err_msg = ret_queue.get()
                QMessageBox.warning(self._mywindow, "Error occurred",
                                    "Error: %s" % err_msg)

    def connect(self, ip_address):
        '''Connects to the given address using remote desktop, the method
        will check first if it can connect and retry if it cant
        '''
        self._progress_dlg.reportProgress("Connecting to %s..." % ip_address)
        self._progress_dlg.show(cancellable=True)
        progress_msgs = Queue.Queue()
        ret_queue = Queue.Queue()
        abort = Event()
        work = Thread(target=connectWorker,
                      args=(
                          ip_address,
                          progress_msgs,
                          ret_queue,
                          abort,
                      ))
        work.start()
        self._waitForTask(work, progress_msgs=progress_msgs, abort_event=abort)

        returned = ret_queue.get()

        self._progress_dlg.close()
        if returned != True:
            err_msg = ret_queue.get()
            if not abort.isSet():
                self._progress_dlg.reportProgress(err_msg)
                self._progress_dlg.exec_()

    def _addMachineToDeployedList(self, ip_address, comment, host):
        '''Adds the given machine to the list of the user deployed ones'''
        itm = QTreeWidgetItem()
        itm.setText(0, ip_address)
        itm.setText(1, comment)
        itm.setText(2, host)
        self._mywindow.tw_deployed.addTopLevelItem(itm)

    def removeFromDeployedList(self, ip_address):
        '''Removes the entry in the deployed list for the given ip address'''
        for i in range(self._mywindow.tw_deployed.topLevelItemCount()):
            current = self._mywindow.tw_deployed.topLevelItem(i).text(0)
            if current == ip_address:
                self._mywindow.tw_deployed.takeTopLevelItem(i)
                break

    @Slot()
    def connectToSelected(self):
        '''Connects to the selected machine using remote desktop'''
        for item in self._mywindow.tw_deployed.selectedItems():
            ip_address = item.text(0)
            self.connect(ip_address)

    @Slot()
    def connectToSelectedFromRunning(self):
        '''Connects to the machines selected from the running vms list'''
        for item in self._mywindow.tw_running_vms.selectedItems():
            ip_address = item.text(0)
            self.connect(ip_address)

    @Slot()
    def deallocateSelected(self):
        '''Deallocates the selected virtual machines'''
        for item in self._mywindow.tw_running_vms.selectedItems():
            ip_address = item.text(0)
            machine_id = item.text(4)
            blade = item.text(5)
            deallocate(blade, machine_id)
            self.removeFromDeployedList(ip_address)
        self.loadRunningVmsFromSelectedHost()

    @Slot()
    def loadTemplatesList(self):
        '''Loads the list of templates from the selected host'''
        self._progress_dlg.reportProgress("Fetching templates")
        self._progress_dlg.show(cancellable=False)
        host = resolveHost(self._mywindow.cb_blades.currentText())
        templates = Queue.Queue()
        work = Thread(target=listTemplatesWorker, args=(
            host,
            templates,
        ))
        work.start()
        self._waitForTask(work)
        response = templates.get()
        self._mywindow.lv_templates.clear()
        for image in response['base_images']:
            self._mywindow.lv_templates.addItem(image['base_image_name'])

        self._progress_dlg.close()

    def _waitForTask(self, tasks, progress_msgs=None, abort_event=None):
        '''Waits for the given thread to finish reporting the thread progress
        thru the queue progress_msgs and handles the cancellation if cancelled
        thru the progress dialog
        FIXME: use of queue is not safe enough, call to empty() is unreliable
        according to python doc and may block, needs better solution for
        passing data between threads
        '''
        if type(tasks) != type([]):
            tasks = [tasks]

        while True:
            if isAlive(tasks) == False:
                break
            if not progress_msgs is None:
                if not progress_msgs.empty():
                    self._progress_dlg.reportProgress(progress_msgs.get())
            #when user cancels
            if self._progress_dlg.getResult() == 0:
                if not abort_event is None:
                    abort_event.set()
                break
            APP.processEvents()
            time.sleep(0)
Beispiel #10
0
class Loading(QObject):
    """docstring for Loading"""
    def __init__(self, loading_list=None, tango_applier=None, progBar=None):
        super(Loading, self).__init__()
        self.progBar = progBar
        self.loading_list = loading_list
        self.tango_applier = tango_applier
        self.num = 0
        self.count = 0

        #self.tango_applier.begin_writing_signal.connect(self.begin_writing)
        #self.tango_applier.end_writing_signal.connect(self.end_writing)

        #self.progBar.

        #self.progBar.forceShow()

    reading_tango_completed_signal = pyqtSignal(dict)

    def start_read_from_tango(self, loading_list):
        self.tango_applier = TangoApplier()

        self.num = 0
        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        #self.progBar.stopButton.clicked.connect(self.stop_ta)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_load_snapshot_signal.connect(
            self.stop_tango_snapshot_loading)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_applier.read_completed_signal.connect(
            self.reading_tango_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.load_snapshot(loading_list)

    def stop_tango_snapshot_loading(self):
        self.progBar.setValue(self.count)
        self.num = 0
        self.count = 0

    def reading_tango_completed(self, value_list):
        if self.num == self.count:
            msgBox = QMessageBox()
            if not self.error_list:
                msgBox.setText("Loading completed successfully.")
            else:
                detail_txt = self._create_tango_error_text(
                    "Next variables don't sending:")
                msgBox.setText("Loading completed with errors.")
                msgBox.setDetailedText(detail_txt)

            msgBox.exec()
        self.reading_tango_completed_signal.emit(value_list)

    def start_write_to_tango(self, loading_list):
        self.tango_applier = TangoApplier()

        self.num = 0
        self.count = len(loading_list)
        self.progBar = ProgressDialog(loading_list)
        self.progBar.accepted.connect(self.canel_write_to_tango)
        self.progBar.show()
        self.progBar.setValue(0)

        self.tango_applier.begin_writing_signal.connect(
            self.begin_tango_dev_writing)
        self.tango_applier.end_writing_signal.connect(
            self.end_tango_dev_writing)
        self.tango_applier.stop_save_snapshot_signal.connect(
            self.stop_tango_snapshot_saving)
        self.tango_applier.error_signal.connect(self.tango_error)
        self.tango_applier.writing_completed_signal.connect(
            self.tango_writing_completed)

        self.error_list = {}
        self.reverse_loading_list = {}
        for name, dev in loading_list.items():
            self.reverse_loading_list[dev] = name

        self.tango_applier.save_snapshot(loading_list)

    def begin_tango_dev_writing(self, dev):
        print(dev)
        self.progBar.set_loading_item(dev)

    def end_tango_dev_writing(self, dev):
        self.progBar.set_done_item(dev)
        self.num += 1
        self.progBar.setValue(self.num)

    def tango_error(self, dev, error):
        dev_name = '/'.join(dev.split('/')[:-1])
        attr = dev.split('/')[-1]
        name = self.reverse_loading_list[dev]
        self.error_list[name] = (dev_name, attr, error)
        self.progBar.set_loading_error(dev)
        self.num += 1
        self.progBar.setValue(self.num)

    def tango_writing_completed(self):
        if self.num == self.count:
            msgBox = QMessageBox()
            if not self.error_list:
                msgBox.setText("Sending completed successfully.")
            else:
                detail_txt = self._create_tango_error_text(
                    "Next variables don't sending:")
                msgBox.setText("Sending completed with errors.")
                msgBox.setDetailedText(detail_txt)

            msgBox.exec()

    def _create_tango_error_text(self, text):
        error_msg = text
        for name, inf in self.error_list.items():
            dev_name, dev_attr, error = inf
            error_msg += ("\n•  Variable name: %s\n    Device name: %s" %
                          (name, dev_name) +
                          "\n    Attribute name: %s\n    Reason: %s\n" %
                          (dev_attr, error))
        return error_msg

    def canel_write_to_tango(self):
        print("stop!")
        self.tango_applier.stop_save_snapshot()

    def stop_tango_snapshot_saving(self):
        self.progBar.setValue(self.count)
        self.num = 0
        self.count = 0
class TopicsAnalyser_UI(QWizard):
    def __init__(self, parent=None):
        super(TopicsAnalyser_UI, self).__init__(parent)
        self.ui = Ui_TopicsModelingWizard()
        self.ui.setupUi(self)
        self.msg = QMessageBox(parent=self)

        # change the icon of the push buttons
        self.ui.add_col_btn.setIcon(self.style().standardIcon(
            getattr(QStyle, 'SP_ArrowForward')))
        self.ui.remove_col_btn.setIcon(self.style().standardIcon(
            getattr(QStyle, 'SP_ArrowBack')))

        # set tooltips on some widgets
        self.ui.other_col_txt.setToolTip(
            r'Enter the name of a <b>categorical</b> column in the dataset and then press <b>[Enter]</b> or <b>[Add]</b>.'
        )
        self.ui.other_cols_lst.setToolTip(
            'To remove a column, select one from the list and then press <b>[Remove]</b>.'
        )
        self.ui.groupby_cols_lbel.setToolTip(
            'The grouping levels start from the top of list.')
        self.ui.groupby_cols_lst.setToolTip(
            'You can drag and drop to change the order of a column in the list. And select the ones you want for grouping.'
        )
        stop_words_tip = 'Enter optional uncommon stop words separated by commas.'
        self.ui.addl_stopwords_lbl.setToolTip(stop_words_tip)
        self.ui.addl_stopwords_txt.setToolTip(stop_words_tip)

        # register the fields to make them required
        self.ui.DataFilePage.registerField('data_file_txt*',
                                           self.ui.data_file_txt)
        self.ui.DataFilePage.registerField('text_col_name_txt*',
                                           self.ui.text_col_name_txt)

        # override some default page functions
        self.ui.DataFilePage.validatePage = self._validate_data_file_page
        self.ui.TopicsModelingPage.initializePage = self.init_modeling_page

        # link the signals to the slots
        self.ui.browse_btn.clicked.connect(self.getfile)
        self.ui.run_btn.clicked.connect(self.run_topics_analyser)
        self.ui.add_col_btn.clicked.connect(self.add_other_col_for_import)
        self.ui.other_col_txt.returnPressed.connect(
            self.add_other_col_for_import)
        self.ui.remove_col_btn.clicked.connect(
            self.remove_other_col_for_import)

        self.data_reader = TextFileReader()

        # set up logger
        self.logger = MyLogging('topicsAnalyserLogger',
                                'topicsanalyser.log').logger
        # set up the uncaught exceptions handler
        sys.excepthook = self.uncaught_exception_handler

        # instantiate the thread pool
        self.threadpool = QThreadPool()
        # set the maximum number of tuning trials
        self.n_trials = 100

    def run_topics_analyser(self) -> None:
        if (len(self.ui.output_file_name_txt.text().strip()) == 0):
            self._show_message(['Please enter the output file name.'],
                               icon=QMessageBox.Warning)
            return

        get_wordlist = lambda text: [word.strip() for word in text.split(',')
                                     ] if (len(text) > 0) else []
        self.addl_stopwords = get_wordlist(self.ui.addl_stopwords_txt.text())
        self.groupby_cols = self._get_groupby_cols()
        self.data = self.data_reader.get_dataframe(
            self.ui.text_col_name_txt.text(), self.groupby_cols)
        self.output_filename = self.ui.output_file_name_txt.text()
        self.num_ngrams = self.ui.num_ngrams_spb.value()
        self.num_topics = self.ui.num_topics_spb.value()
        # use the input file name as the Optuna study name
        self.studyname = re.sub(r'[.]\w+', '',
                                ntpath.basename(self.ui.data_file_txt.text()))
        # log the analysis
        self.logger.info(
            f'Start Topics Analysis:\n{self._get_analysis_inputs_summary()}')
        # create a worker thread for the TopicsAnalyser
        worker = Worker(self.execute_analysis)
        # connect the signals to the slots (callback functions)
        worker.signals.progress.connect(self.on_analysis_progress)
        worker.signals.result.connect(self.on_analysis_success)
        worker.signals.error.connect(self.on_thread_error)
        # Execute the worker thread
        self.threadpool.start(worker)
        # show a progress dialog while the TopicsAnalyser is running
        self.analysis_progress = ProgressDialog(
            'Analysis is running, please wait...', self).progress
        self.analysis_progress.setValue(1)
        self.analysis_progress.show()

    def _get_groupby_cols(self) -> list:
        return [
            self.ui.groupby_cols_lst.item(i).text()
            for i in range(self.ui.groupby_cols_lst.count())
            if self.ui.groupby_cols_lst.item(i).checkState() == Qt.Checked
        ]

    def getfile(self) -> None:
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(self,
                                                  "Open File",
                                                  "",
                                                  "Excel files (*.xlsx)",
                                                  options=options)
        if (filename):
            self.ui.data_file_txt.setText(filename)
            # create a worker thread for data loading
            worker = Worker(self.execute_dataloading, filename)
            # connect the signals to the slots (callback functions)
            worker.signals.finished.connect(self.on_dataloading_success)
            worker.signals.error.connect(self.on_thread_error)
            # Execute the worker thread
            self.threadpool.start(worker)
            self.dataloading_progress = ProgressDialog(
                'Loading data, please wait...', self).progress
            self.dataloading_progress.setValue(1)
            self.dataloading_progress.show()

    def _validate_data_file_page(self) -> bool:
        isvalid = True
        errors = []
        text_col = self.ui.text_col_name_txt.text()
        cols = [text_col] + [
            self.ui.other_cols_lst.item(i).text()
            for i in range(self.ui.other_cols_lst.count())
        ]
        cols_not_exist = self.data_reader.verify_columns_exist(cols)
        if (len(cols_not_exist) > 0):
            errors.extend([
                'The following column(s) do not exist in the data file: ' +
                ', '.join(cols_not_exist)
            ])
            isvalid = False

        if (self.data_reader.is_text_column(text_col) == False):
            errors.extend([f'\n\n"{text_col}" is not a text column.'])
            isvalid = False

        if (len(errors) > 0):
            self._show_message(errors)

        return isvalid

    def init_modeling_page(self) -> None:
        # copy the other column names for grouping use
        self._copy_other_col_names()

    def _show_message(self,
                      msgs: list,
                      buttons_shown: int = QMessageBox.Ok,
                      icon: int = QMessageBox.Critical) -> None:
        self.msg.setIcon(icon)
        self.msg.setText(('').join(msgs))
        self.msg.setStandardButtons(buttons_shown)
        self.msg.exec()

    def _copy_other_col_names(self) -> None:
        self.ui.groupby_cols_lst.clear()
        for i in range(self.ui.other_cols_lst.count()):
            item = self.ui.other_cols_lst.item(i).clone()
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Checked)
            self.ui.groupby_cols_lst.addItem(item)

    def add_other_col_for_import(self) -> None:
        other_col = self.ui.other_col_txt.text()
        if (other_col != ''):
            cols_existed = self.ui.other_cols_lst.findItems(
                other_col, Qt.MatchCaseSensitive)
            if (len(cols_existed) > 0):
                self._show_message(
                    [f'Column "{other_col}" was already added.'],
                    icon=QMessageBox.Warning)
                return
            other_cols_limit = 5
            if (self.ui.other_cols_lst.count() == other_cols_limit):
                self._show_message([
                    f'Only up to {other_cols_limit} other columns are allowed.'
                ],
                                   icon=QMessageBox.Warning)
                return

            self.ui.other_cols_lst.addItem(other_col)
            self.ui.other_col_txt.setText('')

    def remove_other_col_for_import(self) -> None:
        if (self.ui.other_cols_lst.currentRow() != -1):
            self.ui.other_cols_lst.takeItem(
                self.ui.other_cols_lst.currentRow())

    def uncaught_exception_handler(self, type, value, traceback) -> None:
        log_msg = system_hook_format(type, value, traceback,
                                     self._get_analysis_inputs_summary())
        self.logger.exception(log_msg)

        # show a simplified error message to user
        disp_msg = "An unexpected error occurred below -\n" \
                f"Type: {type}\n" \
                f"Value: {value}\n\n" \
                "The error has been logged for debugging."
        self._show_message(disp_msg)

        # close all progress dialogs if open
        if self.dataloading_progress is not None:
            self.dataloading_progress.close()
        if self.analysis_progress is not None:
            self.analysis_progress.close()

    def _get_analysis_inputs_summary(self):
        na = 'N/A'
        datafile = na if self.ui.data_file_txt.text(
        ) is None else ntpath.basename(self.ui.data_file_txt.text())
        filesize = na if self.data_reader.filesize is None else f'{self.data_reader.filesize/(1000*1000):.2f} MB'
        max_nums_topics = self.ui.num_topics_spb.value()
        nums_ngrams = self.ui.num_ngrams_spb.value()
        txt_col = self.ui.text_col_name_txt.text()
        grp_cols = na if len(self._get_groupby_cols()) == 0 else ','.join(
            self._get_groupby_cols())

        return f"Data file: {datafile}\n" \
            f"File size: {filesize}\n" \
            f"Max. # of topics: {max_nums_topics}\n" \
            f"# of N-grams: {nums_ngrams}\n" \
            f"Text column: '{txt_col}'\n" \
            f"Grouping columns: {grp_cols}"

    # progess_signal is expected to pass to the worker function even though it may not be used
    def execute_dataloading(self, filename, progress_signal) -> None:
        self.data_reader.data_file_path = filename
        self.data_reader.read_data()

    def on_dataloading_success(self) -> None:
        self.dataloading_progress.close()

    def execute_analysis(self, progress_signal) -> str:
        analyser = TopicsAnalyser(self.data,
                                  self.output_filename,
                                  studyname=self.studyname,
                                  n_trials=self.n_trials,
                                  progress_signal=progress_signal)
        mod_msg = analyser.get_topics(self.num_topics, self.groupby_cols,
                                      self.num_ngrams, self.addl_stopwords)
        return mod_msg

    def on_analysis_progress(self, status: object) -> None:
        # update the status on the progress dialog
        msg = f"Tuning for:\n{status['study']}\nTrial #: {status['num_trial']}\n"
        self.analysis_progress.setLabelText(msg)

    def on_analysis_success(self, msg: str) -> None:
        self.analysis_progress.close()
        messages = ['Topics analysis is done.\n', msg]
        self._show_message(messages, icon=QMessageBox.Information)

    def on_thread_error(self, error_info: tuple) -> None:
        self.uncaught_exception_handler(*error_info)
Beispiel #12
0
class KvmUI(QObject):
    ''' UI Wrapper to kvm operations'''

    def __init__(self):
        QObject.__init__(self)
        self._mywindow = loadWindowFromFile(r'mainwindow.ui')
        self._mywindow.le_expires.setText("90")
        self._width_of_vm_frame = 400
        self._connectWidgetSignals()
        self._progress_dlg = ProgressDialog()

    def _connectWidgetSignals(self):
        '''Connect all the widget events with the appropriate slots'''
        self._mywindow.bt_refresh_templates.clicked.connect(
            self.loadTemplatesList)
        self._mywindow.bt_deploy.clicked.connect(self.deploySelectedTemplates)
        self._mywindow.bt_deploy_and_connect.clicked.connect(
            Curry(self.deploySelectedTemplates, True))
        self._mywindow.bt_reconnect.clicked.connect(
            self.connectToSelected)
        self._mywindow.bt_refresh_running_vms.clicked.connect(
            self.loadRunningVmsFromSelectedHost)
        self._mywindow.bt_show_running_vms.clicked.connect(
            self.showHideRunningVms)
        self._mywindow.bt_connect.clicked.connect(
            self.connectToSelectedFromRunning)
        self._mywindow.bt_deallocate.clicked.connect(
            self.deallocateSelected)
        self._mywindow.tw_deployed.itemDoubleClicked.connect(
            self.connectToSelected)
        self._mywindow.lv_templates.itemDoubleClicked.connect(
            Curry(self.deploySelectedFromDblClick,True))
        self._mywindow.tw_running_vms.itemDoubleClicked.connect(
            self.connectToSelectedFromRunning)

    def show(self):
        '''Shows the main ui'''
        self._mywindow.show()

    def setComment(self, comment):
        '''Sets the comment used when creating a vm'''
        self._mywindow.le_comment.setText(comment)

    @Slot()
    def showHideRunningVms(self):
        '''Shows / hides the running vm list'''
        if self._mywindow.gp_running_vm.isVisible():
            self._width_of_vm_frame = self._mywindow.gp_running_vm.width() + 5
            self._mywindow.gp_running_vm.hide()
            max_width = self._mywindow.maximumWidth()
            self._mywindow.setFixedWidth(
                self._mywindow.width() - self._width_of_vm_frame)
            self._mywindow.setMaximumWidth(max_width)
            self._mywindow.bt_show_running_vms.setText("Show Running vm's")
        else:
            self._mywindow.gp_running_vm.show()
            self._mywindow.resize(
                self._mywindow.width() + self._width_of_vm_frame,
                self._mywindow.height())
            self._mywindow.bt_show_running_vms.setText("Hide Running vm's")

    @Slot()
    def loadRunningVmsFromSelectedHost(self):
        '''Loads the running vm list from the hosts selected in the combobox'''
        if self._mywindow.cb_blades.currentText() == "Random":
            hostlist = HOSTS
        else:
            hostlist = {self._mywindow.cb_blades.currentText():
                        HOSTS[self._mywindow.cb_blades.currentText()]}
        self.loadRunningVms(hostlist)

    def loadRunningVms(self, hosts):
        '''Loads the running vm list from the given hosts'''
        self._progress_dlg.reportProgress("Fetching running vm's list...")
        self._progress_dlg.show(cancellable=False)
        progress_msgs = Queue.Queue()
        running_vms = Queue.Queue()
        workers = []
        for host in hosts.values():
            work = Thread(target=listRunningVMWorker, args=(host,
                                                            progress_msgs,
                                                            running_vms,))
            work.start()
            workers.append(work)

        self._waitForTask(workers,
                          progress_msgs=progress_msgs,
                          abort_event=None)

        self._mywindow.tw_running_vms.clear()
        end_marks = 0
        while end_marks != len(workers):
            elem = running_vms.get()
            if not elem is None:
                self._addRunningVmToList(elem)
            else:
                end_marks += 1

        self._mywindow.tw_running_vms.sortByColumn(0,
                                                  Qt.SortOrder.AscendingOrder)
        self._progress_dlg.close()

    @Slot()
    def _addRunningVmToList(self, lst):
        '''adds a vm to the running vm list from a list of strings'''
        #FIXME: use a dict
        itm = QTreeWidgetItem()
        itm.setText(0, lst[0])
        itm.setText(1, lst[1])
        itm.setText(2, lst[2])
        itm.setText(3, lst[3])
        itm.setText(4, lst[4])
        itm.setText(5, lst[5])
        self._mywindow.tw_running_vms.addTopLevelItem(itm)

    @Slot()
    def deploySelectedFromDblClick(self, connect_after=False, item=None):
        '''Deploys machines using the selected template, invoked by
        double-click
        '''
        self.deploySelectedTemplates(connect_after)

    @Slot()
    def deploySelectedTemplates(self, connect_after=False):
        '''Deploys machines using the selected templates'''
        templates = []
        for item in self._mywindow.lv_templates.selectedItems():
            templates.append(item.text())

        if len(templates) == 0:
            QMessageBox.warning(self._mywindow, "Template",
                                "Please select a template to deploy")
            return

        comment = self._mywindow.le_comment.text()
        expires = int(self._mywindow.le_expires.text())
        host = resolveHost(self._mywindow.cb_blades.currentText())

        self.deployTemplates(templates, comment, expires, host, connect_after)

    def deployTemplates(self, templates, comment, expires, host, connect_after):
        '''Deploys the provided templates as new vms'''
        for template in templates:
            self._progress_dlg.reportProgress("Deploying template...")
            self._progress_dlg.show(cancellable=False)
            ret_queue = Queue.Queue()
            work = Thread(target=deployWorker, args=(template,
                                                     expires,
                                                     comment,
                                                     host,
                                                     ret_queue,))
            work.start()
            self._waitForTask(work)
            self._progress_dlg.close()
            returned_ip = ret_queue.get()
            if returned_ip != None:
                self._addMachineToDeployedList(returned_ip, comment, host)
                if connect_after:
                    self.connect(returned_ip)
            else:
                err_msg = ret_queue.get()
                QMessageBox.warning(self._mywindow, "Error occurred",
                                    "Error: %s" % err_msg)

    def connect(self, ip_address):
        '''Connects to the given address using remote desktop, the method
        will check first if it can connect and retry if it cant
        '''
        self._progress_dlg.reportProgress("Connecting to %s..." % ip_address)
        self._progress_dlg.show(cancellable=True)
        progress_msgs = Queue.Queue()
        ret_queue = Queue.Queue()
        abort = Event()
        work = Thread(target=connectWorker, args=(ip_address,
                                                  progress_msgs,
                                                  ret_queue,
                                                  abort,))
        work.start()
        self._waitForTask(work, progress_msgs=progress_msgs,
                          abort_event=abort)

        returned = ret_queue.get()

        self._progress_dlg.close()
        if returned != True:
            err_msg = ret_queue.get()
            if not abort.isSet():
                self._progress_dlg.reportProgress(err_msg)
                self._progress_dlg.exec_()

    def _addMachineToDeployedList(self, ip_address, comment, host):
        '''Adds the given machine to the list of the user deployed ones'''
        itm = QTreeWidgetItem()
        itm.setText(0, ip_address)
        itm.setText(1, comment)
        itm.setText(2, host)
        self._mywindow.tw_deployed.addTopLevelItem(itm)

    def removeFromDeployedList(self, ip_address):
        '''Removes the entry in the deployed list for the given ip address'''
        for i in range(self._mywindow.tw_deployed.topLevelItemCount()):
            current = self._mywindow.tw_deployed.topLevelItem(i).text(0)
            if current == ip_address:
                self._mywindow.tw_deployed.takeTopLevelItem(i)
                break

    @Slot()
    def connectToSelected(self):
        '''Connects to the selected machine using remote desktop'''
        for item in self._mywindow.tw_deployed.selectedItems():
            ip_address = item.text(0)
            self.connect(ip_address)

    @Slot()
    def connectToSelectedFromRunning(self):
        '''Connects to the machines selected from the running vms list'''
        for item in self._mywindow.tw_running_vms.selectedItems():
            ip_address = item.text(0)
            self.connect(ip_address)

    @Slot()
    def deallocateSelected(self):
        '''Deallocates the selected virtual machines'''
        for item in self._mywindow.tw_running_vms.selectedItems():
            ip_address = item.text(0)
            machine_id = item.text(4)
            blade = item.text(5)
            deallocate(blade, machine_id)
            self.removeFromDeployedList(ip_address)
        self.loadRunningVmsFromSelectedHost()

    @Slot()
    def loadTemplatesList(self):
        '''Loads the list of templates from the selected host'''
        self._progress_dlg.reportProgress("Fetching templates")
        self._progress_dlg.show(cancellable=False)
        host = resolveHost(self._mywindow.cb_blades.currentText())
        templates = Queue.Queue()
        work = Thread(target=listTemplatesWorker, args=(host, templates,))
        work.start()
        self._waitForTask(work)
        response = templates.get()
        self._mywindow.lv_templates.clear()
        for image in response['base_images']:
            self._mywindow.lv_templates.addItem(image['base_image_name'])

        self._progress_dlg.close()

    def _waitForTask(self, tasks, progress_msgs=None, abort_event=None):
        '''Waits for the given thread to finish reporting the thread progress
        thru the queue progress_msgs and handles the cancellation if cancelled
        thru the progress dialog
        FIXME: use of queue is not safe enough, call to empty() is unreliable
        according to python doc and may block, needs better solution for
        passing data between threads
        '''
        if type(tasks) != type([]):
            tasks = [tasks]

        while True:
            if isAlive(tasks) == False:
                break
            if not progress_msgs is None:
                if not progress_msgs.empty():
                    self._progress_dlg.reportProgress(progress_msgs.get())
            #when user cancels
            if self._progress_dlg.getResult() == 0:
                if not abort_event is None:
                    abort_event.set()
                break
            APP.processEvents()
            time.sleep(0)