def createLogDisplay(self):
    logTextDisplay = QTextEdit()
    logTextDisplay.setFont(GETFONT('Fixed', 8))
    w,h = relaxedSizeNChar(logTextDisplay, 68)[0], int(12 * 8.2)
    logTextDisplay.setMinimumWidth(w)
    logTextDisplay.setMinimumHeight(h)
    logTextDisplay.setReadOnly(True)
    return logTextDisplay
示例#2
0
 def createLogDisplay(self):
     logTextDisplay = QTextEdit()
     logTextDisplay.setFont(GETFONT('Fixed', 8))
     w, h = relaxedSizeNChar(logTextDisplay, 68)[0], int(12 * 8.2)
     logTextDisplay.setMinimumWidth(w)
     logTextDisplay.setMinimumHeight(h)
     logTextDisplay.setReadOnly(True)
     return logTextDisplay
示例#3
0
class PrefsViewerDialog(SizePersistedDialog):
    def __init__(self, gui, namespace):
        SizePersistedDialog.__init__(self, gui, 'Prefs Viewer dialog')
        self.setWindowTitle('Preferences for: ' + namespace)

        self.db = gui.current_db
        self.namespace = namespace
        self._init_controls()
        self.resize_dialog()

        self._populate_settings()

        if self.keys_list.count():
            self.keys_list.setCurrentRow(0)

    def _init_controls(self):
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        ml = QHBoxLayout()
        layout.addLayout(ml, 1)

        self.keys_list = QListWidget(self)
        self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.keys_list.setFixedWidth(150)
        self.keys_list.setAlternatingRowColors(True)
        ml.addWidget(self.keys_list)
        self.value_text = QTextEdit(self)
        self.value_text.setTabStopWidth(24)
        self.value_text.setReadOnly(True)
        ml.addWidget(self.value_text, 1)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok)
        button_box.accepted.connect(self.accept)
        button_box.setCenterButtons(True)
        layout.addWidget(button_box)

    def _populate_settings(self):
        self.keys_list.clear()
        ns_prefix = 'namespaced:%s:' % self.namespace
        keys = sorted([
            k[len(ns_prefix):] for k in self.db.prefs.iterkeys()
            if k.startswith(ns_prefix)
        ])
        for key in keys:
            self.keys_list.addItem(key)
        self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0))
        self.keys_list.currentRowChanged[int].connect(
            self._current_row_changed)

    def _current_row_changed(self, new_row):
        if new_row < 0:
            self.value_text.clear()
            return
        key = unicode(self.keys_list.currentItem().text())
        val = self.db.prefs.get_namespaced(self.namespace, key, '')
        self.value_text.setPlainText(self.db.prefs.to_raw(val))
示例#4
0
class PrefsViewerDialog(SizePersistedDialog):
    
    def __init__(self, gui, namespace):
        SizePersistedDialog.__init__(self, gui, 'Prefs Viewer dialog')
        self.setWindowTitle('Preferences for: '+namespace)

        self.db = gui.current_db
        self.namespace = namespace
        self._init_controls()
        self.resize_dialog()
        
        self._populate_settings()
        
        if self.keys_list.count():
            self.keys_list.setCurrentRow(0)
        
    def _init_controls(self):
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        
        ml = QHBoxLayout()
        layout.addLayout(ml, 1)
        
        self.keys_list = QListWidget(self)
        self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.keys_list.setFixedWidth(150)
        self.keys_list.setAlternatingRowColors(True)
        ml.addWidget(self.keys_list)
        self.value_text = QTextEdit(self)
        self.value_text.setTabStopWidth(24)
        self.value_text.setReadOnly(True)
        ml.addWidget(self.value_text, 1)
 
        button_box = QDialogButtonBox(QDialogButtonBox.Ok)
        button_box.accepted.connect(self.accept)
        button_box.setCenterButtons(True)
        layout.addWidget(button_box)
        
    def _populate_settings(self):
        self.keys_list.clear()
        ns_prefix = 'namespaced:%s:'% self.namespace 
        keys = sorted([k[len(ns_prefix):] for k in self.db.prefs.iterkeys() 
                       if k.startswith(ns_prefix)])
        for key in keys:
            self.keys_list.addItem(key)
        self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0)) 
        self.keys_list.currentRowChanged[int].connect(self._current_row_changed)

    def _current_row_changed(self, new_row):
        if new_row < 0:
            self.value_text.clear()
            return
        key = unicode(self.keys_list.currentItem().text())
        val = self.db.prefs.get_namespaced(self.namespace, key, '')
        self.value_text.setPlainText(self.db.prefs.to_raw(val))
        
示例#5
0
class VersionHistoryDialog(SizePersistedDialog):
    def __init__(self, parent, plugin_name, html):
        SizePersistedDialog.__init__(self, parent, "Plugin Updater plugin:version history dialog")
        self.setWindowTitle(_("Version History for %s") % plugin_name)

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        self.notes = QTextEdit(html, self)
        self.notes.setReadOnly(True)
        layout.addWidget(self.notes)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Close)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)

        # Cause our dialog size to be restored from prefs or created on first usage
        self.resize_dialog()
class VersionHistoryDialog(SizePersistedDialog):

    def __init__(self, parent, plugin_name, html):
        SizePersistedDialog.__init__(self, parent, 'Plugin Updater plugin:version history dialog')
        self.setWindowTitle(_('Version History for %s')%plugin_name)

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        self.notes = QTextEdit(html, self)
        self.notes.setReadOnly(True)
        layout.addWidget(self.notes)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Close)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)

        # Cause our dialog size to be restored from prefs or created on first usage
        self.resize_dialog()
示例#7
0
class AboutWindow(QDialog):
    def __init__(self, html, width=600, timeout=None):
        QDialog.__init__(self)
        self.setMinimumWidth(width)
        self.setObjectName("About NanoEngineer-1")
        TextEditLayout = QVBoxLayout(self)
        TextEditLayout.setSpacing(0)
        TextEditLayout.setMargin(0)
        self.text_edit = QTextEdit(self)
        self.text_edit.setHtml(html)
        self.text_edit.setReadOnly(True)
        self.text_edit.setWordWrapMode(QTextOption.WordWrap)
        TextEditLayout.addWidget(self.text_edit)
        self.quit_button = QPushButton("OK")
        TextEditLayout.addWidget(self.quit_button)
        self.connect(self.quit_button, SIGNAL("clicked()"), self.close)
        if timeout is not None:
            self.qt = QTimer()
            self.qt.setInterval(1000*timeout)
            self.qt.start()
            self.connect(self.qt, SIGNAL("timeout()"), self.close)
        self.show()
        self.exec_()
示例#8
0
class AboutWindow(QDialog):
    def __init__(self, html, width=600, timeout=None):
        QDialog.__init__(self)
        self.setMinimumWidth(width)
        self.setObjectName("About NanoEngineer-1")
        TextEditLayout = QVBoxLayout(self)
        TextEditLayout.setSpacing(0)
        TextEditLayout.setMargin(0)
        self.text_edit = QTextEdit(self)
        self.text_edit.setHtml(html)
        self.text_edit.setReadOnly(True)
        self.text_edit.setWordWrapMode(QTextOption.WordWrap)
        TextEditLayout.addWidget(self.text_edit)
        self.quit_button = QPushButton("OK")
        TextEditLayout.addWidget(self.quit_button)
        self.connect(self.quit_button, SIGNAL("clicked()"), self.close)
        if timeout is not None:
            self.qt = QTimer()
            self.qt.setInterval(1000 * timeout)
            self.qt.start()
            self.connect(self.qt, SIGNAL("timeout()"), self.close)
        self.show()
        self.exec_()
