Esempio n. 1
0
    def __show_form(self):
        if self.__showed:
            return

        self.gridLayout.addWidget(
            QLabel(tr('№ дела (обращения) <em style="color: red">*</em>')))
        w = QLineEdit()
        self.gridLayout.addWidget(w)
        w.setFocus()
        self.__wgts['declar_number'] = w
        self.gridLayout.addWidget(
            QLabel(
                tr('Услуга (код или номер, или наименование)<em style="color: red">*</em>'
                   )))
        w = QLineEdit()
        self.gridLayout.addWidget(w)
        self.__wgts['service'] = w
        self.gridLayout.addWidget(
            QLabel(
                tr('Дата регистрации запроса <em style="color: red">*</em>')))
        de = QDateEdit(QDate().currentDate())
        de.setCalendarPopup(True)
        self.gridLayout.addWidget(de)
        self.__wgts['register_date'] = de
        self.gridLayout.addWidget(
            QLabel(
                tr('Плановый срок предоставления услуги <em style="color: red">*</em>'
                   )))
        de = QDateEdit()
        self.__wgts['register_date'].dateChanged.connect(de.setMinimumDate)
        de.setCalendarPopup(True)
        de.setMinimumDate(self.__wgts['register_date'].date())
        self.gridLayout.addWidget(de)
        self.__wgts['end_date'] = de

        gb = QGroupBox(tr('Место нахождения объекта услуги'))
        gb_l = QGridLayout()
        self.__wgts['object_address'] = self.__add_address(gb_l)
        gb.setLayout(gb_l)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)

        doc = {}
        gb = QGroupBox(tr('Приложенный документ *'))
        gb_l = QGridLayout()
        gb_l.addWidget(
            QLabel(tr('Наименование документа <em style="color: red">*</em>')))
        w = QLineEdit()
        w.setMaxLength(1024)
        gb_l.addWidget(w, 0, 1, 1, 1)
        doc['title'] = w
        gb_l.addWidget(
            QLabel(tr('Номер документа <em style="color: red">*</em>')))
        w = QLineEdit()
        w.setMaxLength(50)
        gb_l.addWidget(w)
        doc['number'] = w
        gb_l.addWidget(
            QLabel(tr('Дата документа <em style="color: red">*</em>')))
        w = QDateEdit()
        w.setCalendarPopup(True)
        gb_l.addWidget(w)
        doc['date'] = w
        gb_l.addWidget(
            QLabel(
                tr('Прямая ссылка на файл. Поддерживаются только пртоколы '
                   'HTTP, FTP <em style="color: red">*</em>')))
        w = QLineEdit()
        gb_l.addWidget(w)
        doc['url'] = w
        gb.setLayout(gb_l)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)
        self.documents.append(doc)

        gb = QGroupBox(tr('Заявители *'))
        self.dec_layout = QGridLayout()
        self.cb = QComboBox()
        self.cb.addItems(('Физическое лицо',
                          'Юридическое лицо/Индивидуальный предприниматель'))
        self.dec_layout.addWidget(self.cb)
        b = QPushButton(tr('Добавить'))
        b.clicked.connect(self.add_declarant)
        self.dec_layout.addWidget(b, 0, 1, 1, 1)
        gb.setLayout(self.dec_layout)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)

        b = QPushButton(tr('Добавить файл документа'))
        b.clicked.connect(self.__add_doc_file)
        self.gridLayout.addWidget(b)
        self.file_label = QLabel()
        self.gridLayout.addWidget(self.file_label)
        self.warn_label = QLabel(tr("Не удаляйте файл до отправки запроса"))
        self.warn_label.setStyleSheet('color: red')
        self.warn_label.setVisible(False)
        self.gridLayout.addWidget(self.warn_label,
                                  self.gridLayout.rowCount() + 1, 0, 1, 2)

        self.__showed = True
