Ejemplo n.º 1
0
def _set_rows(
        model: QtGui.QStandardItemModel,
        columns: Sequence[Column],
        tasks: Iterable[Task]) -> None:
    root_item = model.invisibleRootItem()
    for task in tasks:
        row = _build_row(task, columns)
        root_item.appendRow(row)
Ejemplo n.º 2
0
def get_item_by_index(index: EssModelIndex,
                      model: QStandardItemModel) -> EssStandardItem:
    ancestor_indexes = [index]
    while index.parent() != EssModelIndex():
        ancestor_indexes.append(index.parent())
        index = index.parent()
    ancestor_indexes.reverse()
    item = model.invisibleRootItem()
    for ancestor in ancestor_indexes:
        item = item.child(ancestor.row(), ancestor.column())
    return item
Ejemplo n.º 3
0
 def __init__(self, p):
     super().__init__()
     # enforce monospaced font:
     f = QFont("Monospace")
     f.setPointSize(8)
     self.setFont(f)
     self.setEditTriggers(QTreeView.NoEditTriggers)
     self.setSelectionMode(QTreeView.ExtendedSelection)
     m = QStandardItemModel()
     m.setColumnCount(3)
     m.setHorizontalHeaderLabels(["name", "value", "size"])
     r = m.invisibleRootItem()
     S = self.setup_(p)
     if S:
         r.appendRow(S)
     self.setModel(m)
     self.m = m
     self.setUniformRowHeights(True)
     self.header().setSectionResizeMode(QHeaderView.ResizeToContents)
     self.header().setFont(f)