示例#9
0
class CheckLibraryDialog(QDialog):

    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.db = db

        self.setWindowTitle(_('Check Library -- Problems Found'))
        self.setWindowIcon(QIcon(I('debug.png')))

        self._tl = QHBoxLayout()
        self.setLayout(self._tl)
        self.splitter = QSplitter(self)
        self.left = QWidget(self)
        self.splitter.addWidget(self.left)
        self.helpw = QTextEdit(self)
        self.splitter.addWidget(self.helpw)
        self._tl.addWidget(self.splitter)
        self._layout = QVBoxLayout()
        self.left.setLayout(self._layout)
        self.helpw.setReadOnly(True)
        self.helpw.setText(_('''\
        <h1>Help</h1>

        <p>calibre stores the list of your books and their metadata in a
        database. The actual book files and covers are stored as normal
        files in the calibre library folder. The database contains a list of the files
        and covers belonging to each book entry. This tool checks that the
        actual files in the library folder on your computer match the
        information in the database.</p>

        <p>The result of each type of check is shown to the left. The various
        checks are:
        </p>
        <ul>
        <li><b>Invalid titles</b>: These are files and folders appearing
        in the library where books titles should, but that do not have the
        correct form to be a book title.</li>
        <li><b>Extra titles</b>: These are extra files in your calibre
        library that appear to be correctly-formed titles, but have no corresponding
        entries in the database</li>
        <li><b>Invalid authors</b>: These are files appearing
        in the library where only author folders should be.</li>
        <li><b>Extra authors</b>: These are folders in the
        calibre library that appear to be authors but that do not have entries
        in the database</li>
        <li><b>Missing book formats</b>: These are book formats that are in
        the database but have no corresponding format file in the book's folder.
        <li><b>Extra book formats</b>: These are book format files found in
        the book's folder but not in the database.
        <li><b>Unknown files in books</b>: These are extra files in the
        folder of each book that do not correspond to a known format or cover
        file.</li>
        <li><b>Missing cover files</b>: These represent books that are marked
        in the database as having covers but the actual cover files are
        missing.</li>
        <li><b>Cover files not in database</b>: These are books that have
        cover files but are marked as not having covers in the database.</li>
        <li><b>Folder raising exception</b>: These represent folders in the
        calibre library that could not be processed/understood by this
        tool.</li>
        </ul>

        <p>There are two kinds of automatic fixes possible: <i>Delete
        marked</i> and <i>Fix marked</i>.</p>
        <p><i>Delete marked</i> is used to remove extra files/folders/covers that
        have no entries in the database. Check the box next to the item you want
        to delete. Use with caution.</p>

        <p><i>Fix marked</i> is applicable only to covers and missing formats
        (the three lines marked 'fixable'). In the case of missing cover files,
        checking the fixable box and pushing this button will tell calibre that
        there is no cover for all of the books listed. Use this option if you
        are not going to restore the covers from a backup. In the case of extra
        cover files, checking the fixable box and pushing this button will tell
        calibre that the cover files it found are correct for all the books
        listed. Use this when you are not going to delete the file(s). In the
        case of missing formats, checking the fixable box and pushing this
        button will tell calibre that the formats are really gone. Use this if
        you are not going to restore the formats from a backup.</p>

        '''))

        self.log = QTreeWidget(self)
        self.log.itemChanged.connect(self.item_changed)
        self.log.itemExpanded.connect(self.item_expanded_or_collapsed)
        self.log.itemCollapsed.connect(self.item_expanded_or_collapsed)
        self._layout.addWidget(self.log)

        self.check_button = QPushButton(_('&Run the check again'))
        self.check_button.setDefault(False)
        self.check_button.clicked.connect(self.run_the_check)
        self.copy_button = QPushButton(_('Copy &to clipboard'))
        self.copy_button.setDefault(False)
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        self.ok_button = QPushButton(_('&Done'))
        self.ok_button.setDefault(True)
        self.ok_button.clicked.connect(self.accept)
        self.delete_button = QPushButton(_('Delete &marked'))
        self.delete_button.setToolTip(_('Delete marked files (checked subitems)'))
        self.delete_button.setDefault(False)
        self.delete_button.clicked.connect(self.delete_marked)
        self.fix_button = QPushButton(_('&Fix marked'))
        self.fix_button.setDefault(False)
        self.fix_button.setEnabled(False)
        self.fix_button.setToolTip(_('Fix marked sections (checked fixable items)'))
        self.fix_button.clicked.connect(self.fix_items)
        self.bbox = QDialogButtonBox(self)
        self.bbox.addButton(self.check_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.delete_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.fix_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.copy_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.ok_button, QDialogButtonBox.AcceptRole)

        h = QHBoxLayout()
        ln = QLabel(_('Names to ignore:'))
        h.addWidget(ln)
        self.name_ignores = QLineEdit()
        self.name_ignores.setText(db.prefs.get('check_library_ignore_names', ''))
        self.name_ignores.setToolTip(
            _('Enter comma-separated standard file name wildcards, such as synctoy*.dat'))
        ln.setBuddy(self.name_ignores)
        h.addWidget(self.name_ignores)
        le = QLabel(_('Extensions to ignore'))
        h.addWidget(le)
        self.ext_ignores = QLineEdit()
        self.ext_ignores.setText(db.prefs.get('check_library_ignore_extensions', ''))
        self.ext_ignores.setToolTip(
            _('Enter comma-separated extensions without a leading dot. Used only in book folders'))
        le.setBuddy(self.ext_ignores)
        h.addWidget(self.ext_ignores)
        self._layout.addLayout(h)

        self._layout.addWidget(self.bbox)
        self.resize(950, 500)
        self.bbox.setEnabled(True)

    def do_exec(self):
        self.run_the_check()

        probs = 0
        for c in self.problem_count:
            probs += self.problem_count[c]
        if probs == 0:
            return False
        self.exec_()
        return True

    def accept(self):
        self.db.prefs['check_library_ignore_extensions'] = \
                                            unicode(self.ext_ignores.text())
        self.db.prefs['check_library_ignore_names'] = \
                                            unicode(self.name_ignores.text())
        QDialog.accept(self)

    def box_to_list(self, txt):
        return [f.strip() for f in txt.split(',') if f.strip()]

    def run_the_check(self):
        checker = CheckLibrary(self.db.library_path, self.db)
        checker.scan_library(self.box_to_list(unicode(self.name_ignores.text())),
                             self.box_to_list(unicode(self.ext_ignores.text())))

        plaintext = []

        def builder(tree, checker, check):
            attr, h, checkable, fixable = check
            list = getattr(checker, attr, None)
            if list is None:
                self.problem_count[attr] = 0
                return
            else:
                self.problem_count[attr] = len(list)

            tl = Item()
            tl.setText(0, h)
            if fixable and list:
                tl.setText(1, _('(fixable)'))
                tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                tl.setCheckState(1, False)
            self.top_level_items[attr] = tl

            for problem in list:
                it = Item()
                if checkable:
                    it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                    it.setCheckState(1, False)
                else:
                    it.setFlags(Qt.ItemIsEnabled)
                it.setText(0, problem[0])
                it.setData(0, Qt.UserRole, problem[2])
                it.setText(1, problem[1])
                tl.addChild(it)
                self.all_items.append(it)
                plaintext.append(','.join([h, problem[0], problem[1]]))
            tree.addTopLevelItem(tl)

        t = self.log
        t.clear()
        t.setColumnCount(2)
        t.setHeaderLabels([_('Name'), _('Path from library')])
        self.all_items = []
        self.top_level_items = {}
        self.problem_count = {}
        for check in CHECKS:
            builder(t, checker, check)

        t.resizeColumnToContents(0)
        t.resizeColumnToContents(1)
        self.delete_button.setEnabled(False)
        self.text_results = '\n'.join(plaintext)

    def item_expanded_or_collapsed(self, item):
        self.log.resizeColumnToContents(0)
        self.log.resizeColumnToContents(1)

    def item_changed(self, item, column):
        self.fix_button.setEnabled(False)
        for it in self.top_level_items.values():
            if it.checkState(1):
                self.fix_button.setEnabled(True)

        self.delete_button.setEnabled(False)
        for it in self.all_items:
            if it.checkState(1):
                self.delete_button.setEnabled(True)
                return

    def delete_marked(self):
        if not confirm('<p>'+_('The marked files and folders will be '
               '<b>permanently deleted</b>. Are you sure?')
               +'</p>', 'check_library_editor_delete', self):
            return

        # Sort the paths in reverse length order so that we can be sure that
        # if an item is in another item, the sub-item will be deleted first.
        items = sorted(self.all_items,
                       key=lambda x: len(x.text(1)),
                       reverse=True)
        for it in items:
            if it.checkState(1):
                try:
                    p = os.path.join(self.db.library_path ,unicode(it.text(1)))
                    if os.path.isdir(p):
                        delete_tree(p)
                    else:
                        delete_file(p)
                except:
                    prints('failed to delete',
                            os.path.join(self.db.library_path,
                                unicode(it.text(1))))
        self.run_the_check()

    def fix_missing_formats(self):
        tl = self.top_level_items['missing_formats']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            all = self.db.formats(id, index_is_id=True, verify_formats=False)
            all = set([f.strip() for f in all.split(',')]) if all else set()
            valid = self.db.formats(id, index_is_id=True, verify_formats=True)
            valid = set([f.strip() for f in valid.split(',')]) if valid else set()
            for fmt in all-valid:
                self.db.remove_format(id, fmt, index_is_id=True, db_only=True)

    def fix_missing_covers(self):
        tl = self.top_level_items['missing_covers']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            self.db.set_has_cover(id, False)

    def fix_extra_covers(self):
        tl = self.top_level_items['extra_covers']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            self.db.set_has_cover(id, True)

    def fix_items(self):
        for check in CHECKS:
            attr = check[0]
            fixable = check[3]
            tl = self.top_level_items[attr]
            if fixable and tl.checkState(1):
                func = getattr(self, 'fix_' + attr, None)
                if func is not None and callable(func):
                    func()
        self.run_the_check()

    def copy_to_clipboard(self):
        QApplication.clipboard().setText(self.text_results)