Esempio n. 2
0
class LedgerAuthDialog(QDialog):
    def __init__(self, handler, data):
        '''Ask user for 2nd factor authentication. Support text, security card and paired mobile methods.
        Use last method from settings, but support new pairing and downgrade.
        '''
        QDialog.__init__(self, handler.top_level_window())
        self.handler = handler
        self.txdata = data
        self.idxs = self.txdata['keycardData'] if self.txdata['confirmationType'] > 1 else ''
        self.setMinimumWidth(650)
        self.setWindowTitle(_("Ledger Wallet Authentication"))
        self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
        self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle
        self.ws = None
        self.pin = ''
        
        self.devmode = self.getDevice2FAMode()
        if self.devmode == 0x11 or self.txdata['confirmationType'] == 1:
            self.cfg['mode'] = 0
        
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        
        def on_change_mode(idx):
            if idx < 2 and self.ws:
                self.ws.stop()
                self.ws = None
            self.cfg['mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1
            if self.cfg['mode'] > 1 and self.cfg['pair'] and not self.ws:
                self.req_validation()
            if self.cfg['mode'] > 0:
                self.handler.win.wallet.get_keystore().cfg = self.cfg
                self.handler.win.wallet.save_keystore()
            self.update_dlg()
        def add_pairing():
            self.do_pairing()
        def return_pin():
            self.pin = self.pintxt.text() if self.txdata['confirmationType'] == 1 else self.cardtxt.text() 
            if self.cfg['mode'] == 1:
                self.pin = ''.join(chr(int(str(i),16)) for i in self.pin)
            self.accept()
        
        self.modebox = QWidget()
        modelayout = QHBoxLayout()
        self.modebox.setLayout(modelayout)
        modelayout.addWidget(QLabel(_("Method:")))
        self.modes = QComboBox()
        modelayout.addWidget(self.modes, 2)
        self.addPair = QPushButton(_("Pair"))
        self.addPair.setMaximumWidth(60)
        modelayout.addWidget(self.addPair)
        modelayout.addStretch(1)
        self.modebox.setMaximumHeight(50)
        vbox.addWidget(self.modebox)
        
        self.populate_modes()
        self.modes.currentIndexChanged.connect(on_change_mode)
        self.addPair.clicked.connect(add_pairing)
        
        self.helpmsg = QTextEdit()
        self.helpmsg.setStyleSheet("QTextEdit { background-color: lightgray; }")
        self.helpmsg.setReadOnly(True)
        vbox.addWidget(self.helpmsg)
        
        self.pinbox = QWidget()
        pinlayout = QHBoxLayout()
        self.pinbox.setLayout(pinlayout)
        self.pintxt = QLineEdit()
        self.pintxt.setEchoMode(2)
        self.pintxt.setMaxLength(4)
        self.pintxt.returnPressed.connect(return_pin)
        pinlayout.addWidget(QLabel(_("Enter PIN:")))
        pinlayout.addWidget(self.pintxt)
        pinlayout.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        pinlayout.addStretch(1)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        vbox.addWidget(self.pinbox)
                    
        self.cardbox = QWidget()
        card = QVBoxLayout()
        self.cardbox.setLayout(card)
        self.addrtext = QTextEdit()
        self.addrtext.setStyleSheet("QTextEdit { color:blue; background-color:lightgray; padding:15px 10px; border:none; font-size:20pt; font-family:monospace; }")
        self.addrtext.setReadOnly(True)
        self.addrtext.setMaximumHeight(130)
        card.addWidget(self.addrtext)
        
        def pin_changed(s):
            if len(s) < len(self.idxs):
                i = self.idxs[len(s)]
                addr = self.txdata['address']
                if not constants.net.TESTNET:
                    text = addr[:i] + '<u><b>' + addr[i:i+1] + '</u></b>' + addr[i+1:]
                else:
                    # pin needs to be created from mainnet address
                    addr_mainnet = bitcoin.script_to_address(bitcoin.address_to_script(addr), net=constants.BitcoinMainnet)
                    addr_mainnet = addr_mainnet[:i] + '<u><b>' + addr_mainnet[i:i+1] + '</u></b>' + addr_mainnet[i+1:]
                    text = str(addr) + '\n' + str(addr_mainnet)
                self.addrtext.setHtml(str(text))
            else:
                self.addrtext.setHtml(_("Press Enter"))
                
        pin_changed('')    
        cardpin = QHBoxLayout()
        cardpin.addWidget(QLabel(_("Enter PIN:")))
        self.cardtxt = QLineEdit()
        self.cardtxt.setEchoMode(2)
        self.cardtxt.setMaxLength(len(self.idxs))
        self.cardtxt.textChanged.connect(pin_changed)
        self.cardtxt.returnPressed.connect(return_pin)
        cardpin.addWidget(self.cardtxt)
        cardpin.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        cardpin.addStretch(1)
        card.addLayout(cardpin)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        vbox.addWidget(self.cardbox)
        
        self.pairbox = QWidget()
        pairlayout = QVBoxLayout()
        self.pairbox.setLayout(pairlayout)
        pairhelp = QTextEdit(helpTxt[5])
        pairhelp.setStyleSheet("QTextEdit { background-color: lightgray; }")
        pairhelp.setReadOnly(True)
        pairlayout.addWidget(pairhelp, 1)
        self.pairqr = QRCodeWidget()
        pairlayout.addWidget(self.pairqr, 4)
        self.pairbox.setVisible(False)
        vbox.addWidget(self.pairbox)
        self.update_dlg()
        
        if self.cfg['mode'] > 1 and not self.ws:
            self.req_validation()
        
    def populate_modes(self):
        self.modes.blockSignals(True)
        self.modes.clear()
        self.modes.addItem(_("Summary Text PIN (requires dongle replugging)") if self.txdata['confirmationType'] == 1 else _("Summary Text PIN is Disabled"))
        if self.txdata['confirmationType'] > 1:
            self.modes.addItem(_("Security Card Challenge"))
            if not self.cfg['pair']:
                self.modes.addItem(_("Mobile - Not paired")) 
            else:
                self.modes.addItem(_("Mobile - {}").format(self.cfg['pair'][1]))
        self.modes.blockSignals(False)
        
    def update_dlg(self):
        self.modes.setCurrentIndex(self.cfg['mode'])
        self.modebox.setVisible(True)
        self.addPair.setText(_("Pair") if not self.cfg['pair'] else _("Re-Pair"))
        self.addPair.setVisible(self.txdata['confirmationType'] > 2)
        self.helpmsg.setText(helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self.cfg['pair'] else 4])
        self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] == 1 else 100)
        self.pairbox.setVisible(False)
        self.helpmsg.setVisible(True)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        self.pintxt.setFocus(True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True)
        self.setMaximumHeight(400)

    def do_pairing(self):
        rng = os.urandom(16)
        pairID = (hexlify(rng) + hexlify(hashlib.sha256(rng).digest()[0:1])).decode('utf-8')
        self.pairqr.setData(pairID)
        self.modebox.setVisible(False)
        self.helpmsg.setVisible(False)
        self.pinbox.setVisible(False)
        self.cardbox.setVisible(False)
        self.pairbox.setVisible(True)
        self.pairqr.setMinimumSize(300,300)
        if self.ws:
            self.ws.stop()
        self.ws = LedgerWebSocket(self, pairID)
        self.ws.pairing_done.connect(self.pairing_done)
        self.ws.start() 
               
    def pairing_done(self, data):
        if data is not None:
            self.cfg['pair'] = [ data['pairid'], data['name'], data['platform'] ]
            self.cfg['mode'] = 2
            self.handler.win.wallet.get_keystore().cfg = self.cfg
            self.handler.win.wallet.save_keystore()
        self.pin = 'paired'
        self.accept()
    
    def req_validation(self):
        if self.cfg['pair'] and 'secureScreenData' in self.txdata:
            if self.ws:
                self.ws.stop()
            self.ws = LedgerWebSocket(self, self.cfg['pair'][0], self.txdata)
            self.ws.req_updated.connect(self.req_updated)
            self.ws.start()
              
    def req_updated(self, pin):
        if pin == 'accepted':
            self.helpmsg.setText(helpTxt[3])
        else:
            self.pin = str(pin)
            self.accept()
        
    def getDevice2FAMode(self):
        apdu = [0xe0, 0x24, 0x01, 0x00, 0x00, 0x01] # get 2fa mode
        try:
            mode = self.dongle.exchange( bytearray(apdu) )
            return mode
        except BTChipException as e:
            debug_msg('Device getMode Failed')
        return 0x11
    
    def closeEvent(self, evnt):
        debug_msg("CLOSE - Stop WS")
        if self.ws:
            self.ws.stop()
        if self.pairbox.isVisible():
            evnt.ignore()
            self.update_dlg()
Esempio n. 3
0
class CalibreBookBrainzPluginDialog(QDialog):
    def __init__(self, gui, icon, do_user_config):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.do_user_config = do_user_config

        self.db = gui.current_db

        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.header = QLabel(prefs['searchinbookbrainz'])
        self.l.addWidget(self.header)

        self.img = QLabel()
        pixmap = QPixmap("images/BBt.svg")
        self.img.setPixmap(pixmap)
        self.l.addWidget(self.img)

        # QCol = QColor()
        # QCol.setRed(220)
        # QCol.setGreen(255)
        # QCol.setBlue(240)


        self.setWindowTitle('Calibre Book Brainz Integration')
        self.setWindowIcon(icon)

        self.search_space = QLineEdit()
        self.selected_button = QPushButton('Use title from selected book', self)
        self.selected_button.clicked.connect(self.exporttitlefromselected)
        self.l.addWidget(self.selected_button)

        self.search_space = QLineEdit()
        self.l.addWidget(self.search_space)

        self.listWidget = QListWidget()
        self.l.addWidget(self.listWidget)

        self.searchExecutionButton = QPushButton('Search', self)
        self.searchExecutionButton.clicked.connect(self.search)
        self.l.addWidget(self.searchExecutionButton)

        self.aboutButton = QPushButton('About', self)
        self.aboutButton.clicked.connect(self.about)
        self.l.addWidget(self.aboutButton)

        self.resize(400, 600)
        self.search_space.setFocus()

    def exporttitlefromselected(self):
        rows = self.gui.current_view().selectionModel().selectedRows()
        if len(rows) == 0:
            self.search_space.setText("")
        else:
            mi = self.gui.library_view.model().db.get_metadata(rows[0].row())
            self.search_space.setText(mi.title)

    def search(self):

        text = self.search_space.text()
        print(text)
        self.listWidget.clear()
        self.listWidget.setFocus()
        try:
            url = "https://bookbrainz.org/ws/search/?q=\"" + text + "\"&mode=\"search\""
            hits = request_get(url)['hits']
        except:
            return
        numQueries = len(hits)
        act = 0
        for i in range(numQueries):
            enttype = hits[i]['_source']['_type']
            if not enttype in ['Publication', 'Work', 'Edition']:
                continue
            print(hits[i])
            item = QListWidgetItem("%i. %s BBID : %i" % ((act + 1), hits[i]['_source']['default_alias']['name'], 1))
            Qcol = QColor()
            if i % 2 == 0:
                Qcol.setRed(240)
                Qcol.setGreen(255)
                Qcol.setBlue(255)
            else:
                Qcol.setRed(220)
                Qcol.setGreen(255)
                Qcol.setBlue(240)
            item.setBackground(QBrush(Qcol))
            self.listWidget.addItem(item)
            act += 1

        self.listWidget.setFocus()
        self.searchExecutionButton.setFocus()

    def about(self):
        text = get_resources('about.txt')
        QMessageBox.about(self, 'About the Calibre Book Brainz Plugin',
                          text.decode('utf-8'))

    def config(self):
        self.do_user_config(parent=self)
        # Apply the changes
        self.label.setText(prefs['hello_world_msg'])