Ejemplo n.º 4
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        #self.ui = ()
        self.setupUi(self)

        self.p: QProcess = None

        dirname = r"K:\Media Library"

        processing_dirs = getBaseDirs(dirname)

        s: QtCore.QSize = self.treeView.iconSize()
        self.message(f'size = {s}')
        s = QtCore.QSize(16, 16)  # Set icon sizing here
        self.treeView.setIconSize(s)

        style = QApplication.style()
        self.running_icon = style.standardIcon(QStyle.SP_BrowserReload)
        self.done_icon = style.standardIcon(QStyle.SP_DialogApplyButton)
        self.failed_icon = style.standardIcon(QStyle.SP_MessageBoxCritical)
        self.missing_icon = style.standardIcon(
            QStyle.SP_TitleBarContextHelpButton)
        self.added_icon = style.standardIcon(QStyle.SP_ArrowUp)
        self.warning_icon = style.standardIcon(QStyle.SP_MessageBoxWarning)

        self.checksum_sets = []

        for dirname in processing_dirs:
            self.checksum_sets.append(ChecksumSet(dirname))

        self.updateStats()

        self.populateModel()
        self.treeView.setModel(self.model)
        #   self.treeView.setExpandsOnDoubleClick(True)

        #      for x in self.iterItems(self.model.invisibleRootItem()):
        #    y = x.data(role=DisplayRole)
        #     z = x.data(role=UserRole)
        #    self.message(f'y = {y}, z = {z}')
        #    x.setText('hi')
        #         y = x.data(role=QtCore.Qt.UserRole)
        #        self.message(x.text())

        #        self.message('HI' + y.baseDirname)
        #        self.message('HI' + str(y))

        self.start_process()

    #   model.setHorizontalHeaderLabels(['Title', 'Summary'])
    #   rootItem = model.invisibleRootItem()

    #First top-level row and children
    #   item0 = [QStandardItem('Title0'), QStandardItem('Summary0')]

    #    item00 = [QStandardItem('Title00'), QStandardItem('Summary00')]
    #    item01 = [QStandardItem('Title01'), QStandardItem('Summary01')]
    #   rootItem.appendRow(item0)
    #    item0[0].appendRow(item00)
    #    item0[0].appendRow(item01)

    #Second top-level item and its children
    #    item1 = [QStandardItem('Title1'), QStandardItem('Summary1')]
    #    item10 = [QStandardItem('Title10'), QStandardItem('Summary10')]
    #    item11 = [QStandardItem('Title11'), QStandardItem('Summary11')]
    #    item12 = [QStandardItem('Title12'), QStandardItem('Summary12')]
    #    rootItem.appendRow(item1)
    #    item1[0].appendRow(item10)
    #    item1[0].appendRow(item11)
    #    item1[0].appendRow(item12)

    #Children of item11 (third level items)
    #    item110 = [QStandardItem('Title110'), QStandardItem('Summary110')]
    #    item111 = [QStandardItem('Title111'), QStandardItem('Summary111')]
    #    item11[0].appendRow(item110)
    #    item11[0].appendRow(item111)

    def toast_notification(self, title, text):
        AppID = 'zchecksum'
        XML = ToastNotificationManager.get_template_content(
            ToastTemplateType.TOAST_TEXT02)
        print(XML)
        t = XML.get_elements_by_tag_name("text")
        print(t)
        t[0].append_child(XML.create_text_node(title))
        t[1].append_child(XML.create_text_node(text))
        notifier = ToastNotificationManager.create_toast_notifier(AppID)
        notifier.show(ToastNotification(XML))

    def iterItems(self, root):
        if root is not None:
            for row in range(root.rowCount()):
                row_item = root.child(row, 0)
                if row_item.hasChildren():
                    for childIndex in range(row_item.rowCount()):
                        # Take second column from "child"-row
                        child = row_item.child(childIndex, 1)
                        yield child

    def format_size(self, size):
        if size < 0:
            raise Exception('Unknown file size')

        if size < 1024:
            return f'{size} Bytes'
        elif size < 1024 * 1024:
            size_kb = size / 1024
            return f'{size_kb:.1f} KB'
        elif size < 1024 * 1024 * 1024:
            size_mb = size / 1024 / 1024
            return f'{size_mb:.1f} MB'
        else:
            size_gb = size / 1024 / 1024 / 1024
            return f'{size_gb:.1f} GB'

    def populateModel(self):

        self.model = QStandardItemModel()
        self.model.setHorizontalHeaderLabels([
            'Status', 'Directory / Filename', 'File Count', 'Size', 'Checksum',
            'Last Verified'
        ])
        rootItem = self.model.invisibleRootItem()

        for checksum_set in self.checksum_sets:
            last_verified = ''
            status = ''
            if not checksum_set.hasSha512File():
                status = 'New'
            elif checksum_set.has_changes():
                status = "Modified"
                self.toast_notification("Checksum set was modified.",
                                        checksum_set.baseDirname)
            else:
                time_delta = datetime.now(
                ) - checksum_set.sha512File.last_verified
                last_verified = f'{time_delta.days} days ago'
                if time_delta.days > good_days:
                    status = 'Test'
                else:
                    status = 'Good'

            if status == 'Test' or status == 'New' or status == 'Modified':
                item = [
                    QStandardItem(status),
                    QStandardItem(checksum_set.baseDirname),
                    QStandardItem(str(len(checksum_set.filenames))),
                    QStandardItem(''),
                    QStandardItem(''),
                    QStandardItem(last_verified)
                ]
                for filename in checksum_set.filenames:
                    checksum_text = ''
                    file_status = ''
                    if checksum_set.sha512File:
                        checksum = checksum_set.sha512File.findChecksum(
                            filename)
                        if checksum:
                            checksum_text = checksum
                        else:
                            file_status = 'Added'
                    size = Path(checksum_set.baseDirname +
                                filename).stat().st_size
                    size_display = self.format_size(size)
                    #     sz = len(checksum_set.baseDirname) + len(filename)
                    c_item = [
                        QStandardItem(file_status),
                        QStandardItem(filename),
                        QStandardItem(''),
                        QStandardItem(size_display),
                        QStandardItem(checksum_text)
                    ]
                    c_item[1].setData(checksum_set, QtCore.Qt.UserRole)
                    if file_status == 'Added':
                        c_item[0].setIcon(self.added_icon)
                    if filename == 'Thumbs.db':
                        c_item[0].setIcon(self.warning_icon)
                    item[0].appendRow(c_item)
                if checksum_set.hasSha512File():
                    for filename in checksum_set.get_missing_from_dir():
                        checksum_text = checksum_set.sha512File.findChecksum(
                            filename)
                        c_item = [
                            QStandardItem('Missing'),
                            QStandardItem(filename),
                            QStandardItem(''),
                            QStandardItem('n/a'),
                            QStandardItem(checksum_text)
                        ]
                        c_item[1].setData(checksum_set, QtCore.Qt.UserRole)
                        c_item[0].setIcon(self.missing_icon)
                        item[0].appendRow(c_item)
                rootItem.appendRow(item)

    #    self.showIssues()

    #TODO: FIX, NOT WORKING!
    def showIssues(self):
        self.treeView.expandAll()
        root = self.model.invisibleRootItem()
        if root is not None:
            for row in range(root.rowCount()):
                row_item = root.child(row, 0)
                if row_item.hasChildren():
                    for childIndex in range(row_item.rowCount()):
                        # Take second column from "child"-row
                        child = row_item.child(childIndex, 1)

                        filename = child.text()
                        print(f'f = {filename}, {row_item.index()}')
                        if filename == 'Thumbs.db':
                            self.treeView.setExpanded(row_item.index(), True)
                        #   c_item[0].setIcon(self.warning_icon)
                        #   item[0].setExpanded(True)

    #   self.start_process()

    #   header = self.treeWidget.header()
    #  header

    #    header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
    #    header.setStretchLastSection(False)
    #   header.setSectionResizeMode(5, QtWidgets.QHeaderView.Stretch)

    def updateStats(self):
        new_count = 0
        modified_count = 0
        test_count = 0
        good_count = 0

        #    items = []
        for checksum_set in self.checksum_sets:
            if not checksum_set.hasSha512File():
                new_count += 1
            elif checksum_set.has_changes():
                modified_count += 1
            else:
                time_delta = datetime.now(
                ) - checksum_set.sha512File.last_verified
                if time_delta.days > good_days:
                    test_count += 1
                else:
                    good_count += 1

        self.statusBar().showMessage(
            f'Total sets: {len(self.checksum_sets)} sets.   New sets: {new_count}   Modified sets: {modified_count}   Test sets: {test_count}   Good sets: {good_count}'
        )

    def message(self, s):
        #    self.statusBar().showMessage(s)
        self.listWidget.addItem(s)

    def start_process(self):
        root = self.model.invisibleRootItem()

        started_count = 0

        if root is not None:
            for row in range(root.rowCount()):

                if self.p:
                    break

                row_item = root.child(row, 0)
                #  item = self.model.item(row)
                dir = root.child(row, 1)
                set_status = root.child(row, 0)

                #       self.message(dir.text())
                if (set_status.text() == "New" or set_status.text()
                        == 'Test') and row_item.hasChildren():
                    for childIndex in range(row_item.rowCount()):
                        # Take second column from "child"-row
                        #  status = row_item.child(childIndex, 0)

                        #   self.message(status.text())
                        #          if status.text() == 'New':
                        #              self.message(dir.text())

                        status = row_item.child(childIndex, 0)
                        filename = row_item.child(childIndex, 1)
                        #      self.message(filename.text())
                        #   checksum_item = row_item.child(childIndex, 4)

                        if status.text() != "Done":
                            #      parent = filename.parent()
                            #       self.message("parent " + str(parent))

                            self.run_process(dir.text(), filename.text(),
                                             row_item, childIndex)
                            started_count += 1

                            if self.p:
                                break

        self.message(f'start_process done.  Started {started_count}')

        #  yield child