示例#10
0
    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()
示例#11
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 = rng.encode('hex') + hashlib.sha256(rng).digest()[0].encode(
            'hex')
        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, e:
            debug_msg('Device getMode Failed')
        return 0x11
class DownloadDialog(QDialog):

    def __init__(self, gui, icon, do_user_config):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.do_user_config = do_user_config

        # The current database shown in the GUI
        self.db = gui.current_db

        self.prefs = PrefsFacade(self.db)

        self.version = Downloader.version

        # The GUI, created and layouted by hand...
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.setWindowTitle('Beam EBooks Downloader')
        self.setWindowIcon(icon)

        self.log_area = QTextEdit('Log output', self)
        self.log_area.setReadOnly(True)
        self.log_area.setLineWrapMode(QTextEdit.NoWrap);
        self.log_area.setText("")
        self.layout.addWidget(self.log_area)

        self.download_button = QPushButton('Download books', self)
        self.download_button.clicked.connect(self.download)
        self.layout.addWidget(self.download_button)

        self.conf_button = QPushButton('Configure this plugin', self)
        self.conf_button.clicked.connect(self.config)
        self.layout.addWidget(self.conf_button)

        self.resize(self.sizeHint())


    def config(self):
        self.do_user_config(parent=self)
        # Apply the changes
        # Not necessary, the downloader will obtain fresh config anyway...
        # self.label.setText(prefs['hello_world_msg'])


    def notify(self, message = None):
        if message is not None:
            # insertPlainText inserts at the beginning of the log area...
            self.log_area.append(message)
            sb = self.log_area.verticalScrollBar()
            sb.setValue(sb.maximum())


    def download(self):
        prefs = self.prefs

        self.download_button.setEnabled(False)
        self.conf_button.setEnabled(False)

        downloader = BeamEbooksDownloader(self.prefs, self.version, caller = self)
        self.notify("Downloader is: %s" % (downloader))

        # Loop over all accounts until we have support for selection
        for account_id in prefs[prefs.ACCOUNTS]:
            account = prefs[prefs.ACCOUNTS][account_id]
            account[prefs.ACCOUNT_ID] = account_id

            if account[prefs.ENABLED]:
                self.enqueue(account, downloader)

        self.hide()


    def enqueue(self, account, downloader):
        prefs = self.prefs

        self.notify("Account: '%s'" % account[prefs.USERNAME])
        # downloader.login(account)

        func = 'arbitrary_n'
        # func = 'arbitrary'
        cpus = self.gui.job_manager.server.pool_size
        print "CPUs: %s" % (cpus)
        args = ['calibre_plugins.beam_ebooks_downloader.jobs', 'do_obtain_new_books', (cpus, account)]
        desc = 'Beam EBooks Downloader'
        job = self.gui.job_manager.run_job(Dispatcher(self._done), func, args=args, description=desc)
        print "Job: %s" % (job)

        self.notify("  Start parsing OPDS catalog")

        # if downloader.successful_login == False:
        #     self.notify("Failed to log in...")
        # else:
        #     self.notify("Scanning (beam) private library now...")
        #     downloader.recursive_descent(norms(prefs[prefs.URLBASE]))

    def _done(self, job):
        print "Done Downloading"
        print "Self: %s" % (self)
        print "Job: %s" % (job)
        # print "  Result: %s" % (job.result)
        # print "  Result: %s" % (len(job.result))
        self.notify("  Finished download catalog...")

        if job.result is not None:
            for entry in job.result:
                beamebooks_id = entry['id']
                message = "<br/>Ebook # %s" % (beamebooks_id)
                self.notify(message)

        self.download_button.setEnabled(True)
        self.conf_button.setEnabled(True)

        payload = job.result
        msg = "Parsing OPDS Catalog complete, found %s ebooks." % (len(job.result))
        msg = msg + "<br>Do you want to import the books into the library?"

        # question_dialog
        self.gui.proceed_question(self._add_ebooks, payload, job.details,
                    'OPDS Download Log', 'OPDS parse complete', msg, show_copy_button = False)


    def _done_2(self, job):
        print "Done Downloading"
        print "Self: %s" % (self)
        print "Job: %s" % (job)
        # print "  Result: %s" % (job.result)
        # print "  Result: %s" % (len(job.result))
        self.notify("  Finished download book...")


    def _add_ebooks(self, payload):
        print "Done Downloading, Step 2"
        print "Self: %s" % (self)
        # print "Payload: %s" % (payload)
        # Printing the complete payload at once gives [IOError 12] - Out of space (memory, that is...)
        self.notify("  Finished adding books...")
        for entry in payload:
            print "Entry: %s" % entry

            # TODO allow for checkbox list of entries to download
            func = 'arbitrary_n'
            # func = 'arbitrary'
            cpus = self.gui.job_manager.server.pool_size
            print "CPUs: %s" % (cpus)
            args = ['calibre_plugins.beam_ebooks_downloader.jobs', 'do_download_book', (cpus, entry)]
            desc = 'Beam EBooks Downloader'
            job = self.gui.job_manager.run_job(Dispatcher(self._done_2), func, args=args, description=desc)
            print "Job: %s" % (job)