Esempio n. 4
0
class CustomColumnWizard(SizePersistedDialog, Logger):

    STEP_ONE = _("Name your '{0}' column:")

    YELLOW_BG = '<font style="background:#FDFF99">{0}</font>'

    def __init__(self, parent, column_type, profile, verbose=True):
        super(CustomColumnWizard,
              self).__init__(parent, 'annotations plugin:custom column wizard')
        self.column_type = column_type
        self.db = parent.gui.current_db
        self.gui = parent.gui
        self.modified_column = None
        self.previous_name = None
        self.profile = profile

        self.verbose = verbose
        self._log_location()

        self.setWindowTitle(_('Custom column wizard'))
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        title_layout = ImageTitleLayout(self,
                                        '../images/wizard.png',
                                        _('Custom column wizard'),
                                        has_help=False)
        layout.addLayout(title_layout)

        grid_layout = QGridLayout()
        layout.addLayout(grid_layout)

        self.calibre_destination_le = QLineEdit()
        grid_layout.addWidget(self.calibre_destination_le, 3, 1)
        self.step_1 = QLabel("1. Step 1", self)
        grid_layout.addWidget(self.step_1, 2, 1)

        self.bb = QDialogButtonBox(QDialogButtonBox.Cancel)
        layout.addWidget(self.bb)
        # Add the Accept button
        self.accept_button = self.bb.addButton('Button',
                                               QDialogButtonBox.AcceptRole)
        self.accept_button.setDefault(True)

        # Hook the QLineEdit box
        self.calibre_destination_le.textChanged.connect(
            self.validate_destination)

        self.populate_editor()

        self.highlight_step(1)

        # Hook the button events
        self.bb.clicked.connect(self.dispatch_button_click)

    def accept(self):
        self._log_location()
        super(CustomColumnWizard, self).accept()

    def close(self):
        self._log_location()
        super(CustomColumnWizard, self).close()

    def custom_column_add(self, requested_name, profile):
        '''
        Add the requested custom column with profile
        '''
        self._log_location(requested_name)
        self._log(profile)
        self.db.create_custom_column(profile['label'],
                                     requested_name,
                                     profile['datatype'],
                                     profile['is_multiple'],
                                     display=profile['display'])
        self.modified_column = {
            'destination': requested_name,
            'label': "#%s" % profile['label'],
            'previous': self.previous_name,
            'source': profile['source']
        }

    def custom_column_rename(self, requested_name, profile):
        '''
        The name already exists for label, update it
        '''
        self._log_location(requested_name)
        self._log(profile)

        # Find the existing
        for cf in self.db.custom_field_keys():
            #self._log(self.db.metadata_for_field(cf))
            mi = self.db.metadata_for_field(cf)
            if mi['label'] == profile['label']:
                self.db.set_custom_column_metadata(mi['colnum'],
                                                   name=requested_name,
                                                   label=mi['label'],
                                                   display=mi['display'])
                self.modified_column = {
                    'destination': requested_name,
                    'label': "#%s" % profile['label'],
                    'previous': self.previous_name,
                    'source': profile['source']
                }
                break

    def dispatch_button_click(self, button):
        '''
        BUTTON_ROLES = ['AcceptRole', 'RejectRole', 'DestructiveRole', 'ActionRole',
                        'HelpRole', 'YesRole', 'NoRole', 'ApplyRole', 'ResetRole']
        '''
        self._log_location()
        if self.bb.buttonRole(button) == QDialogButtonBox.AcceptRole:
            requested_name = str(self.calibre_destination_le.text())

            if requested_name in self.get_custom_column_names():
                self._log("'%s' already in use" % requested_name)
                warning_dialog(
                    self.gui,
                    _("Already in use"),
                    _("<p>'{0}' is an existing custom column.</p><p>Pick a different name.</p>"
                      ).format(requested_name),
                    show=True,
                    show_copy_button=False)

                self.calibre_destination_le.selectAll()
                self.calibre_destination_le.setFocus()

            else:
                source = self.column_type
                #profile = self.FIELDS[source]
                self.profile['source'] = source
                if button.objectName() == 'add_button':
                    self.custom_column_add(requested_name, self.profile)

                elif button.objectName() == 'rename_button':
                    self.custom_column_rename(requested_name, self.profile)
                self.accept()

        elif self.bb.buttonRole(button) == QDialogButtonBox.RejectRole:
            self.close()

    def esc(self, *args):
        self.close()

    def highlight_step(self, step):
        '''
        '''
        self._log_location(step)
        if step == 1:
            #self.step_1.setText(self.YELLOW_BG.format(self.STEP_ONE.format(self.column_type)))
            self.step_1.setText(self.STEP_ONE.format(self.column_type))

    def get_custom_column_names(self):
        '''
        '''
        self._log_location()
        existing_custom_names = []
        for cf in self.db.custom_field_keys():
            #self._log(self.db.metadata_for_field(cf))
            existing_custom_names.append(
                self.db.metadata_for_field(cf)['name'])
        return existing_custom_names

    def reset_accept_button(self, action="add_button", enabled=False):
        '''
        '''
        self.accept_button.setObjectName(action)
        if action == "add_button":
            self.accept_button.setText(_('Add custom column'))
            self.accept_button.setIcon(QIcon(I('plus.png')))
        elif action == "rename_button":
            self.accept_button.setText(_("Rename custom column"))
            self.accept_button.setIcon(QIcon(I('edit_input.png')))
        self.accept_button.setEnabled(enabled)

    def populate_editor(self):
        '''
        '''
        self._log_location()

        selected = self.column_type
        existing = None
        #label = self.FIELDS[selected]['label']
        label = self.profile['label']
        for cf in self.db.custom_field_keys():
            #self._log(self.db.metadata_for_field(cf))
            cfd = self.db.metadata_for_field(cf)
            if cfd['label'] == label:
                existing = cfd['name']
                break

        # Does label already exist?
        if existing:
            self.previous_name = existing
            self.calibre_destination_le.setText(existing)
            self.reset_accept_button(action="rename_button", enabled=True)
        else:
            # Populate the edit box with the default Column name
            self.calibre_destination_le.setText(selected)
            self.reset_accept_button(action="add_button", enabled=True)

        # Select the text
        self.calibre_destination_le.selectAll()
        self.calibre_destination_le.setFocus()

    def validate_destination(self, destination):
        '''
        Confirm length of column name > 0
        '''
        enabled = len(str(destination))
        self.accept_button.setEnabled(enabled)