#     for i in range(self.model.rowCount()):
#                 item = self.model.item(i)

#    root = self.treeWidget.invisibleRootItem()
#    child_count = root.childCount()
#    for i in range(child_count):
#        item = ro
# ot.child(i)
#       url = item.text(0) # text at first (0) column
#        item.setText(1, 'result from %s' % url) # update result column (1)

    def run_process(self, dir, filename, set_item, childIndex):
        if self.p is None:  # No process running.
            self.p_item = dict(set_item=set_item, child_index=childIndex)
            self.p = QProcess(
            )  # Keep a reference to the QProcess (e.g. on self) while it's running.

            #    item
            #       self.p.readyReadStandardOutput.connect(self.handle_stdout)
            self.p.readyReadStandardError.connect(self.handle_stderr)
            self.p.stateChanged.connect(self.handle_state)
            self.p.finished.connect(
                self.process_finished)  # Clean up once complete.

            #   filename = r"J:\Media Library\TV\New\Family Guy\Misc\Family Guy S07E11.avi"

            filepath = dir + filename
            self.message("Executing process for file: " + filepath)

            if Path(filepath).stat().st_size > 0:
                args = ["-hashfile", filepath, "SHA512"]
                self.p.start("certutil", args)
            else:
                # CertUtil cannot compute hashes on empty files
                args = ["zero_sha512.py"]
                self.p.start("python", args)

            status = set_item.child(childIndex, 0)

            status.setIcon(self.running_icon)
            set_item.setIcon(self.running_icon)

            if status.text() == '':
                if set_item.text() != 'Test':
                    set_item.child(childIndex, 0).setText('Running Pass 1/3')
                else:
                    set_item.child(childIndex, 0).setText('Running')
            elif status.text() == 'Running Pass 1/3':
                set_item.child(childIndex, 0).setText('Running Pass 2/3')
            elif status.text() == 'Running Pass 2/3':
                set_item.child(childIndex, 0).setText('Running Pass 3/3')

        else:
            self.message("process already running!")

    def handle_stderr(self):
        data = self.p.readAllStandardError()
        stderr = bytes(data).decode("utf8")
        # Extract progress if it is in the data.
        #     progress = simple_percent_parser(stderr)
        #     if progress:
        #         self.progress.setValue(progress)
        self.message(stderr)

    def handle_stdout(self):
        data = self.p.readAllStandardOutput()
        stdout = bytes(data).decode("utf8")
        self.message(stdout)

    def handle_state(self, state):
        states = {
            QProcess.NotRunning: 'Not running',
            QProcess.Starting: 'Starting',
            QProcess.Running: 'Running',
        }
        state_name = states[state]
        self.message(f"State changed: {state_name}")

    def process_finished(self, exitCode, exitStatus):

        row_item = self.p_item['set_item']
        child_index = self.p_item['child_index']
        status_item = row_item.child(child_index, 0)
        filename_item = row_item.child(child_index, 1)

        try:
            checksum_set = filename_item.data(QtCore.Qt.UserRole)

            if checksum_set is None:
                self.toast_notification(
                    "Checksum set not found.",
                    "No checksum set for file " + filename_item.text())
                raise Exception("No checksum set found")

            self.message(
                f'Process finished. exitCode = {exitCode}, exitStatus = {exitStatus}, baseDirname = {checksum_set.baseDirname}'
            )

            data = self.p.readAllStandardOutput()

            #       stdout = bytes(data)
            #      self.message("normal stdout: " + stdout)
            #  .decode('iso-8859-1').encode('utf8')
            #    stdout = bytes(data).decode("iso-8859-1")
            #try:
            stdout = bytes(data).decode('utf8', 'replace')
            #  except:
            #      stdout = bytes(data).decode('iso-8859-1')

            #   self.message("row_item" + row_item)
            self.message("stdout: " + stdout)

            lines = stdout.splitlines()

            if exitCode != 0 or len(lines) != 3:
                msg = f'Compute SHA512 failed.  stdout: ({stdout})'
                error_message = ''
                if len(lines) > 1 and lines[1].startswith("CertUtil: "):
                    error_message = lines[1][10:]

            #   msg = f'Error: Compute SHA512 failed for file {filename}.  stdout: ({cp.stdout}) stderr: ({cp.stderr})'
        #       print(msg)
                self.toast_notification(
                    'Failed to compute checksum. ' + error_message,
                    filename_item.text())
                raise Exception(msg)

            new_checksum = lines[1].replace(" ", "")

            checksum_item = row_item.child(child_index, 4)

            old_checksum = checksum_item.text()

            if old_checksum == "":
                checksum_item.setText(new_checksum)
            elif new_checksum != old_checksum:
                msg = f'Checksums do not match.'
                self.toast_notification('Checksums mismatch',
                                        filename_item.text())
                raise Exception(msg)

            if status_item.text() == "Running Pass 3/3" or status_item.text(
            ) == 'Running':
                status_item.setText('Done')
                status_item.setIcon(self.done_icon)

        #   checksum = QStandardItem()
        #   row_item.setChild(0, 4, checksum)
        # my_item.setText()

        #  my_item.setText(0, "Done")
        #  self.message("my_item: " + my_item.text(1))

    #     if self.all_files_done_checksum(row_item.parent()):
    #        self.create_sha_file(my_item.parent())

            if self.all_files_done_checksum(row_item):
                row_item.setIcon(self.done_icon)
                row_item.setText("Done")
                if checksum_set.hasSha512File():
                    self.message(
                        f'Updating {checksum_set.baseDirname} checksum file modified date'
                    )
                    checksum_set.update_modified()
                else:
                    self.create_sha_file(row_item)
        except Exception as e:
            status_item.setText("Failed")
            status_item.setIcon(self.failed_icon)
            row_item.setText("Failed")
            row_item.setIcon(self.failed_icon)
            self.message("Error: " + str(e))
        finally:
            self.p = None
            self.start_process()

    def all_files_done_checksum(self, set_item):
        for childIndex in range(set_item.rowCount()):
            status_item = set_item.child(childIndex, 0)
            checksum_item = set_item.child(childIndex, 4)
            filename_item = set_item.child(childIndex, 1)
            self.message(filename_item.text())

            if status_item.text() != 'Done' or checksum_item.text() == '':
                return False

        return True

    def create_sha_file(self, set_item):
        self.message("create_sha_file!!")

        # index = set_item.index()

        #  self.message(f'index = {index}')
        #  dirname = self.model.item(index, 1)

        #   dirname = set_item.data(1)

        dir = self.model.invisibleRootItem().child(set_item.row(), 1)

        dirname = dir.text()
        self.message(
            f'create_sha_file2, dir = {dir.text()}, row = {set_item.row()}, set_item.columnCount = {set_item.columnCount()}'
        )

        shaFile = Sha512(dirname)

        for childIndex in range(set_item.rowCount()):
            checksum_item = set_item.child(childIndex, 4)

            filename_item = set_item.child(childIndex, 1)
            self.message(filename_item.text())

            shaFile.addFileAndChecksum(filename_item.text(),
                                       checksum_item.text())

        shaFile.writeFile()
Ejemplo n.º 5
0
    model_size = 100000
    list = []
    source_model = QStandardItemModel()
    horizontal_header_list = [
        "First Column with spacing", "Second Column with spacing"
    ]
    source_model.setHorizontalHeaderLabels(horizontal_header_list)
    for i in range(model_size):
        first_item = QStandardItem("FancyTextNumber {}".format(i))
        if i == 0:
            first_item.appendRow(add_child(2, 2))
        second_item = QStandardItem("FancyRow2TextNumber {}".format(i))
        if i % 2 == 0:
            first_item.setBackground(Qt.red)
        row = [first_item, second_item]
        source_model.invisibleRootItem().appendRow(row)
        list.append("FancyTextNumber {}".format(i))

    # Needed by QMLModelViewClient
    role_names = {
        Qt.DisplayRole: QByteArray(b'_text'),
        Qt.BackgroundRole: QByteArray(b'_color')
    }
    source_model.setItemRoleNames(role_names)

    roles = [Qt.DisplayRole, Qt.BackgroundRole]

    print("Creating registry host")
    node = QRemoteObjectRegistryHost(QUrl("local:registry"))

    node2 = QRemoteObjectHost(QUrl("local:replica"), QUrl("local:registry"))