class CheckLibraryDialog(QDialog):
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.db = db

        self.setWindowTitle(_('Check Library -- Problems Found'))
        self.setWindowIcon(QIcon(I('debug.png')))

        self._tl = QHBoxLayout()
        self.setLayout(self._tl)
        self.splitter = QSplitter(self)
        self.left = QWidget(self)
        self.splitter.addWidget(self.left)
        self.helpw = QTextEdit(self)
        self.splitter.addWidget(self.helpw)
        self._tl.addWidget(self.splitter)
        self._layout = QVBoxLayout()
        self.left.setLayout(self._layout)
        self.helpw.setReadOnly(True)
        self.helpw.setText(
            _('''\
        <h1>Help</h1>

        <p>calibre stores the list of your books and their metadata in a
        database. The actual book files and covers are stored as normal
        files in the calibre library folder. The database contains a list of the files
        and covers belonging to each book entry. This tool checks that the
        actual files in the library folder on your computer match the
        information in the database.</p>

        <p>The result of each type of check is shown to the left. The various
        checks are:
        </p>
        <ul>
        <li><b>Invalid titles</b>: These are files and folders appearing
        in the library where books titles should, but that do not have the
        correct form to be a book title.</li>
        <li><b>Extra titles</b>: These are extra files in your calibre
        library that appear to be correctly-formed titles, but have no corresponding
        entries in the database</li>
        <li><b>Invalid authors</b>: These are files appearing
        in the library where only author folders should be.</li>
        <li><b>Extra authors</b>: These are folders in the
        calibre library that appear to be authors but that do not have entries
        in the database</li>
        <li><b>Missing book formats</b>: These are book formats that are in
        the database but have no corresponding format file in the book's folder.
        <li><b>Extra book formats</b>: These are book format files found in
        the book's folder but not in the database.
        <li><b>Unknown files in books</b>: These are extra files in the
        folder of each book that do not correspond to a known format or cover
        file.</li>
        <li><b>Missing cover files</b>: These represent books that are marked
        in the database as having covers but the actual cover files are
        missing.</li>
        <li><b>Cover files not in database</b>: These are books that have
        cover files but are marked as not having covers in the database.</li>
        <li><b>Folder raising exception</b>: These represent folders in the
        calibre library that could not be processed/understood by this
        tool.</li>
        </ul>

        <p>There are two kinds of automatic fixes possible: <i>Delete
        marked</i> and <i>Fix marked</i>.</p>
        <p><i>Delete marked</i> is used to remove extra files/folders/covers that
        have no entries in the database. Check the box next to the item you want
        to delete. Use with caution.</p>

        <p><i>Fix marked</i> is applicable only to covers and missing formats
        (the three lines marked 'fixable'). In the case of missing cover files,
        checking the fixable box and pushing this button will tell calibre that
        there is no cover for all of the books listed. Use this option if you
        are not going to restore the covers from a backup. In the case of extra
        cover files, checking the fixable box and pushing this button will tell
        calibre that the cover files it found are correct for all the books
        listed. Use this when you are not going to delete the file(s). In the
        case of missing formats, checking the fixable box and pushing this
        button will tell calibre that the formats are really gone. Use this if
        you are not going to restore the formats from a backup.</p>

        '''))

        self.log = QTreeWidget(self)
        self.log.itemChanged.connect(self.item_changed)
        self.log.itemExpanded.connect(self.item_expanded_or_collapsed)
        self.log.itemCollapsed.connect(self.item_expanded_or_collapsed)
        self._layout.addWidget(self.log)

        self.check_button = QPushButton(_('&Run the check again'))
        self.check_button.setDefault(False)
        self.check_button.clicked.connect(self.run_the_check)
        self.copy_button = QPushButton(_('Copy &to clipboard'))
        self.copy_button.setDefault(False)
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        self.ok_button = QPushButton(_('&Done'))
        self.ok_button.setDefault(True)
        self.ok_button.clicked.connect(self.accept)
        self.delete_button = QPushButton(_('Delete &marked'))
        self.delete_button.setToolTip(
            _('Delete marked files (checked subitems)'))
        self.delete_button.setDefault(False)
        self.delete_button.clicked.connect(self.delete_marked)
        self.fix_button = QPushButton(_('&Fix marked'))
        self.fix_button.setDefault(False)
        self.fix_button.setEnabled(False)
        self.fix_button.setToolTip(
            _('Fix marked sections (checked fixable items)'))
        self.fix_button.clicked.connect(self.fix_items)
        self.bbox = QDialogButtonBox(self)
        self.bbox.addButton(self.check_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.delete_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.fix_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.copy_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.ok_button, QDialogButtonBox.AcceptRole)

        h = QHBoxLayout()
        ln = QLabel(_('Names to ignore:'))
        h.addWidget(ln)
        self.name_ignores = QLineEdit()
        self.name_ignores.setText(
            db.prefs.get('check_library_ignore_names', ''))
        self.name_ignores.setToolTip(
            _('Enter comma-separated standard file name wildcards, such as synctoy*.dat'
              ))
        ln.setBuddy(self.name_ignores)
        h.addWidget(self.name_ignores)
        le = QLabel(_('Extensions to ignore'))
        h.addWidget(le)
        self.ext_ignores = QLineEdit()
        self.ext_ignores.setText(
            db.prefs.get('check_library_ignore_extensions', ''))
        self.ext_ignores.setToolTip(
            _('Enter comma-separated extensions without a leading dot. Used only in book folders'
              ))
        le.setBuddy(self.ext_ignores)
        h.addWidget(self.ext_ignores)
        self._layout.addLayout(h)

        self._layout.addWidget(self.bbox)
        self.resize(950, 500)
        self.bbox.setEnabled(True)

    def do_exec(self):
        self.run_the_check()

        probs = 0
        for c in self.problem_count:
            probs += self.problem_count[c]
        if probs == 0:
            return False
        self.exec_()
        return True

    def accept(self):
        self.db.prefs['check_library_ignore_extensions'] = \
                                            unicode(self.ext_ignores.text())
        self.db.prefs['check_library_ignore_names'] = \
                                            unicode(self.name_ignores.text())
        QDialog.accept(self)

    def box_to_list(self, txt):
        return [f.strip() for f in txt.split(',') if f.strip()]

    def run_the_check(self):
        checker = CheckLibrary(self.db.library_path, self.db)
        checker.scan_library(
            self.box_to_list(unicode(self.name_ignores.text())),
            self.box_to_list(unicode(self.ext_ignores.text())))

        plaintext = []

        def builder(tree, checker, check):
            attr, h, checkable, fixable = check
            list = getattr(checker, attr, None)
            if list is None:
                self.problem_count[attr] = 0
                return
            else:
                self.problem_count[attr] = len(list)

            tl = Item()
            tl.setText(0, h)
            if fixable and list:
                tl.setText(1, _('(fixable)'))
                tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                tl.setCheckState(1, False)
            self.top_level_items[attr] = tl

            for problem in list:
                it = Item()
                if checkable:
                    it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                    it.setCheckState(1, False)
                else:
                    it.setFlags(Qt.ItemIsEnabled)
                it.setText(0, problem[0])
                it.setData(0, Qt.UserRole, problem[2])
                it.setText(1, problem[1])
                tl.addChild(it)
                self.all_items.append(it)
                plaintext.append(','.join([h, problem[0], problem[1]]))
            tree.addTopLevelItem(tl)

        t = self.log
        t.clear()
        t.setColumnCount(2)
        t.setHeaderLabels([_('Name'), _('Path from library')])
        self.all_items = []
        self.top_level_items = {}
        self.problem_count = {}
        for check in CHECKS:
            builder(t, checker, check)

        t.resizeColumnToContents(0)
        t.resizeColumnToContents(1)
        self.delete_button.setEnabled(False)
        self.text_results = '\n'.join(plaintext)

    def item_expanded_or_collapsed(self, item):
        self.log.resizeColumnToContents(0)
        self.log.resizeColumnToContents(1)

    def item_changed(self, item, column):
        self.fix_button.setEnabled(False)
        for it in self.top_level_items.values():
            if it.checkState(1):
                self.fix_button.setEnabled(True)

        self.delete_button.setEnabled(False)
        for it in self.all_items:
            if it.checkState(1):
                self.delete_button.setEnabled(True)
                return

    def delete_marked(self):
        if not confirm(
                '<p>' + _('The marked files and folders will be '
                          '<b>permanently deleted</b>. Are you sure?') +
                '</p>', 'check_library_editor_delete', self):
            return

        # Sort the paths in reverse length order so that we can be sure that
        # if an item is in another item, the sub-item will be deleted first.
        items = sorted(self.all_items,
                       key=lambda x: len(x.text(1)),
                       reverse=True)
        for it in items:
            if it.checkState(1):
                try:
                    p = os.path.join(self.db.library_path, unicode(it.text(1)))
                    if os.path.isdir(p):
                        delete_tree(p)
                    else:
                        delete_file(p)
                except:
                    prints(
                        'failed to delete',
                        os.path.join(self.db.library_path,
                                     unicode(it.text(1))))
        self.run_the_check()

    def fix_missing_formats(self):
        tl = self.top_level_items['missing_formats']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            all = self.db.formats(id, index_is_id=True, verify_formats=False)
            all = set([f.strip() for f in all.split(',')]) if all else set()
            valid = self.db.formats(id, index_is_id=True, verify_formats=True)
            valid = set([f.strip()
                         for f in valid.split(',')]) if valid else set()
            for fmt in all - valid:
                self.db.remove_format(id, fmt, index_is_id=True, db_only=True)

    def fix_missing_covers(self):
        tl = self.top_level_items['missing_covers']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            self.db.set_has_cover(id, False)

    def fix_extra_covers(self):
        tl = self.top_level_items['extra_covers']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = item.data(0, Qt.UserRole).toInt()[0]
            self.db.set_has_cover(id, True)

    def fix_items(self):
        for check in CHECKS:
            attr = check[0]
            fixable = check[3]
            tl = self.top_level_items[attr]
            if fixable and tl.checkState(1):
                func = getattr(self, 'fix_' + attr, None)
                if func is not None and callable(func):
                    func()
        self.run_the_check()

    def copy_to_clipboard(self):
        QApplication.clipboard().setText(self.text_results)