Esempio n. 5
0
class LedgerAuthDialog(QDialog):
    def __init__(self, handler, data):
        '''Ask user for 2nd factor authentication. Support text, security card and paired mobile methods.
        Use last method from settings, but support new pairing and downgrade.
        '''
        QDialog.__init__(self, handler.top_level_window())
        self.handler = handler
        self.txdata = data
        self.idxs = self.txdata['keycardData'] if self.txdata['confirmationType'] > 1 else ''
        self.setMinimumWidth(600)
        self.setWindowTitle(_("Ledger Wallet Authentication"))
        self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
        self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle
        self.ws = None
        self.pin = ''
        
        self.devmode = self.getDevice2FAMode()
        if self.devmode == 0x11 or self.txdata['confirmationType'] == 1:
            self.cfg['mode'] = 0
        
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        
        def on_change_mode(idx):
            if idx < 2 and self.ws:
                self.ws.stop()
                self.ws = None
            self.cfg['mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1
            if self.cfg['mode'] > 1 and self.cfg['pair'] and not self.ws:
                self.req_validation()
            if self.cfg['mode'] > 0:
                self.handler.win.wallet.get_keystore().cfg = self.cfg
                self.handler.win.wallet.save_keystore()
            self.update_dlg()
        def add_pairing():
            self.do_pairing()
        def return_pin():
            self.pin = self.pintxt.text() if self.txdata['confirmationType'] == 1 else self.cardtxt.text() 
            if self.cfg['mode'] == 1:
                self.pin = ''.join(chr(int(str(i),16)) for i in self.pin)
            self.accept()
        
        self.modebox = QWidget()
        modelayout = QHBoxLayout()
        self.modebox.setLayout(modelayout)
        modelayout.addWidget(QLabel(_("Method:")))
        self.modes = QComboBox()
        modelayout.addWidget(self.modes, 2)
        self.addPair = QPushButton(_("Pair"))
        self.addPair.setMaximumWidth(60)
        modelayout.addWidget(self.addPair)
        modelayout.addStretch(1)
        self.modebox.setMaximumHeight(50)
        vbox.addWidget(self.modebox)
        
        self.populate_modes()
        self.modes.currentIndexChanged.connect(on_change_mode)
        self.addPair.clicked.connect(add_pairing)
        
        self.helpmsg = QTextEdit()
        self.helpmsg.setStyleSheet("QTextEdit { background-color: lightgray; }")
        self.helpmsg.setReadOnly(True)
        vbox.addWidget(self.helpmsg)
        
        self.pinbox = QWidget()
        pinlayout = QHBoxLayout()
        self.pinbox.setLayout(pinlayout)
        self.pintxt = QLineEdit()
        self.pintxt.setEchoMode(2)
        self.pintxt.setMaxLength(4)
        self.pintxt.returnPressed.connect(return_pin)
        pinlayout.addWidget(QLabel(_("Enter PIN:")))
        pinlayout.addWidget(self.pintxt)
        pinlayout.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        pinlayout.addStretch(1)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        vbox.addWidget(self.pinbox)
                    
        self.cardbox = QWidget()
        card = QVBoxLayout()
        self.cardbox.setLayout(card)
        self.addrtext = QTextEdit()
        self.addrtext.setStyleSheet("QTextEdit { color:blue; background-color:lightgray; padding:15px 10px; border:none; font-size:20pt; }")
        self.addrtext.setReadOnly(True)
        self.addrtext.setMaximumHeight(120)
        card.addWidget(self.addrtext)
        
        def pin_changed(s):
            if len(s) < len(self.idxs):
                i = self.idxs[len(s)]
                addr = self.txdata['address']
                addr = addr[:i] + '<u><b>' + addr[i:i+1] + '</u></b>' + addr[i+1:]
                self.addrtext.setHtml(str(addr))
            else:
                self.addrtext.setHtml(_("Press Enter"))
                
        pin_changed('')    
        cardpin = QHBoxLayout()
        cardpin.addWidget(QLabel(_("Enter PIN:")))
        self.cardtxt = QLineEdit()
        self.cardtxt.setEchoMode(2)
        self.cardtxt.setMaxLength(len(self.idxs))
        self.cardtxt.textChanged.connect(pin_changed)
        self.cardtxt.returnPressed.connect(return_pin)
        cardpin.addWidget(self.cardtxt)
        cardpin.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        cardpin.addStretch(1)
        card.addLayout(cardpin)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        vbox.addWidget(self.cardbox)
        
        self.pairbox = QWidget()
        pairlayout = QVBoxLayout()
        self.pairbox.setLayout(pairlayout)
        pairhelp = QTextEdit(helpTxt[5])
        pairhelp.setStyleSheet("QTextEdit { background-color: lightgray; }")
        pairhelp.setReadOnly(True)
        pairlayout.addWidget(pairhelp, 1)
        self.pairqr = QRCodeWidget()
        pairlayout.addWidget(self.pairqr, 4)
        self.pairbox.setVisible(False)
        vbox.addWidget(self.pairbox)
        self.update_dlg()
        
        if self.cfg['mode'] > 1 and not self.ws:
            self.req_validation()
        
    def populate_modes(self):
        self.modes.blockSignals(True)
        self.modes.clear()
        self.modes.addItem(_("Summary Text PIN (requires dongle replugging)") if self.txdata['confirmationType'] == 1 else _("Summary Text PIN is Disabled"))
        if self.txdata['confirmationType'] > 1:
            self.modes.addItem(_("Security Card Challenge"))
            if not self.cfg['pair']:
                self.modes.addItem(_("Mobile - Not paired")) 
            else:
                self.modes.addItem(_("Mobile - %s") % self.cfg['pair'][1]) 
        self.modes.blockSignals(False)
        
    def update_dlg(self):
        self.modes.setCurrentIndex(self.cfg['mode'])
        self.modebox.setVisible(True)
        self.addPair.setText(_("Pair") if not self.cfg['pair'] else _("Re-Pair"))
        self.addPair.setVisible(self.txdata['confirmationType'] > 2)
        self.helpmsg.setText(helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self.cfg['pair'] else 4])
        self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] == 1 else 100)
        self.pairbox.setVisible(False)
        self.helpmsg.setVisible(True)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        self.pintxt.setFocus(True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True)
        self.setMaximumHeight(200)
        
    def do_pairing(self):
        rng = os.urandom(16)
        pairID = (hexlify(rng) + hexlify(hashlib.sha256(rng).digest()[0:1])).decode('utf-8')
        self.pairqr.setData(pairID)
        self.modebox.setVisible(False)
        self.helpmsg.setVisible(False)
        self.pinbox.setVisible(False)
        self.cardbox.setVisible(False)
        self.pairbox.setVisible(True)
        self.pairqr.setMinimumSize(300,300)
        if self.ws:
            self.ws.stop()
        self.ws = LedgerWebSocket(self, pairID)
        self.ws.pairing_done.connect(self.pairing_done)
        self.ws.start() 
               
    def pairing_done(self, data):
        if data is not None:
            self.cfg['pair'] = [ data['pairid'], data['name'], data['platform'] ]
            self.cfg['mode'] = 2
            self.handler.win.wallet.get_keystore().cfg = self.cfg
            self.handler.win.wallet.save_keystore()
        self.pin = 'paired'
        self.accept()
    
    def req_validation(self):
        if self.cfg['pair'] and 'secureScreenData' in self.txdata:
            if self.ws:
                self.ws.stop()
            self.ws = LedgerWebSocket(self, self.cfg['pair'][0], self.txdata)
            self.ws.req_updated.connect(self.req_updated)
            self.ws.start()
              
    def req_updated(self, pin):
        if pin == 'accepted':
            self.helpmsg.setText(helpTxt[3])
        else:
            self.pin = str(pin)
            self.accept()
        
    def getDevice2FAMode(self):
        apdu = [0xe0, 0x24, 0x01, 0x00, 0x00, 0x01] # get 2fa mode
        try:
            mode = self.dongle.exchange( bytearray(apdu) )
            return mode
        except BTChipException as e:
            debug_msg('Device getMode Failed')
        return 0x11
    
    def closeEvent(self, evnt):
        debug_msg("CLOSE - Stop WS")
        if self.ws:
            self.ws.stop()
        if self.pairbox.isVisible():
            evnt.ignore()
            self.update_dlg()