class PluginObject(object):

   tabName = 'Pass Phrase Finder'
   maxVersion = '0.93.99'
   
   #############################################################################
   def __init__(self, main):
      self.searchThread = None
      self.passPhraseFinder = None
      self.isSearchOver = False
      
      def updateResults(resultStr):
         self.resultStr += resultStr
         
      def updateDisplay():
         if len(self.resultStr) > 0:
            self.resultsDisplay.append(self.resultStr)
            self.resultStr = ''
            self.resultsDisplay.moveCursor(QtGui.QTextCursor.End)
            self.resultsDisplay.repaint()
         if self.isSearchOver:
            endSearch()
      
      # Call this from another thread to end the search
      def terminateSearch():
         self.isSearchOver = True
      
      # Call this from the main thread to end the search
      def endSearch():
         self.main.extraHeartbeatAlways.remove(updateDisplay)
         self.searchButton.setEnabled(True)
         self.stopButton.setEnabled(False)
         # If the thread is still searching tell the pass phrase finder to stop
         if self.passPhraseFinder and self.searchThread  and not self.searchThread.isFinished():
            self.passPhraseFinder.isStopped = True
            
      def searchForPassphrase():
         # Get the selected wallet from the main screen
         wlt = self.getSelectedWlt()
         if wlt and not wlt.watchingOnly and wlt.isLocked:
            self.resultStr = ''
            self.passPhraseFinder = PassPhraseFinder(wlt)
            self.resultsDisplay.setText(QString(''))
            self.main.extraHeartbeatAlways.append(updateDisplay)
            if len(self.segOrdStrSet) > 0:
               # From self.segOrdStrList, create a list of lists of indexes that describe the segment orderings to search
               # In other words convert all of the strings in orderings list to lists of integers
               segOrdIntListList = []
               for ordStr in self.segOrdStrSet:
                  # The indexes provided by the users are 1 based, and the list indexes ought to be 0 based
                  segOrdIntListList.append([int(indexStr)-1 for indexStr in ordStr.split(',')])
               self.searchThread = PyBackgroundThread(self.passPhraseFinder.searchForPassPhrase, 
                  [segDef.getSegList() for segDef in self.segDefList], 
                  segOrdIntListList, 
                  updateResults,
                  terminateSearch )
               # Reset the isSearchOver flag
               self.isSearchOver = False
               self.searchThread.start()
               
               # Disable search button adn enabled stop button
               self.stopButton.setEnabled(True)
               self.searchButton.setEnabled(False)
            else:
               QMessageBox.warning(self.main, tr('Invalid'), tr("""
                  There are no valid segment combinations to search.
                  Please add at least one segment and ordering to search."""), QMessageBox.Ok)
         else:
            QMessageBox.warning(self.main, tr('Invalid'), tr("""
               No valid wallet is selected. Please select a locked
               non-watching-only from Available Wallets."""), QMessageBox.Ok)

      def addKnownSegment():
         dlgEnterSegment = DlgEnterSegment(main, main)
         if dlgEnterSegment.exec_():
            segmentText = str(dlgEnterSegment.editSegment.text())
            if len(segmentText)>0:
               self.segDefList.append(KnownSeg(segmentText))
               self.segDefTableModel.updateSegList(self.segDefList)
      
      def addUnknownCaseSegment():
         dlgEnterSegment = DlgEnterSegment(main, main)
         if dlgEnterSegment.exec_():
            segmentText = str(dlgEnterSegment.editSegment.text())
            if len(segmentText)>0:
               self.segDefList.append(UnknownCaseSeg(segmentText))
               self.segDefTableModel.updateSegList(self.segDefList)
               
      def addUnknownOrderSegment():
         dlgEnterSegment = DlgEnterSegment(main, main, isUnknownOrder=True)
         if dlgEnterSegment.exec_():
            segmentText = str(dlgEnterSegment.editSegment.text())
            minLen = int(str(dlgEnterSegment.minSelector.currentText()))
            maxLen = int(str(dlgEnterSegment.maxSelector.currentText()))
            if len(segmentText)>0:
               self.segDefList.append(UnknownSeg(segmentText, minLen, maxLen))
               self.segDefTableModel.updateSegList(self.segDefList)

      def addOrdering():
         if len(self.segDefList) > 0:
            dlgSpecifyOrdering = DlgSpecifyOrdering(main, main, len(self.segDefList))     
            if dlgSpecifyOrdering.exec_():
               self.segOrdStrSet.add(str(dlgSpecifyOrdering.parseOrderingList()).strip('[]'))
               self.updateOrderingListBox()
         else:
            QMessageBox.warning(self.main, tr('Not Ready'), tr("""
               No segments have been entered. You must enter some segments before you can order them."""), QMessageBox.Ok)

      
      self.main = main
      self.segDefList = []
      self.segOrdStrSet = set()
      segmentHeader = QRichLabel(tr("""<b>Build segments for pass phrase search: </b>"""), doWrap=False)
      self.knownButton = QPushButton("Add Known Segment")
      self.unknownCaseButton = QPushButton("Add Unknown Case Segment")
      self.unknownOrderButton = QPushButton("Add Unknown Order Segment")
      self.main.connect(self.knownButton, SIGNAL('clicked()'), addKnownSegment)
      self.main.connect(self.unknownCaseButton, SIGNAL('clicked()'), addUnknownCaseSegment)
      self.main.connect(self.unknownOrderButton, SIGNAL('clicked()'), addUnknownOrderSegment)
      topRow =  makeHorizFrame([segmentHeader, self.knownButton, self.unknownCaseButton, self.unknownOrderButton, 'stretch'])
      
      self.segDefTableModel = SegDefDisplayModel()
      self.segDefTableView = QTableView()
      self.segDefTableView.setModel(self.segDefTableModel)
      self.segDefTableView.setSelectionBehavior(QTableView.SelectRows)
      self.segDefTableView.setSelectionMode(QTableView.SingleSelection)
      self.segDefTableView.verticalHeader().setDefaultSectionSize(20)
      self.segDefTableView.verticalHeader().hide()
      
      h = tightSizeNChar(self.segDefTableView, 1)[1]
      self.segDefTableView.setMinimumHeight(2 * (1.3 * h))
      self.segDefTableView.setMaximumHeight(10 * (1.3 * h))      
      initialColResize(self.segDefTableView, [.1, .2, .4, .1, .1, .1])

      self.segDefTableView.customContextMenuRequested.connect(self.showSegContextMenu)
      self.segDefTableView.setContextMenuPolicy(Qt.CustomContextMenu)
      
      segmentOrderingsHeader = QRichLabel(tr("""<b>Specify orderings for pass phrase search: </b>"""), doWrap=False)
      self.addOrderingButton = QPushButton("Add Ordering")
      
      
      self.main.connect(self.addOrderingButton, SIGNAL('clicked()'), addOrdering)
      orderingButtonPanel = makeHorizFrame([segmentOrderingsHeader, self.addOrderingButton, 'stretch'])

      self.segOrdListBox  = QListWidget()
      
      self.segOrdListBox.customContextMenuRequested.connect(self.showOrdContextMenu)
      self.segOrdListBox.setContextMenuPolicy(Qt.CustomContextMenu)
      
      
      self.searchButton = QPushButton("Search")
      self.main.connect(self.searchButton, SIGNAL('clicked()'), searchForPassphrase)
      self.stopButton = QPushButton("Stop Searching")
      self.stopButton.setEnabled(False)
      self.main.connect(self.stopButton, SIGNAL('clicked()'), endSearch)
      totalSearchLabel = QRichLabel(tr("""<b>Total Passphrase Tries To Search: </b>"""), doWrap=False)
      self.totalSearchTriesDisplay = QLineEdit()
      self.totalSearchTriesDisplay.setReadOnly(True)
      self.totalSearchTriesDisplay.setText(QString('0'))
      self.totalSearchTriesDisplay.setFont(GETFONT('Fixed'))
      self.totalSearchTriesDisplay.setMinimumWidth(tightSizeNChar(self.totalSearchTriesDisplay, 6)[0])
      self.totalSearchTriesDisplay.setMaximumWidth(tightSizeNChar(self.totalSearchTriesDisplay, 12)[0])
      searchButtonPanel = makeHorizFrame([self.searchButton, self.stopButton, 'stretch', totalSearchLabel,  self.totalSearchTriesDisplay])
      
      self.resultsDisplay = QTextEdit()
      self.resultsDisplay.setReadOnly(True)
      self.resultsDisplay.setFont(GETFONT('Fixed'))
      self.resultsDisplay.setMinimumHeight(100)
      self.searchPanel = makeVertFrame([topRow, self.segDefTableView, orderingButtonPanel,
             self.segOrdListBox, searchButtonPanel, self.resultsDisplay, 'stretch'])
      # Now set the scrollarea widget to the layout
      self.tabToDisplay = QScrollArea()
      self.tabToDisplay.setWidgetResizable(True)
      self.tabToDisplay.setWidget(self.searchPanel)
   
   def getSelectedWlt(self):
      wlt = None
      selectedWltList = self.main.walletsView.selectedIndexes()
      if len(selectedWltList)>0:
            row = selectedWltList[0].row()
            wltID = str(self.main.walletsView.model().index(row, WLTVIEWCOLS.ID).data().toString())
            wlt = self.main.walletMap[wltID]
      return wlt
   
   def showSegContextMenu(self):
      menu = QMenu(self.segDefTableView)
      if len(self.segDefTableView.selectedIndexes())==0:
         return

      row = self.segDefTableView.selectedIndexes()[0].row()
      deleteSegMenuItem = menu.addAction("Delete Segment")
      action = menu.exec_(QCursor.pos())
      
      if action == deleteSegMenuItem:
         self.deleteSegRow(row)
         
   def showOrdContextMenu(self):
      menu = QMenu(self.segOrdListBox)
      if len(self.segOrdListBox.selectedItems())==0:
         return

      item = self.segOrdListBox.currentItem()
      deleteOrdMenuItem = menu.addAction("Delete Ordering")
      action = menu.exec_(QCursor.pos())
      
      if action == deleteOrdMenuItem:
         self.deleteOrdItem(item)
         
   def deleteSegRow(self, row):
      self.segDefList.remove(self.segDefList[row])
      self.segDefTableModel.updateSegList(self.segDefList)
      self.segOrdStrSet.clear()
      self.updateOrderingListBox()
   
         
   def deleteOrdItem(self, ordItem):
      ordText = str(ordItem.text())
      self.segOrdStrSet.remove(ordText)
      self.updateOrderingListBox()
   
   
   def getTabToDisplay(self):
      return self.tabToDisplay

   def updateOrderingListBox(self):
      self.segOrdListBox.clear()
      segOrdList = list(self.segOrdStrSet)
      segOrdList.sort()
      totalTries = 0
      for ordStr in segOrdList:
         self.segOrdListBox.addItem(QListWidgetItem(ordStr))
         totalTries += self.calculateTries(ordStr)
      if totalTries > BILLION_INT:
         self.totalSearchTriesDisplay.setText(OVER_BILLION_STR)
      else:         
         self.totalSearchTriesDisplay.setText(str(totalTries))
      
   def calculateTries(self, ordStr):
      ordIntList = [int(indexStr) for indexStr in ordStr.split(',')]
      totalTries = 1
      # Multiply each of the totals of segment instance together.
      for ordInt in ordIntList:
         totalTries *= self.segDefList[ordInt-1].getSegListLen()
      return totalTries
示例#15
0
class IPETLogFileView(QWidget):
    StyleSheet = """
        QComboBox { color: darkblue; }
        QTextEdit { font-family : monospace;
                    font-size : 12px; }
        """
    """
    a view of a log file, with selection mechanisms for the desired test run and problem that should be shown
    """
    def __init__(self, parent=None):
        super(IPETLogFileView, self).__init__(parent)
        vlayout = QVBoxLayout(self)
        self.textbrowser = QTextEdit(self)
        self.textbrowser.setReadOnly(True)
        self.testrunselection = OptionsComboBox(self)
        self.problemselection = OptionsComboBox(self)
        vlayout.addWidget(self.textbrowser)
        self.setStyleSheet(self.StyleSheet)
        hlayout = QHBoxLayout()
        testrunselectionlabel = QLabel("Select a test run", self)
        problemselectionlabel = QLabel("Select an instance", self)
        testrunselectionlabel.setBuddy(self.testrunselection)
        problemselectionlabel.setBuddy(self.problemselection)
        for l, s in [(testrunselectionlabel, self.testrunselection),
                     (problemselectionlabel, self.problemselection)]:
            v = QVBoxLayout(self)
            v.addWidget(l)
            v.addWidget(s)
            hlayout.addLayout(v)
        vlayout.addLayout(hlayout)
        self.setLayout(vlayout)

        self.initConnections()

    def getProblem(self):
        problem = self.problemselection.currentText()
        return problem

    def getSelectedText(self):
        return self.textbrowser.textCursor().selection()

    def getLineSelectionIndex(self):
        c = self.textbrowser.textCursor()
        if c.anchor() < c.position():
            # normal left to right selection
            return (c.positionInBlock() -
                    (c.selectionEnd() - c.selectionStart()),
                    c.positionInBlock())
        else:
            return (c.positionInBlock(), c.positionInBlock() +
                    (c.selectionEnd() - c.selectionStart()))

    def getSelectedLine(self):
        cursor = self.textbrowser.textCursor()
        cursor.select(QTextCursor.LineUnderCursor)
        return str(cursor.selectedText())

    def getTestRun(self):
        testruntext = self.testrunselection.currentText()
        for t in ExperimentManagement.getExperiment().getTestRuns():
            if t.getName() == testruntext:
                return t
        return None

    def initConnections(self):
        for s in (self.testrunselection, self.problemselection):
            self.connect(s, SIGNAL("currentIndexChanged(int)"),
                         self.updateView)

    def updateExperimentData(self):
        self.testrunselection.clear()
        self.problemselection.clear()

        testruns = ExperimentManagement.getExperiment().getTestRuns()
        problems = ExperimentManagement.getExperiment().getProblemNames()

        self.testrunselection.addItems([t.getName() for t in testruns])
        self.problemselection.addItems([p for p in problems])

    def updateView(self):
        selectedtestrun = self.getTestRun()
        selectedproblem = self.getProblem()
        if selectedtestrun is None:
            return
        outfile = selectedtestrun.getLogFile()

        with open(outfile, 'r') as in_file:
            linesstart = selectedtestrun.getProblemDataById(
                str(selectedproblem), "LineNumbers_BeginLogFile")
            linesend = selectedtestrun.getProblemDataById(
                str(selectedproblem), "LineNumbers_EndLogFile")
            self.text = []
            for idx, line in enumerate(in_file):
                if idx > linesend:
                    break
                elif idx >= linesstart:
                    self.text.append(line)
            self.text = "".join(self.text)
            self.textbrowser.setText(self.text)
            self.textbrowser.update()
示例#16
0
class PrefsViewerDialog(SizePersistedDialog):
    def __init__(self, gui, namespace):
        SizePersistedDialog.__init__(self, gui, 'Prefs Viewer dialog')
        self.setWindowTitle('Preferences for: ' + namespace)

        self.gui = gui
        self.db = gui.current_db
        self.namespace = namespace
        self._init_controls()
        self.resize_dialog()

        self._populate_settings()

        if self.keys_list.count():
            self.keys_list.setCurrentRow(0)

    def _init_controls(self):
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        ml = QHBoxLayout()
        layout.addLayout(ml, 1)

        self.keys_list = QListWidget(self)
        self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.keys_list.setFixedWidth(150)
        self.keys_list.setAlternatingRowColors(True)
        ml.addWidget(self.keys_list)
        self.value_text = QTextEdit(self)
        self.value_text.setTabStopWidth(24)
        self.value_text.setReadOnly(False)
        ml.addWidget(self.value_text, 1)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self._apply_changes)
        button_box.rejected.connect(self.reject)
        self.clear_button = button_box.addButton('Clear',
                                                 QDialogButtonBox.ResetRole)
        self.clear_button.setIcon(get_icon('trash.png'))
        self.clear_button.setToolTip('Clear all settings for this plugin')
        self.clear_button.clicked.connect(self._clear_settings)
        layout.addWidget(button_box)

    def _populate_settings(self):
        self.keys_list.clear()
        ns_prefix = self._get_ns_prefix()
        keys = sorted([
            k[len(ns_prefix):] for k in self.db.prefs.iterkeys()
            if k.startswith(ns_prefix)
        ])
        for key in keys:
            self.keys_list.addItem(key)
        self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0))
        self.keys_list.currentRowChanged[int].connect(
            self._current_row_changed)

    def _current_row_changed(self, new_row):
        if new_row < 0:
            self.value_text.clear()
            return
        key = unicode(self.keys_list.currentItem().text())
        val = self.db.prefs.get_namespaced(self.namespace, key, '')
        self.value_text.setPlainText(self.db.prefs.to_raw(val))

    def _get_ns_prefix(self):
        return 'namespaced:%s:' % self.namespace

    def _apply_changes(self):
        from calibre.gui2.dialogs.confirm_delete import confirm
        message = '<p>Are you sure you want to change your settings in this library for this plugin?</p>' \
                  '<p>Any settings in other libraries or stored in a JSON file in your calibre plugins ' \
                  'folder will not be touched.</p>' \
                  '<p>You must restart calibre afterwards.</p>'
        if not confirm(message, self.namespace + '_clear_settings', self):
            return

        val = self.db.prefs.raw_to_object(
            unicode(self.value_text.toPlainText()))
        key = unicode(self.keys_list.currentItem().text())
        self.db.prefs.set_namespaced(self.namespace, key, val)

        restart = prompt_for_restart(
            self, 'Settings changed',
            '<p>Settings for this plugin in this library have been changed.</p>'
            '<p>Please restart calibre now.</p>')
        self.close()
        if restart:
            self.gui.quit(restart=True)

    def _clear_settings(self):
        from calibre.gui2.dialogs.confirm_delete import confirm
        message = '<p>Are you sure you want to clear your settings in this library for this plugin?</p>' \
                  '<p>Any settings in other libraries or stored in a JSON file in your calibre plugins ' \
                  'folder will not be touched.</p>' \
                  '<p>You must restart calibre afterwards.</p>'
        if not confirm(message, self.namespace + '_clear_settings', self):
            return

        ns_prefix = self._get_ns_prefix()
        keys = [k for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix)]
        for k in keys:
            del self.db.prefs[k]
        self._populate_settings()
        restart = prompt_for_restart(
            self, 'Settings deleted',
            '<p>All settings for this plugin in this library have been cleared.</p>'
            '<p>Please restart calibre now.</p>')
        self.close()
        if restart:
            self.gui.quit(restart=True)