Esempio n. 6
0
class LoginQDialog(QDialog):
    """
        Class who create login QDialog.
    """
    def __init__(self, parent=None):
        super(LoginQDialog, self).__init__(parent)
        self.setWindowTitle('Login to Alignak')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(310, 360)
        # Fields
        self.username_line = QLineEdit()
        self.password_line = QLineEdit()
        self.proxies = {}
        self.offset = None

    def create_widget(self):
        """
        Create widget login

        """

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)

        main_layout.addWidget(get_logo_widget(self, _('Login'), exitapp=True))

        # Login QWidget
        login_widget = QWidget(self)
        login_widget.setObjectName('dialog')
        login_layout = QGridLayout()
        login_widget.setLayout(login_layout)

        # _ = init_localization()
        title = QLabel(_('Welcome to Alignak-app'))
        title.setObjectName('itemtitle')
        title.setContentsMargins(1, 1, 1, 1)
        login_layout.addWidget(title, 0, 0, 1, 2)
        login_layout.setAlignment(title, Qt.AlignCenter)

        version = QLabel(_('Version %s') % __version__)
        version.setObjectName('subtitle')
        login_layout.addWidget(version, 1, 0, 1, 2)
        login_layout.setAlignment(version, Qt.AlignCenter | Qt.AlignTop)

        # Alignak server
        login_label = QLabel(_('Configure Alignak server'))
        login_layout.addWidget(login_label, 2, 0, 1, 1)
        login_layout.setAlignment(login_label, Qt.AlignRight)

        server_btn = QPushButton()
        server_btn.clicked.connect(self.handle_server)
        server_btn.setFixedSize(35, 35)
        server_btn.setIcon(QIcon(settings.get_image('server_settings')))
        server_btn.setToolTip(_('Configure Alignak Server'))
        login_layout.addWidget(server_btn, 2, 1, 1, 1)

        # Proxy settings
        proxy_lbl = QLabel(_('Configure Proxy'))
        login_layout.addWidget(proxy_lbl, 3, 0, 1, 1)
        login_layout.setAlignment(proxy_lbl, Qt.AlignRight)

        proxy_btn = QPushButton()
        proxy_btn.setIcon(QIcon(settings.get_image('password')))
        proxy_btn.setToolTip(_('Configure your Proxy'))
        proxy_btn.setFixedSize(35, 35)
        proxy_btn.clicked.connect(self.handle_proxy)
        login_layout.addWidget(proxy_btn, 3, 1, 1, 1)

        # Connection label
        connection_lbl = QLabel()
        connection_lbl.setText(_('<b>Log-in</b> to use the application'))
        connection_lbl.setWordWrap(True)
        login_layout.addWidget(connection_lbl, 4, 0, 1, 2)

        # Username field
        self.username_line.setFixedHeight(25)
        self.username_line.setPlaceholderText(_('username...'))
        login_layout.addWidget(self.username_line, 5, 0, 1, 2)

        # Password field
        self.password_line.setFixedHeight(25)
        self.password_line.setPlaceholderText(_('password...'))
        self.password_line.setEchoMode(QLineEdit.Password)
        login_layout.addWidget(self.password_line, 6, 0, 1, 2)

        # Login button
        login_button = QPushButton(_('LOGIN'), self)
        login_button.clicked.connect(self.accept_login)
        login_button.setObjectName('valid')
        login_button.setMinimumHeight(30)
        login_button.setDefault(True)
        login_layout.addWidget(login_button, 7, 0, 1, 2)

        main_layout.addWidget(login_widget)
        self.setLayout(main_layout)

        center_widget(self)

        if settings.get_config('Alignak', 'proxy_user'):
            self.handle_proxy()

    def accept_login(self):
        """
        Accept Login or not if backend is connected

        """

        username = str(self.username_line.text())
        password = str(self.password_line.text())

        # Set proxy only if in config
        if not self.proxies and settings.get_config('Alignak', 'proxy'):
            self.set_proxy_settings()

        if app_backend.login(username, password, proxies=self.proxies):
            self.accept()
        else:
            self.reject()

    def set_proxy_settings(self, proxy_password=None):
        """
        Set the proxy settings, with password if given

        :param proxy_password: the pasword of proxy
        :type proxy_password: str
        """

        if settings.get_config('Alignak', 'proxy_user'):
            # Model is: {'http': 'http://*****:*****@proxy:port'}
            protocol, address, port = settings.get_config('Alignak',
                                                          'proxy').split(':')
            proxy_user = settings.get_config('Alignak', 'proxy_user')
            address = address.replace('//', '')
            proxy = {
                protocol:
                '%s://%s:%s@%s:%s' %
                (protocol, proxy_user, proxy_password, address, port)
            }
            self.proxies = proxy
        elif settings.get_config('Alignak', 'proxy'):
            protocol = settings.get_config('Alignak', 'proxy').split(':')[0]
            self.proxies = {protocol: settings.get_config('Alignak', 'proxy')}
        else:
            self.proxies = {}

    def handle_proxy(self):  # pragma: no cover - not testable
        """
        Handle Proxy QDialog display and set proxies for login

        """

        proxy_dialog = ProxyQDialog()
        proxy_dialog.initialize_dialog()

        self.proxies = None

        if proxy_dialog.exec_() == ProxyQDialog.Accepted:
            proxy_address = proxy_dialog.proxy_address.text().rstrip()
            proxy_user = proxy_dialog.proxy_user.text().rstrip()
            proxy_password = proxy_dialog.proxy_password.text().rstrip()

            # Save proxy and user proxy for next login
            settings.set_config('Alignak', 'proxy', proxy_address)
            settings.set_config('Alignak', 'proxy_user', proxy_user)

            self.set_proxy_settings(proxy_password)

    @staticmethod
    def handle_server():  # pragma: no cover - not testable
        """
        Handle for Server QDialog and set alignak backend server settings

        """

        server_dialog = ServerQDialog()
        server_dialog.initialize_dialog()

        if server_dialog.exec_() == QDialog.Accepted:
            if server_dialog.server_port.text().rstrip():
                backend_url = '%(url)s:' + str(
                    server_dialog.server_port.text()).rstrip()
            else:
                backend_url = '%(url)s'
            settings.set_config('Alignak', 'backend', backend_url)
            settings.set_config('Alignak', 'url',
                                str(server_dialog.server_url.text()).rstrip())
            settings.set_config('Alignak', 'processes',
                                str(server_dialog.server_proc.text()).rstrip())
            settings.set_config(
                'Alignak', 'webservice',
                str(server_dialog.webservice_url.text()).rstrip())

    def showEvent(self, _):
        """ QDialog.showEvent(QShowEvent) """

        self.username_line.setFocus()

    def mousePressEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        self.offset = event.pos()

    def mouseMoveEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        try:
            x = event.globalX()
            y = event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x - x_w, y - y_w)
        except AttributeError as e:
            logger.warning('Move Event %s: %s', self.objectName(), str(e))