示例#17
0
class ServiceControl(QDialog):
    SSHcnt =0
    HTTPcnt =0
    FTPcnt =0
    ip =''     

    
    def __init__(self, parent=None): 
        
        
        self.ip=''
        
        super(ServiceControl, self).__init__(parent)
        try:
            self.ip = ni.ifaddresses('eth0')[2][0]['addr']
            
            
        except:
            self.ip = 'No Network '
            
        

# servis etiketleri...........................        
        SSHLabel = QLabel('<center><font color="#2980B9" size="4"> SSH </font></center>')
        HTTPLabel = QLabel('<center><font color="#2980B9" size="4"> HTTP </font></center>')
        FTPLabel = QLabel('<center><font color="#2980B9" size="4"> FTP </font></center>')
        
# servis calisiyor etiketleri ..............................     
     
        self.SSHRLabel = QLabel()
        self.HTTPRLabel =QLabel()
        self.FTPRLabel =QLabel()
        
# servis Buttonlari.....................................        
        self.SSHBtn=QPushButton()
        self.HTTPBtn=QPushButton()
        self.FTPBtn=QPushButton()
        
# servis Buttonlarina tiklandigi zaman gidecekleri fonsiyonlar...................       
        
        self.SSHBtn.clicked.connect(self.SSH_Change)
        self.HTTPBtn.clicked.connect(self.HTTP_Change)
        self.FTPBtn.clicked.connect(self.FTP_Change)        
        
        self.HTTPRestart = QPushButton('Restart')       
        self.FTPRestart = QPushButton('Restart')        
        self.SSHRestart = QPushButton('Restart')
        
        self.SSHRestart.clicked.connect(self.SSH_Restart)
        self.HTTPRestart.clicked.connect(self.Http_Restart)
        self.FTPRestart.clicked.connect(self.Ftp_Restart) 
        
        
        
# logo...................................
        self.label = QLabel()
        self.pixmap = QPixmap(os.getcwd() + '/p2.png')
        self.label.setPixmap(self.pixmap)
    
        
       
        
# ssh kapaliysa kapali yaz... 

        Stringssh = commands.getoutput('/etc/init.d/ssh status')        
        Stringhttp = commands.getoutput('/etc/init.d/lighttpd status')
        Stringftp = os.system('/etc/init.d/vsftpd status')
        
        StringCheck = 'Active: inactive'

        Cssh = Stringssh.find('Active: active')
        Chttp = Stringhttp.find('Active: active')
        Cftp = Stringssh.find('Active: active')

    
        
        if Cssh != -1:
            self.SSHBtn.setText('DURDUR')
            self.SSHRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>')
            print('Aktif')
    
        else:
            self.SSHBtn.setText('BASLAT')
                       
            
        if Chttp !=-1:
            self.HTTPBtn.setText('DURDUR')
            self.HTTPRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>')
            print('Aktif')
        else:
            self.HTTPBtn.setText('BASLAT')
            
            
        if Cftp !=-1:
            self.FTPBtn.setText('DURDUR')
            self.FTPRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>')
            print('Aktif')
        else:
            self.FTPBtn.setText('BASLAT')


    
# alt kisim. ip ve kernel surumleri.............

        self.Text = QTextEdit()
        self.Text.setText('Pardus ARM Servis Kontrol'+'\n'+
                          'Host Name  : ' +
                          str(commands.getoutput("hostname")) + '\n'+
                          'Kernel  : '+
                          str(commands.getoutput("uname -r")) +'\n' 
                          +'IP Adress  : '+ self.ip)
        self.Text.setReadOnly(True)
        
        
        
# grid layout etiketleri ve buttonlari ekliyoruz.....................

        kutu = QHBoxLayout()
        kutu.addStretch(1)
        kutu.addWidget(self.label)
        
        
        grid = QGridLayout()
      #  grid.addWidget(kutu,3,0,0,0)
        grid.addWidget(self.label,3,0,4,4)
        
        grid.addWidget(SSHLabel,3,1)
        grid.addWidget(HTTPLabel,4,1)
        grid.addWidget(FTPLabel,5,1)
        
        grid.addWidget(self.SSHRLabel,3,2)
        grid.addWidget(self.HTTPRLabel,4,2)
        grid.addWidget(self.FTPRLabel,5,2)
        
        grid.addWidget(self.SSHBtn,3,3)
        grid.addWidget(self.HTTPBtn,4,3)
        grid.addWidget(self.FTPBtn,5,3)
        
        grid.addWidget(self.SSHRestart,3,4)
        grid.addWidget(self.HTTPRestart,4,4)
        grid.addWidget(self.FTPRestart,5,4)
        
        
        grid.addWidget(self.Text, 8, 0, 7, 4)      
        
        self.setLayout(grid)        
        self.setWindowTitle('Pardus Servis Control')
        self.setFixedSize(650, 350)
        
        
    def SSH_Change(self):
   
        if(self.SSHBtn.text()=='BASLAT'):
            os.system('/etc/init.d/ssh start')
            self.SSHBtn.setText('DURDUR')
            self.SSHRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>') 
            
                       
            
        else:
            os.system('/etc/init.d/ssh stop')
            self.SSHRLabel.setText('')            
            self.SSHBtn.setText('BASLAT')
            print('kapandi') 
            
    
    def HTTP_Change(self):
          
        if(self.HTTPBtn.text()=='BASLAT'):
            os.system('/etc/init.d/lighttpd start')
            self.HTTPBtn.setText('DURDUR')
            self.HTTPRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>') 
                        
            
        else:
            os.system('/etc/init.d/lighttpd stop') 
            self.HTTPBtn.setText('BASLAT')
            self.HTTPRLabel.setText('')
            print('kapandi') 
            
    def FTP_Change(self):
          
        if(self.FTPBtn.text()=='BASLAT'):
            os.system('/etc/init.d/vsftpd start')
            self.FTPBtn.setText('DURDUR')
            self.FTPRLabel.setText('<center><font color="#2980B9" size="2"> Runing... </font></center>') 
            print('acildi')                 
            
        else:
            os.system('/etc/init.d/vsftpd stop') 
            self.FTPBtn.setText('BASLAT')
            self.FTPRLabel.setText('')
            print('kapandi')         

            
            
    def SSH_Restart(self):
        os.system('/etc/init.d/ssh restart') 
        
    def Http_Restart(self):
        os.system('/etc/init.d/lighttpd restart')
        
    def Ftp_Restart(self):
        os.system('/etc/init.d/vsftpd restart')  

    def Close(self):
        
        self.close()
示例#18
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 = rng.encode('hex') + hashlib.sha256(rng).digest()[0].encode('hex')
        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, e:
            debug_msg('Device getMode Failed')
        return 0x11
示例#19
0
 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()
示例#20
0
class PrefsViewerDialog(SizePersistedDialog):

    def __init__(self, gui, namespace):
        SizePersistedDialog.__init__(self, gui, 'Prefs Viewer dialog')
        self.setWindowTitle('Preferences for: '+namespace)

        self.gui = gui
        self.db = gui.current_db
        self.namespace = namespace
        self._init_controls()
        self.resize_dialog()

        self._populate_settings()

        if self.keys_list.count():
            self.keys_list.setCurrentRow(0)

    def _init_controls(self):
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        ml = QHBoxLayout()
        layout.addLayout(ml, 1)

        self.keys_list = QListWidget(self)
        self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.keys_list.setFixedWidth(150)
        self.keys_list.setAlternatingRowColors(True)
        ml.addWidget(self.keys_list)
        self.value_text = QTextEdit(self)
        self.value_text.setTabStopWidth(24)
        self.value_text.setReadOnly(True)
        ml.addWidget(self.value_text, 1)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok)
        button_box.accepted.connect(self.accept)
        self.clear_button = button_box.addButton('Clear', QDialogButtonBox.ResetRole)
        self.clear_button.setIcon(get_icon('trash.png'))
        self.clear_button.setToolTip('Clear all settings for this plugin')
        self.clear_button.clicked.connect(self._clear_settings)
        layout.addWidget(button_box)

    def _populate_settings(self):
        self.keys_list.clear()
        ns_prefix = self._get_ns_prefix()
        keys = sorted([k[len(ns_prefix):] for k in self.db.prefs.iterkeys()
                       if k.startswith(ns_prefix)])
        for key in keys:
            self.keys_list.addItem(key)
        self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0))
        self.keys_list.currentRowChanged[int].connect(self._current_row_changed)

    def _current_row_changed(self, new_row):
        if new_row < 0:
            self.value_text.clear()
            return
        key = unicode(self.keys_list.currentItem().text())
        val = self.db.prefs.get_namespaced(self.namespace, key, '')
        self.value_text.setPlainText(self.db.prefs.to_raw(val))

    def _get_ns_prefix(self):
        return 'namespaced:%s:'% self.namespace

    def _clear_settings(self):
        from calibre.gui2.dialogs.confirm_delete import confirm
        message = '<p>Are you sure you want to clear your settings in this library for this plugin?</p>' \
                  '<p>Any settings in other libraries or stored in a JSON file in your calibre plugins ' \
                  'folder will not be touched.</p>' \
                  '<p>You must restart calibre afterwards.</p>'
        if not confirm(message, self.namespace+'_clear_settings', self):
            return
        ns_prefix = self._get_ns_prefix()
        keys = [k for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix)]
        for k in keys:
            del self.db.prefs[k]
        self._populate_settings()
        d = info_dialog(self, 'Settings deleted',
                    '<p>All settings for this plugin in this library have been cleared.</p>'
                    '<p>Please restart calibre now.</p>',
                    show_copy_button=False)
        b = d.bb.addButton(_('Restart calibre now'), d.bb.AcceptRole)
        b.setIcon(QIcon(I('lt.png')))
        d.do_restart = False
        def rf():
            d.do_restart = True
        b.clicked.connect(rf)
        d.set_details('')
        d.exec_()
        b.clicked.disconnect()
        self.close()
        if d.do_restart:
            self.gui.quit(restart=True)
class DownloadDialog(QDialog):
    def __init__(self, gui, icon, do_user_config):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.do_user_config = do_user_config

        # The current database shown in the GUI
        self.db = gui.current_db

        self.prefs = PrefsFacade(self.db)

        self.version = Downloader.version

        # The GUI, created and layouted by hand...
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.setWindowTitle('Beam EBooks Downloader')
        self.setWindowIcon(icon)

        self.log_area = QTextEdit('Log output', self)
        self.log_area.setReadOnly(True)
        self.log_area.setLineWrapMode(QTextEdit.NoWrap)
        self.log_area.setText("")
        self.layout.addWidget(self.log_area)

        self.download_button = QPushButton('Download books', self)
        self.download_button.clicked.connect(self.download)
        self.layout.addWidget(self.download_button)

        self.conf_button = QPushButton('Configure this plugin', self)
        self.conf_button.clicked.connect(self.config)
        self.layout.addWidget(self.conf_button)

        self.resize(self.sizeHint())

    def config(self):
        self.do_user_config(parent=self)
        # Apply the changes
        # Not necessary, the downloader will obtain fresh config anyway...
        # self.label.setText(prefs['hello_world_msg'])

    def notify(self, message=None):
        if message is not None:
            # insertPlainText inserts at the beginning of the log area...
            self.log_area.append(message)
            sb = self.log_area.verticalScrollBar()
            sb.setValue(sb.maximum())

    def download(self):
        prefs = self.prefs

        self.download_button.setEnabled(False)
        self.conf_button.setEnabled(False)

        downloader = BeamEbooksDownloader(self.prefs,
                                          self.version,
                                          caller=self)
        self.notify("Downloader is: %s" % (downloader))

        # Loop over all accounts until we have support for selection
        for account_id in prefs[prefs.ACCOUNTS]:
            account = prefs[prefs.ACCOUNTS][account_id]
            account[prefs.ACCOUNT_ID] = account_id

            if account[prefs.ENABLED]:
                self.enqueue(account, downloader)

        self.hide()

    def enqueue(self, account, downloader):
        prefs = self.prefs

        self.notify("Account: '%s'" % account[prefs.USERNAME])
        # downloader.login(account)

        func = 'arbitrary_n'
        # func = 'arbitrary'
        cpus = self.gui.job_manager.server.pool_size
        print "CPUs: %s" % (cpus)
        args = [
            'calibre_plugins.beam_ebooks_downloader.jobs',
            'do_obtain_new_books', (cpus, account)
        ]
        desc = 'Beam EBooks Downloader'
        job = self.gui.job_manager.run_job(Dispatcher(self._done),
                                           func,
                                           args=args,
                                           description=desc)
        print "Job: %s" % (job)

        self.notify("  Start parsing OPDS catalog")

        # if downloader.successful_login == False:
        #     self.notify("Failed to log in...")
        # else:
        #     self.notify("Scanning (beam) private library now...")
        #     downloader.recursive_descent(norms(prefs[prefs.URLBASE]))

    def _done(self, job):
        print "Done Downloading"
        print "Self: %s" % (self)
        print "Job: %s" % (job)
        # print "  Result: %s" % (job.result)
        # print "  Result: %s" % (len(job.result))
        self.notify("  Finished download catalog...")

        if job.result is not None:
            for entry in job.result:
                beamebooks_id = entry['id']
                message = "<br/>Ebook # %s" % (beamebooks_id)
                self.notify(message)

        self.download_button.setEnabled(True)
        self.conf_button.setEnabled(True)

        payload = job.result
        msg = "Parsing OPDS Catalog complete, found %s ebooks." % (len(
            job.result))
        msg = msg + "<br>Do you want to import the books into the library?"

        # question_dialog
        self.gui.proceed_question(self._add_ebooks,
                                  payload,
                                  job.details,
                                  'OPDS Download Log',
                                  'OPDS parse complete',
                                  msg,
                                  show_copy_button=False)

    def _done_2(self, job):
        print "Done Downloading"
        print "Self: %s" % (self)
        print "Job: %s" % (job)
        # print "  Result: %s" % (job.result)
        # print "  Result: %s" % (len(job.result))
        self.notify("  Finished download book...")

    def _add_ebooks(self, payload):
        print "Done Downloading, Step 2"
        print "Self: %s" % (self)
        # print "Payload: %s" % (payload)
        # Printing the complete payload at once gives [IOError 12] - Out of space (memory, that is...)
        self.notify("  Finished adding books...")
        for entry in payload:
            print "Entry: %s" % entry

            # TODO allow for checkbox list of entries to download
            func = 'arbitrary_n'
            # func = 'arbitrary'
            cpus = self.gui.job_manager.server.pool_size
            print "CPUs: %s" % (cpus)
            args = [
                'calibre_plugins.beam_ebooks_downloader.jobs',
                'do_download_book', (cpus, entry)
            ]
            desc = 'Beam EBooks Downloader'
            job = self.gui.job_manager.run_job(Dispatcher(self._done_2),
                                               func,
                                               args=args,
                                               description=desc)
            print "Job: %s" % (job)