Esempio n. 7
0
class MFSSEL_UI(QMainWindow):
    def __init__(self):
        super().__init__()
        # 初始化UI
        self.initUI()
        # 创建action
        self.initAction()
        self.center()
        self.setWindowTitle("基于Spark的视频语义检测系统")
        self.setFixedSize(750, 600)
        self.__videoList = []

    def initUI(self):
        """
        初始化UI
        :return:
        """
        # QAction是一个抽象类,可以通过菜单栏,工具栏,或者快捷键实现,
        # 以下代码实现了带有图标和Exit的菜单的创建,同时设置了执行命令的快捷键以及鼠标悬停在这个菜单上的提示信息
        exitAct = QAction(QIcon('exit.ico'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Press and quit')

        # 执行此动作时,发射一个triggered信号,这个信号和quit连接,执行相关事件
        exitAct.triggered.connect(qApp.quit)

        # 状态栏
        self.statusBar()
        # tbar = self.addToolBar('Exit')
        # tbar.addAction(exitAct)

        # 服务器地址label
        self.label_serverAddress = QtWidgets.QLabel(self)
        self.label_serverAddress.setText("服务器地址:")
        self.label_serverAddress.resize(120, 30)
        self.label_serverAddress.move(30, 35)
        # 服务器地址
        self.textbox_serverAddress = QLineEdit(self)
        self.textbox_serverAddress.move(115, 35)

        # 用户名label
        self.label_userName = QtWidgets.QLabel(self)
        self.label_userName.setText("用户名:")
        # self.label_userName.resize(120, 30)
        self.label_userName.move(220, 35)
        # 用户名LineEdit
        self.textbox_userName = QLineEdit(self)
        self.textbox_userName.move(275, 35)

        # 密码label
        self.label_password = QtWidgets.QLabel(self)
        self.label_password.setText("密码:")
        # self.label_userName.resize(120, 30)
        self.label_password.move(380, 35)
        # 密码LineEdit
        self.textbox_password = QLineEdit(self)
        self.textbox_password.move(420, 35)
        self.textbox_password.setEchoMode(QLineEdit.Password)

        # 链接服务器按钮
        self.bt_connectServer = QPushButton('连接服服务器', self)
        self.bt_connectServer.clicked.connect(self.on_click)
        self.bt_connectServer.move(620, 35)
        # 菜单栏
        self.menubar = self.menuBar()

        # 打开menu
        self.menu_openvideos = QtWidgets.QMenu()
        self.menu_openvideos.setTitle("添加")
        self.menubar.addMenu(self.menu_openvideos)

        # 处理menu
        self.menu_dispose = QtWidgets.QMenu()
        self.menu_dispose.setTitle("处理")
        self.menubar.addMenu(self.menu_dispose)

        # 帮助menu
        self.menu_help = QtWidgets.QMenu()
        self.menu_help.setTitle("帮助")
        self.menubar.addMenu(self.menu_help)

        # 检测视频文件目录label
        self.label_videofiledir = QtWidgets.QLabel(self)
        self.label_videofiledir.setText("待检测视频列表:")
        self.label_videofiledir.resize(120, 30)
        self.label_videofiledir.move(380, 60)

        # 检测视频文件目录
        self.treeview_videofiledir = QtWidgets.QTreeView(self)
        self.treeview_videofiledir.resize(340, 480)
        self.treeview_videofiledir.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOn)
        self.treeview_videofiledir.setSizeAdjustPolicy(
            QtWidgets.QTreeView.AdjustToContents)
        self.treeview_videofiledir.header().setFixedWidth(700)
        self.model = QtGui.QStandardItemModel()
        self.model.setHorizontalHeaderItem(0, QtGui.QStandardItem("视频列表"))
        self.treeview_videofiledir.setModel(self.model)
        self.treeview_videofiledir.move(380, 90)

        # 播放视频的线程
        # self.playvideothread = pvt.PlayVideoThread()

        # 双击文件目录连接启动播放视频的线程
        self.treeview_videofiledir.doubleClicked.connect(
            self.startPlayVideoThread)

        # 视频播放label
        self.label_videoplay = QtWidgets.QLabel(self)
        self.label_videoplay.setText("视频播放:")
        self.label_videoplay.move(30, 60)

        # 显示视频框
        self.picturelabel = QtWidgets.QLabel(self)

        init_image = QPixmap(QDir.currentPath() + "/no_video.jpg").scaled(
            320, 240)
        self.picturelabel.setPixmap(init_image)
        self.picturelabel.resize(320, 240)
        self.picturelabel.move(30, 90)

        # 显示处理信息label
        self.label_showmessage = QtWidgets.QLabel(self)
        self.label_showmessage.setText("处理信息:")
        self.label_showmessage.move(30, 340)
        # 显示处理信息框
        self.textedit = QtWidgets.QTextEdit(self)
        self.textedit.setReadOnly(True)
        self.textedit.resize(320, 200)
        self.textedit.move(30, 370)

    def initAction(self):
        """
        创建action
        :return:
        """
        # 选取待检测视频menu的Action
        self.action_openvideos_choosevideos = QtWidgets.QAction(
            "添加视频到待检测视频列表", self)
        self.action_openvideos_choosevideos.triggered.connect(
            self.chooseVideos)
        self.action_openvideos_choosefolder = QtWidgets.QAction(
            "添加文件夹到待检测视频列表", self)
        self.action_openvideos_choosefolder.triggered.connect(
            self.chooseFolder)
        self.action_openvideos_clear = QtWidgets.QAction("清空待检测视频列表", self)
        self.action_openvideos_clear.triggered.connect(self.openVideos_clear)
        self.menu_openvideos.addAction(self.action_openvideos_choosevideos)
        self.menu_openvideos.addAction(self.action_openvideos_choosefolder)
        self.menu_openvideos.addAction(self.action_openvideos_clear)
        self.menu_openvideos.addSeparator()
        # 处理menu的Action
        self.action_keyframe = QtWidgets.QAction("Spark下关键帧提取", self)
        self.action_keyframe.setEnabled(False)
        self.action_keyframe.triggered.connect(self.extractKeyFrames)
        self.action_feature = QtWidgets.QAction("Spark下特征提取", self)
        self.action_feature.setEnabled(False)
        self.action_feature.triggered.connect(self.extractFeatures)
        self.action_trainmodel = QtWidgets.QAction("Spark下训练模型", self)
        self.action_trainmodel.setEnabled(False)
        self.action_trainmodel.triggered.connect(self.trainModel)
        self.action_detect = QtWidgets.QAction("检测视频", self)
        self.action_detect.triggered.connect(self.detectVideo)
        self.menu_dispose.addAction(self.action_keyframe)
        self.menu_dispose.addAction(self.action_feature)
        self.menu_dispose.addAction(self.action_trainmodel)
        self.menu_dispose.addAction(self.action_detect)
        self.menu_dispose.addSeparator()
        # 帮助menu的Action
        self.action_lookuphelp = QtWidgets.QAction("帮助", self)
        self.action_lookuphelp.triggered.connect(self.lookuphelpfile)
        self.action_about = QtWidgets.QAction("关于", self)
        self.action_about.triggered.connect(self.lookupaboutfile)
        self.menu_help.addAction(self.action_lookuphelp)
        self.menu_help.addAction(self.action_about)
        self.menu_help.addSeparator()

    def center(self):
        """
        控制窗口显示在屏幕中心的方法
        :return:
        """
        # 获得窗口
        qr = self.frameGeometry()
        # 获得屏幕中心点
        cp = QDesktopWidget().availableGeometry().center()
        # 显示到屏幕中心
        qr.moveCenter(cp)
        # self.move(qr.topLeft())
        self.move(320, 70)

    def on_click(self):
        """
        链接服务器按钮点击
        :return:
        """
        textbox_serverAddress_Value = self.textbox_serverAddress.text().strip()
        textbox_userName_Value = self.textbox_userName.text().strip()
        textbox_password_Value = self.textbox_password.text().strip()
        if (textbox_serverAddress_Value is
                "") or len(textbox_serverAddress_Value) == 0:
            QMessageBox.information(self, "注意", "服务器地址为空!")
            self.textbox_serverAddress.setFocus()
        elif (textbox_userName_Value is
              "") or len(textbox_userName_Value) == 0:
            QMessageBox.information(self, "注意", "用户名为空!")
            self.textbox_userName.setFocus()
        elif (textbox_password_Value is
              "") or len(textbox_password_Value) == 0:
            QMessageBox.information(self, "注意", "密码为空!")
            self.textbox_password.setFocus()
        try:
            self.ssh = paramiko.SSHClient()
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh.connect(hostname=textbox_serverAddress_Value,
                             username=textbox_userName_Value,
                             password=textbox_password_Value)
            # self.ssh.connect(hostname=hostname, username=username, password=password)
            stdin, stdout, stderr = self.ssh.exec_command('who')
            whoMess = repr(stdout.read().decode())
            search = whoMess.find(textbox_userName_Value)
            if search:
                info = '服务器连接成功。'
                self.flag = 1
                self.action_trainmodel.setEnabled(True)
                self.action_keyframe.setEnabled(True)
                self.action_feature.setEnabled(True)
            else:
                info = '服务器连接失败。'
                self.flag = 2
                self.action_trainmodel.setEnabled(False)
                self.action_keyframe.setEnabled(False)
                self.action_feature.setEnabled(False)

        except:
            info = '服务器连接失败。'
            self.flag = 2
            self.action_trainmodel.setEnabled(False)
            self.action_keyframe.setEnabled(False)
            self.action_feature.setEnabled(False)
        self.textedit.append(info)

    def chooseVideos(self):
        """
        选取要检测的视频加入到视频列表中
        :return:
        """
        files, filetype = QFileDialog.getOpenFileNames(
            None, "视频选择", os.path.expanduser("~"),
            "Video Files (*.avi *.mpg *.mp4)")
        if files:
            # 清空model
            self.openVideos_clear()
            self.__videoList = files
            videoItem = QtGui.QStandardItem(os.path.dirname(files[0]))
            videoItem.setEditable(False)
            for file in files:
                videoItemChild = QtGui.QStandardItem(os.path.basename(file))
                videoItemChild.setEditable(False)
                videoItem.appendRow(videoItemChild)
            self.model.appendRow(videoItem)
            self.treeview_videofiledir.setModel(self.model)

    def chooseFolder(self):
        """
        把文件夹中的视频加入视频列表中
        :return:
        """
        directory = QFileDialog.getExistingDirectory(None, "文件夹选择",
                                                     os.path.expanduser("~"))
        if os.path.isdir(directory):
            # 清空model
            self.openVideos_clear()
            # 遍历文件夹
            for dirpath, dirnames, filenames in os.walk(directory):
                for filename in filenames:
                    filePath = os.path.join(dirpath, filename)
                    self.__videoList.append(filePath)
                if filenames:
                    videoItem = QtGui.QStandardItem(dirpath)
                    videoItem.setEditable(False)
                    for filename in filenames:
                        # 获取文件名后缀,通过os.path.splitext(path)分离文件名和扩展名
                        ext = os.path.splitext(filename)[1]
                        # 将文件名统一转化为小写
                        ext = ext.lower()
                        if ext == '.avi' or ext == '.mpg' or ext == '.mp4':
                            videoItemChild = QtGui.QStandardItem(
                                os.path.basename(filename))
                            videoItemChild.setEditable(False)
                            videoItem.appendRow(videoItemChild)
                    self.model.appendRow(videoItem)
                    self.treeview_videofiledir.setModel(self.model)

    def openVideos_clear(self):
        """
        清空视频列表
        :return:
        """
        self.__videoList.clear()
        self.model.clear()
        headerItem = QtGui.QStandardItem("视频列表")
        headerItem.setEditable(False)
        self.model.setHorizontalHeaderItem(0, headerItem)
        self.treeview_videofiledir.setModel(self.model)
        init_image = QPixmap(QDir.currentPath() + "/no_video.jpg").scaled(
            320, 240)
        self.picturelabel.setPixmap(init_image)

    def startPlayVideoThread(self):
        """
        启动播放视频的线程
        :return:
        """
        # 获取选中的当前的Index
        index = self.treeview_videofiledir.selectionModel().currentIndex()
        # 如果当前Index有父节点,也就是说点击视频文件名
        if index.parent().data():
            # 视频的路径
            videopath = index.parent().data() + os.sep + index.data()
            self.playCapture = cv2.VideoCapture(videopath)
            fps = self.playCapture.get(cv2.CAP_PROP_FPS)
            self.timer = QTimer()
            self.timer.timeout.connect(self.playVideo)
            self.timer.start(1000 / fps)
            # self.playvideothread.setFps(fps)
            # # 连接播放视频槽
            # self.playvideothread.signal.connect(self.playVideo)
            # self.playvideothread.start()

    def playVideo(self):
        """
        播放视频
        :return:
        """
        if self.playCapture.isOpened():
            ret, frame = self.playCapture.read()
            if ret:
                # self.treeview_videofiledir.setDisabled(True)
                # 获取视频播放label的大小
                s = self.picturelabel.rect()
                # frame重置大小
                R_frame = cv2.resize(frame, (QRect.width(s), QRect.height(s)))
                if R_frame.ndim == 3:
                    R_frame_RGB = cv2.cvtColor(R_frame, cv2.COLOR_BGR2RGB)
                elif R_frame.ndim == 2:
                    R_frame_RGB = cv2.cvtColor(R_frame, cv2.COLOR_GRAY2BGR)
                qImage = QtGui.QImage(R_frame_RGB[:], R_frame_RGB.shape[1],
                                      R_frame_RGB.shape[0],
                                      QtGui.QImage.Format_RGB888)
                pixmap = QPixmap.fromImage(qImage)
                self.picturelabel.setPixmap(pixmap)
            else:
                # 释放VideoCapture
                self.playCapture.release()
                # 关闭线程
                self.timer.stop()
                # self.playvideothread.stop()
                # self.treeview_videofiledir.setDisabled(False)

    def extractKeyFrames(self):
        """
        关键帧提取
        :return:
        """
        if os.path.exists("/home/sunbite/MFSSEL/keyframe"):
            reply = QMessageBox.information(self, "注意", "已有关键帧信息,是否重新提取关键帧?",
                                            QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.startExtractKeyFramesThread()

            else:
                pass
        else:
            self.startExtractKeyFramesThread()

    def startExtractKeyFramesThread(self):
        """
        调用关键帧提取线程
        :return:
        """
        self.textedit.append("正在提取关键帧...")
        self.action_keyframe.setEnabled(False)
        self.action_feature.setEnabled(False)
        self.action_trainmodel.setEnabled(False)
        self.action_detect.setEnabled(False)
        self.extractKeyFramesThread = ExtractKeyFramesThread(
            self.receiveLogForExtractKeyFrames, self.ssh)
        # self.trainmodelthread.signal.connect(self.trainModel)
        self.extractKeyFramesThread.start()

    def receiveLogForExtractKeyFrames(self, msg):
        """
        接受log信息
        :param msg: log信息
        :return:
        """
        self.textedit.append(msg)
        self.extractKeyFramesThread.stop()
        self.action_keyframe.setEnabled(True)
        self.action_feature.setEnabled(True)
        self.action_trainmodel.setEnabled(True)
        self.action_detect.setEnabled(True)

    def extractFeatures(self):
        """
        特征提取
        :return:
        """
        if os.path.exists("/home/sunbite/MFSSEL/features"):
            reply = QMessageBox.information(self, "注意", "已有特征信息,是否重新提取特征?",
                                            QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                if os.path.exists("/home/sunbite/MFSSEL/keyframe"):
                    self.startExtractFeaturesThread()
                else:
                    QMessageBox.information(self, "注意", "关键帧信息不存在,请重新提取关键帧!")

            else:
                pass
        else:
            if os.path.exists("/home/sunbite/MFSSEL/keyframe"):
                self.startExtractFeaturesThread()
            else:
                QMessageBox.information(self, "注意", "关键帧信息不存在,请重新提取关键帧!")

    def startExtractFeaturesThread(self):
        """
        调用训练model线程
        :return:
        """
        self.textedit.append("正在提取特征...")
        self.action_keyframe.setEnabled(False)
        self.action_feature.setEnabled(False)
        self.action_trainmodel.setEnabled(False)
        self.action_detect.setEnabled(False)
        self.extractfeaturesThread = ExtractFeaturesThread(
            self.receiveLogForExtractFeatures, self.ssh)
        # self.trainmodelthread.signal.connect(self.trainModel)
        self.extractfeaturesThread.start()

    def receiveLogForExtractFeatures(self, msg):
        """
        接受log信息
        :param msg: log信息
        :return:
        """
        self.textedit.append(msg)
        self.extractfeaturesThread.stop()
        self.action_keyframe.setEnabled(True)
        self.action_feature.setEnabled(True)
        self.action_trainmodel.setEnabled(True)
        self.action_detect.setEnabled(True)

    def trainModel(self):
        """
        训练model
        :return:
        """
        if os.path.exists("/home/sunbite/MFSSEL/model"):
            reply = QMessageBox.information(self, "注意", "已有训练模型,是否重新训练模型?",
                                            QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                if os.path.exists("/home/sunbite/MFSSEL/keyframe"):
                    if os.path.exists("/home/sunbite/MFSSEL/features"):
                        self.startTrainModelThread()
                    else:
                        QMessageBox.information(self, "注意", "特征信息不存在,请重新提取特征!")
                else:
                    QMessageBox.information(self, "注意", "关键帧信息不存在,请重新提取关键帧!")

            else:
                pass
        else:
            if os.path.exists("/home/sunbite/MFSSEL/keyframe"):
                if os.path.exists("/home/sunbite/MFSSEL/features"):
                    self.startTrainModelThread()
                else:
                    QMessageBox.information(self, "注意", "特征信息不存在,请重新提取特征!")
            else:
                QMessageBox.information(self, "注意", "关键帧信息不存在,请重新提取关键帧!")

    def startTrainModelThread(self):
        """
        调用训练model线程
        :return:
        """
        self.textedit.append("正在训练模型...")
        self.action_keyframe.setEnabled(False)
        self.action_feature.setEnabled(False)
        self.action_trainmodel.setEnabled(False)
        self.action_detect.setEnabled(False)
        self.trainmodelthread = TrainModelThread(self.receiveLogForTrainModel,
                                                 self.ssh)
        # self.trainmodelthread.signal.connect(self.trainModel)
        self.trainmodelthread.start()

    def receiveLogForTrainModel(self, msg):
        """
        接受log信息
        :param msg: log信息
        :return:
        """
        self.textedit.append(msg)
        self.trainmodelthread.stop()
        self.action_keyframe.setEnabled(True)
        self.action_feature.setEnabled(True)
        self.action_trainmodel.setEnabled(True)
        self.action_detect.setEnabled(True)

    def detectVideo(self):
        """
        检测视频
        :return:
        """
        print(len(self.__videoList))
        if len(self.__videoList) == 0:
            reply = QMessageBox.information(self, "注意", "待检测视频为空,请添加待检测视频!",
                                            QMessageBox.Ok)
        else:
            if os.path.exists("/home/sunbite/MFSSEL/model"):
                self.startDetectVideoThread()
            else:
                QMessageBox.information(self, "注意", "模型不存在,请重新训练模型!")

    def startDetectVideoThread(self):
        """
        调用检测线程
        :return:
        """
        self.textedit.append("正在检测视频...")
        self.action_openvideos_choosevideos.setEnabled(False)
        self.action_openvideos_choosefolder.setEnabled(False)
        self.action_openvideos_clear.setEnabled(False)
        self.action_keyframe.setEnabled(False)
        self.action_feature.setEnabled(False)
        self.action_trainmodel.setEnabled(False)
        self.action_detect.setEnabled(False)
        self.detectvideothread = DetectVideoThread(
            self.receiveLogForDetectVideo, self.__videoList)
        # self.trainmodelthread.signal.connect(self.trainModel)
        self.detectvideothread.start()

    def receiveLogForDetectVideo(self, msg):
        """
        接受log信息
        :param msg: log信息
        :return:
        """
        self.textedit.append(msg)
        self.detectvideothread.stop()
        self.action_openvideos_choosevideos.setEnabled(True)
        self.action_openvideos_choosefolder.setEnabled(True)
        self.action_openvideos_clear.setEnabled(True)
        self.action_keyframe.setEnabled(True)
        self.action_feature.setEnabled(True)
        self.action_trainmodel.setEnabled(True)
        self.action_detect.setEnabled(True)

    def lookuphelpfile(self):
        """
        使用系统的浏览器打开帮助文档
        :return:
        """
        os.system(
            "firefox /home/sunbite/PycharmProjects/myFirstPoint/help.html")

    def lookupaboutfile(self):
        """
        使用系统的浏览器打开关于文档
        :return:
        """
        os.system(
            "firefox /home/sunbite/PycharmProjects/myFirstPoint/about.html")