From 2a377780da41cc07558bd0b1f1d2fc12e96f02bd Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Nov 2021 10:20:05 -0700 Subject: [PATCH 1/2] intermission --- README.md | 2 +- assets/torrentfileQt.png | Bin 0 -> 20822 bytes requirements.txt | 8 -- torrentfileQt/checkTab.py | 171 ++++++++++++++++++-------------------- torrentfileQt/qss.py | 11 ++- 5 files changed, 85 insertions(+), 107 deletions(-) create mode 100644 assets/torrentfileQt.png diff --git a/README.md b/README.md index 32c1636..645fd20 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # TorrentfileQt -TorrentFileQt is a Graphical User Interface for [TorrentFile CLI](https://github.com/alexpdev/torrentfile). +TorrentFileQt is a GUI Frontend for [TorrentFile CLI](https://github.com/alexpdev/torrentfile) project. ## Features diff --git a/assets/torrentfileQt.png b/assets/torrentfileQt.png new file mode 100644 index 0000000000000000000000000000000000000000..70c69349c8653798a1cd7e4c51905263e80c49f8 GIT binary patch literal 20822 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 z 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
?}*j>q0kLE zlU}fh^aoBk^85z2@3XK)xn-ZfL#t@U*EJJjHBxU*ZBT*R(E7&g>QGBUgo{;zlNNN z#|bAElyGu-a`$%l$k^^AkjlX=ffRb}81JI32hHy2U|=1Ji+;Kog<_V&ibq82Eq(s$ z_LMqBrK+ovENOfz3VcDb;de4|egdX2FABu!1s@ADO;k?ta{-;W=BwwDcVij#U|3N( zl6e^Ijam5+K3C5m(1WlkA&;`%Vfa1TyB5rjh`^I}3(TDUyt1Kp#tMp={Ir|&#`bF6 z>-)O^-(S3-udc`Mo_S0d|{pL0rGRbJYqh9T;b^v?Y=Qgip9#IC2$@AcY!8dj1t}jpTMn|0=E={ywpI*&X z6X1dsfX8q5k0(1p4lc}YkQe4{&Q)(i%K$pwxFy`F=D54r%}%Y`=u>gQ$qyGJ_vb z?2FLXN6|d|OcA9yHnhucey6d*z{FF>0#Quq%z!Yiu+2>J_z4qS;w3M<+b0(Khj_5l zw6kJZSld6_J{#?#IT*2Z7xnu7E90N@uchO_h}iAii2fsFfjKKN5h2^-D}Is80}W-8 zVHPnJXBqK42j0x@P5$gKEf&6zBc+icZPx3n8I5|PH<^U1vycTDEK^X6;p;!w>KnCD zX3@i1U9SO^2>m~S#5O~baY242z6V+iR&fhwY*Ew1zdM1EZg4%q)d$I9v-2Dppc;gy zHw6>GCE$Ob{fm!`noVZhWqdv-kZLkig!*4Xx&GGu9KXg;CWmq00JJULuKVw@0lr@U(R(Nfvo<AP%9DZKfA#Z}y zvNG$w!Uzt%Zxw8d28V z86Bc&vt!!J%k?ACYaUr|aNd$Q`ht5|9GOd`ao*}mf_+-|V_^--A_ze%tBt34p^?wJ zuUvF#P>4et9CL)P(dTlp^ag6j4kv$$_(d_Du%aeID-^LlSw+LuQ?dp2czyvg2Rt^BF__RSSC} zob|BghH7~y!=*s9kU>V01VEitnuOYH!kUt(44UA{n!lo2kkVE2_eT0C|2S z%5^ztw`2iba5ub}%`b1#_#x-{C###W@x2&bur+dDQcP_DakHsNkL!+4SBXkrFnSQ% zKWEvvC$I^2k06}>-?{C_&;;!gUFjhD-!3#~ZO~4xW)91NcSfn2yp*LY3h1(Rw8qx- z@=H#(0^|ea*#}7hQnPTouv}241_*Gm-emN>`be+Pk!%Ui+wFcC zGp#5Tgl)rt5gbjQ#8(mpi6nDfuUqT6g+@d_T7kGYgl!j~NJObC9Yy!prf0XxEIXWK zO#aJEJz7-gcqPasNNwNNg0ySC*waPD|0wqBt#yuUnI~j=7FODAwDPiFz;me$JGh+~ zoeaYm$n0X0ezky9O{wPRhVyP3BlRH2&ImHAtTF2ZG%3)Asf*;FxxvT55*zdUV`m z`+o65TIGAGXMnOhY;(%TWc$(ZTT~X1kj`{b^by(s;EcJ$cV!9klg@+yniN#7t9`gM zAvcB09-)qm2eeEh{8GdQPOiZeI%nY$A0528j#V_VB*Dsg@2Pk5%kuQKxNQbx4WM_7 zKv$DNC$v7I-z;_9`d&eZ_<-0nMcRgw1d}7#Lhg?^R~<2YFfw)vWJAv*ciaI^r*pf{ zqHL>jx%#{x61!aTbaFFQ+EHVL$iE+L0iSBEXekw zmaQ&R_KZI6I||#eisjO|A!6%daPoIFMvzwNhRPI$^egrY^o|*+3wB}>26^Ln1xloV z0`Z4PLjFT&CN1`Z-#??NAN+L&7LVy2-!%lwz<`6{rOi>_Zi_o0I>szr$ z2H{Lej%%GBV>{aPyLwWoBIYq5qi!?T0^DVYeEZ$(1zQ$~8#rO8YXHX@&;4dW3hEo2 znUvslm5pPk1|uB6w#v~a3;6Qz?|(KBQHejG-t}9*8pwbksBu0ty3Gk(dzAKX!WGmN zGzsK0Sr$3FTa!B%P1}=N*uE&Pu@Xa6ynZ$tbU`{Pm_gKm{mOOa)if|-&?y#AT>|VB T{%E5s+xZZE7Gqv+>Js}OqnRzu literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt index b9775cb..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +0,0 @@ -coverage>=5 -pyben -PyQt6 -PyQt6-Qt6 -PyQt6-sip -pytest -pytest-cov -torrentfile diff --git a/torrentfileQt/checkTab.py b/torrentfileQt/checkTab.py index f4ec67e..c6dbe46 100644 --- a/torrentfileQt/checkTab.py +++ b/torrentfileQt/checkTab.py @@ -18,10 +18,9 @@ ############################################################################## import os -from threading import Thread from collections.abc import Sequence -from PyQt6.QtCore import Qt, pyqtSignal +from PyQt6.QtCore import Qt, pyqtSignal, QThread from PyQt6.QtGui import QIcon from PyQt6.QtWidgets import ( QWidget, @@ -73,7 +72,7 @@ def __init__(self, parent=None): self.searchLabel.setAlignment(Qt.AlignmentFlag.AlignLeft) self.searchInput = LineEdit(parent=self) self.browseButton2 = BrowseFolders(parent=self) - self.checkButton = CheckButton("Check", parent=self) + self.checkButton = ReCheckButton("Check", parent=self) self.hlayout1.addWidget(self.fileInput) self.hlayout1.addWidget(self.browseButton1) @@ -101,65 +100,35 @@ def __init__(self, parent=None): self.searchInput.setObjectName("CheckWidget_searchInput") -class CheckButton(QPushButton): +class ReCheckButton(QPushButton): """Button Widget for validating torrent files against downloaded contents. Args: text (`str`): The text displayed on the button itself. parent (`QWidget`, default=None): This widgets parent widget. """ + process = None def __init__(self, text, parent=None): """Construct the CheckButton Widget.""" super().__init__(text, parent=parent) self.widget = parent + self.window = parent.window self.pressed.connect(self.submit) self.setCursor(Qt.CursorShape.PointingHandCursor) self.setStyleSheet(pushButtonSheet) - self.torrent = None - self.folder = None - - - @property - def textEdit(self): - return self.widget.textEdit - - @property - def treeWidget(self): - return self.widget.treeWidget - def submit(self): - self.treeWidget.clear() - self.textEdit.clear() - func1 = self.textEdit.callback - func2 = self.treeWidget.callback - CheckerClass.register_callbacks(func1, func2) - self.torrent = self.widget.fileInput.text() - self.folder = self.widget.searchInput.text() - self.widget.treeWidget.setRoot(self.folder) - thread = Thread(group=None, target=self.re_check_torrent) - thread.run() - # self.re_check_torrent() - - def re_check_torrent(self): - checker = CheckerClass(self.torrent, self.folder) - msg = f"Torrent Contents are {checker.result}% completely downloaded." - self.textEdit.insertPlainText(msg) - if self.treeWidget.paths: - last_path = self.treeWidget.paths[-1] - value = self.treeWidget.itemWidgets[last_path] - widget = value["widget"] - children = value["children"] - tally = total = 0 - for child in children: - tally += child.val - total += 100 - percent = int((tally / total) * 100) - self.treeWidget.removeItemWidget(widget, 2) - progressbar = Progress(parent=None) - progressbar.setValue(percent) - self.treeWidget.setItemWidget(widget, 2, progressbar) + self.tree = self.widget.treeWidget + self.textEdit = self.widget.textEdit + searchInput = self.widget.searchInput + fileInput = self.widget.fileInput + metafile = fileInput.text() + content = searchInput.text() + self.tree.setRoot(content) + CheckerClass.register_callback(self.textEdit.callback) + self.process = ReCheckThread(self.window, metafile, content, self.tree) + self.process.start() class BrowseTorrents(QToolButton): @@ -251,6 +220,7 @@ def __init__(self, type=0, tree=None): self.ChildIndicatorPolicy.DontShowIndicatorWhenChildless ) self.data_role = Qt.ItemDataRole.UserRole + self.setExpanded(True) self.tree = tree def set_top(self, path, icon): @@ -261,10 +231,10 @@ def set_icon(self, path): icon = QIcon(path) self.setIcon(0, icon) - def set_val(self, value): + def set_val(self, value, piece): self.val = value self.set_icon("./assets/percentage.png") - self.setText(1, f"Piece Patial Match: {value}") + self.setText(1, f"{piece.hex()}") progressbar = Progress() progressbar.setRange(0,100) progressbar.setValue(value) @@ -289,7 +259,8 @@ class TreeWidget(QTreeWidget): Args: parent(`QWidget`, default=None) """ - callback_activated = pyqtSignal() + new_path = pyqtSignal() + add_top_child = pyqtSignal([dict]) def __init__(self, parent=None): super().__init__(parent=parent) @@ -297,6 +268,8 @@ def __init__(self, parent=None): self.setStyleSheet(treeSheet + headerSheet) self.setColumnCount(3) self.setIndentation(10) + self.item = self.invisibleRootItem() + self.item.setExpanded(True) header = self.header() header.setSectionResizeMode(0, header.ResizeMode.ResizeToContents) header.setSectionResizeMode(1, header.ResizeMode.ResizeToContents) @@ -304,8 +277,9 @@ def __init__(self, parent=None): self.root = None self.itemWidgets = {} self.paths = [] - self.item_tree = {"widget" : self.invisibleRootItem()} - self.callback_activated.connect(self.performAction) + self.item_tree = {"widget" : self.item} + self.new_path.connect(self.performAction) + self.add_top_child def clear_data(self): self.clear() @@ -330,50 +304,10 @@ def performAction(self): progressbar.setValue(percent) self.setItemWidget(widget, 2, progressbar) - - def callback(self, response, path, size, total): - if path.startswith(self.root): - path = path.strip(self.root) - if path not in self.itemWidgets: - temp, partials = path, [] - while True: - root, base = os.path.split(temp) - if not base: - break - partials.insert(0,base) - temp = root - self.callback_activated.emit() - item_tree = self.item_tree - for i, partial in enumerate(partials): - if partial in item_tree: - item_tree = item_tree[partial] - continue - widget = item_tree["widget"] - item = TreePieceItem(type=0, tree=self) - item.set_top(partial, "./assets/folder.png") - widget.addChild(item) - item_tree[partial] = {"widget": item} - if i == len(partials) - 1: - progressbar = Progress() - self.setItemWidget(item, 2, progressbar) - self.itemWidgets[path] = {"children": [], "widget": item} - item_tree = item_tree[partial] - self.paths.append(path) - children = self.itemWidgets[path]["children"] - widget = self.itemWidgets[path]["widget"] - item2 = TreePieceItem(type=0, tree=self) - widget.addChild(item2) - amount = 0 if not response else 100 - item2.set_val(amount) - children.append(item2) - self.window.update() - self.window.repaint() - def setRoot(self, root): self.root = os.path.split(root)[0] - class LogTextEdit(QPlainTextEdit): def __init__(self, parent=None): super().__init__(parent=parent) @@ -391,4 +325,57 @@ def clear_data(self): def callback(self, msg): self.insertPlainText(msg) - self.insertPlainText("\n\n") + self.insertPlainText("\n") + + +class ReCheckThread(QThread): + def __init__(self, window, metafile, content, tree): + QThread.__init__(self) + self.window = window + self.metafile = metafile + self.content = content + self.tree = tree + + def run(self): + checker = CheckerClass(self.metafile, self.content) + for actual, expected, path, size in checker.iter_hashes(): + if path.startswith(self.tree.root): + path = path.strip(self.tree.root) + if path not in self.tree.itemWidgets: + self.tree.new_path.emit() + temp, partials = path, [] + while True: + root, base = os.path.split(temp) + if not base: + break + partials.insert(0,base) + temp = root + item_tree = self.tree.item_tree + for i, partial in enumerate(partials): + if partial in item_tree: + item_tree = item_tree[partial] + continue + widget = item_tree["widget"] + item = TreePieceItem(type=0, tree=self.tree) + item.set_top(partial, "./assets/folder.png") + widget.addChild(item) + item_tree[partial] = {"widget": item} + if i == len(partials) - 1: + progressbar = Progress() + self.tree.setItemWidget(item, 2, progressbar) + self.tree.itemWidgets[path] = { + "children": [], + "widget": item + } + item_tree = item_tree[partial] + self.tree.paths.append(path) + children = self.tree.itemWidgets[path]["children"] + widget = self.tree.itemWidgets[path]["widget"] + item2 = TreePieceItem(type=0, tree=self.tree) + widget.addChild(item2) + amount = 0 if actual != expected else 100 + item2.set_val(amount, expected) + children.append(item2) + self.window.update() + self.window.repaint() + self.tree.new_path.emit() diff --git a/torrentfileQt/qss.py b/torrentfileQt/qss.py index dc6a122..86a30e0 100644 --- a/torrentfileQt/qss.py +++ b/torrentfileQt/qss.py @@ -51,15 +51,14 @@ color: white; } QTreeWidget QProgressBar { - border: 2px solid #e57e22; - border-radius: 6px; + border: 8px solid black; + border-radius: 8px; text-align: center; } QTreeWidget QProgressBar::chunk { - background-color: #164caf; - width: 25px; + background-color: #3ab1de; + width: 20px; margin: 1px; - border-radius: 30px; } """ @@ -479,7 +478,7 @@ background-color: #646464; border: #1a1a1a 2px solid; color: #fff; - font: 9pt; + font: 7pt; border-radius: 4px; } """ From 5eafe9ddeb6e713faaa109d6a59258e9b5cf79c7 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Nov 2021 22:28:41 -0700 Subject: [PATCH 2/2] working --- coverage.xml | 352 +++++++++++++++++--------------------- tests/test_gui.py | 27 +-- torrentfileQt/checkTab.py | 205 +++++++++++----------- torrentfileQt/qss.py | 18 +- 4 files changed, 266 insertions(+), 336 deletions(-) diff --git a/coverage.xml b/coverage.xml index b0ded77..f14ddf9 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,12 +1,12 @@ - + C:\Users\asp\Documents\Code\repos\torrentfileQt - + @@ -209,27 +209,6 @@ - - - - - - - - - - - - - - - - - - - - - @@ -240,7 +219,7 @@ - + @@ -248,7 +227,7 @@ - + @@ -303,161 +282,162 @@ - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + - - - - - + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + - - + + + + - - - + + - - - - - - - - + + + + + + + + + - - - - - + + + - - - - - + + + + + + + + + + - - - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + @@ -468,44 +448,22 @@ - - - + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + @@ -997,28 +955,28 @@ - - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/tests/test_gui.py b/tests/test_gui.py index 8ee9de5..b84e458 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -211,32 +211,7 @@ def test_check_tab2(wind, ttorrent2): assert checktab.fileInput.text() != "" -def test_check_tab3(wind, ttorrent1): - root = ttorrent1 +def test_check_tab4(wind): checktab = wind.central.checkWidget tree_widget = checktab.treeWidget - tree_widget.setRoot(root) - path = Path(root).resolve() - parent = path.parent.parent - for path in parent.iterdir(): - tree_widget.callback(True, str(path), 10, 10) - tree_widget.performAction() assert tree_widget.invisibleRootItem() is not None - - -def test_check_tab4(wind, ttorrent1): - root = ttorrent1 - checktab = wind.central.checkWidget - tree_widget = checktab.treeWidget - tree_widget.setRoot(root) - tree_widget.clear_data() - assert tree_widget.invisibleRootItem() is not None - - -def test_check_tab5(wind, ttorrent2): - checktab = wind.central.checkWidget - testdir = os.path.dirname(ttorrent2) - checktab.browseButton1.browse(path=testdir) - checktab.browseButton2.browse(path=testdir) - checktab.checkButton.click() - assert checktab.textEdit.toPlainText() != "" diff --git a/torrentfileQt/checkTab.py b/torrentfileQt/checkTab.py index c6dbe46..ffb24e1 100644 --- a/torrentfileQt/checkTab.py +++ b/torrentfileQt/checkTab.py @@ -18,9 +18,10 @@ ############################################################################## import os +import logging from collections.abc import Sequence -from PyQt6.QtCore import Qt, pyqtSignal, QThread +from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtGui import QIcon from PyQt6.QtWidgets import ( QWidget, @@ -119,16 +120,18 @@ def __init__(self, text, parent=None): self.setStyleSheet(pushButtonSheet) def submit(self): - self.tree = self.widget.treeWidget - self.textEdit = self.widget.textEdit + tree = self.widget.treeWidget + textEdit = self.widget.textEdit searchInput = self.widget.searchInput fileInput = self.widget.fileInput metafile = fileInput.text() content = searchInput.text() - self.tree.setRoot(content) - CheckerClass.register_callback(self.textEdit.callback) - self.process = ReCheckThread(self.window, metafile, content, self.tree) - self.process.start() + tree.setRoot(content) + CheckerClass.register_callback(textEdit.callback) + logging.debug("Registering Callback, setting root") + piece_hasher(metafile, content, tree) + # tree.start_thread(metafile, content) + class BrowseTorrents(QToolButton): @@ -207,44 +210,58 @@ def browse(self, path=None): self.parent().searchInput.setText(path) -class ProgressBar(QProgressBar): - def __init__(self, parent=None): - super().__init__(parent=parent) - - class TreePieceItem(QTreeWidgetItem): def __init__(self, type=0, tree=None): super().__init__(type=type) - self.val = None - self.setChildIndicatorPolicy( - self.ChildIndicatorPolicy.DontShowIndicatorWhenChildless - ) - self.data_role = Qt.ItemDataRole.UserRole - self.setExpanded(True) self.tree = tree + self.progressbar = None + policy = self.ChildIndicatorPolicy.DontShowIndicatorWhenChildless + self.setChildIndicatorPolicy(policy) + self.setExpanded(True) + self.total = 0 + self.length = 0 + + def setProgressBar(self, progressbar): + self.progressbar = progressbar + + def getProgressBar(self): + return self.progressbar def set_top(self, path, icon): - self.set_icon(icon) + pix = QIcon(icon) + self.setIcon(0, pix) self.setText(1, path) - def set_icon(self, path): - icon = QIcon(path) - self.setIcon(0, icon) + def setTotal(self, total): + self.total = total - def set_val(self, value, piece): - self.val = value - self.set_icon("./assets/percentage.png") - self.setText(1, f"{piece.hex()}") - progressbar = Progress() - progressbar.setRange(0,100) - progressbar.setValue(value) - self.tree.setItemWidget(self, 2, progressbar) + def add_piece(self, length): + self.length += length + if self.total > 0: + val = int(self.length / self.total * 100) + progressbar = self.getProgressBar() + progressbar.setValue(val) def __repr__(self): return f"" -class Progress(QProgressBar): +class Filler: + def __init__(self, **kwargs): + self.tree = kwargs["tree"] + self.value = None + self.expected = None + + def set_val(self, val, expected): + self.expected = expected + self.value = val + + def text(self): + if self.expected: + return self.expected + + +class ProgressBar(QProgressBar): def __init__(self, parent=None): super().__init__(parent=parent) self.setRange(0, 100) @@ -259,8 +276,8 @@ class TreeWidget(QTreeWidget): Args: parent(`QWidget`, default=None) """ - new_path = pyqtSignal() - add_top_child = pyqtSignal([dict]) + valueUpdate = pyqtSignal([list]) + addPathChild = pyqtSignal([str, int]) def __init__(self, parent=None): super().__init__(parent=parent) @@ -274,41 +291,53 @@ def __init__(self, parent=None): header.setSectionResizeMode(0, header.ResizeMode.ResizeToContents) header.setSectionResizeMode(1, header.ResizeMode.ResizeToContents) self.setHeaderHidden(True) - self.root = None self.itemWidgets = {} self.paths = [] + self.total = 0 self.item_tree = {"widget" : self.item} - self.new_path.connect(self.performAction) - self.add_top_child + self.valueUpdate.connect(self.updateValue) + self.addPathChild.connect(self.add_path_child) + + def updateValue(self, args): + actual, expected, path, size = args + widget = self.itemWidgets[path]["widget"] + if actual == expected: + widget.add_piece(size) + self.window.repaint() - def clear_data(self): - self.clear() + def clear(self): + super().clear() self.item_tree = {"widget" : self.invisibleRootItem()} self.itemWidgets = {} self.paths = [] self.root = None - def performAction(self): - if self.paths: - last_path = self.paths[-1] - value = self.itemWidgets[last_path] - widget = value["widget"] - children = value["children"] - tally = total = 0 - for child in children: - tally += child.val - total += 100 - percent = int((tally / total) * 100) - self.removeItemWidget(widget, 2) - progressbar = Progress(parent=None) - progressbar.setValue(percent) - self.setItemWidget(widget, 2, progressbar) - - def setRoot(self, root): - self.root = os.path.split(root)[0] + def add_path_child(self, path, size): + partials = path.split(os.sep) + item, item_tree = None, self.item_tree + for i, partial in enumerate(partials): + if partial in item_tree: + item_tree = item_tree[partial] + continue + widget = item_tree["widget"] + item = TreePieceItem(type=0, tree=self) + item.set_top(partial, "./assets/folder.png") + widget.addChild(item) + widget.setExpanded(True) + item_tree[partial] = {"widget": item} + if i == len(partials) - 1: + item.setTotal(size) + progressbar = ProgressBar() + self.setItemWidget(item, 2, progressbar) + item.setProgressBar(progressbar) + self.itemWidgets[path] = {"widget": item} + item_tree = item_tree[partial] + self.window.repaint() + self.paths.append(path) class LogTextEdit(QPlainTextEdit): + def __init__(self, parent=None): super().__init__(parent=parent) self._parent = parent @@ -316,7 +345,7 @@ def __init__(self, parent=None): font = self.font() font.setFamily("Consolas") font.setBold(True) - font.setPointSize(11) + font.setPointSize(8) self.setFont(font) self.setStyleSheet(logTextEditSheet) @@ -328,54 +357,14 @@ def callback(self, msg): self.insertPlainText("\n") -class ReCheckThread(QThread): - def __init__(self, window, metafile, content, tree): - QThread.__init__(self) - self.window = window - self.metafile = metafile - self.content = content - self.tree = tree - - def run(self): - checker = CheckerClass(self.metafile, self.content) - for actual, expected, path, size in checker.iter_hashes(): - if path.startswith(self.tree.root): - path = path.strip(self.tree.root) - if path not in self.tree.itemWidgets: - self.tree.new_path.emit() - temp, partials = path, [] - while True: - root, base = os.path.split(temp) - if not base: - break - partials.insert(0,base) - temp = root - item_tree = self.tree.item_tree - for i, partial in enumerate(partials): - if partial in item_tree: - item_tree = item_tree[partial] - continue - widget = item_tree["widget"] - item = TreePieceItem(type=0, tree=self.tree) - item.set_top(partial, "./assets/folder.png") - widget.addChild(item) - item_tree[partial] = {"widget": item} - if i == len(partials) - 1: - progressbar = Progress() - self.tree.setItemWidget(item, 2, progressbar) - self.tree.itemWidgets[path] = { - "children": [], - "widget": item - } - item_tree = item_tree[partial] - self.tree.paths.append(path) - children = self.tree.itemWidgets[path]["children"] - widget = self.tree.itemWidgets[path]["widget"] - item2 = TreePieceItem(type=0, tree=self.tree) - widget.addChild(item2) - amount = 0 if actual != expected else 100 - item2.set_val(amount, expected) - children.append(item2) - self.window.update() - self.window.repaint() - self.tree.new_path.emit() +def piece_hasher(metafile, content, tree): + checker = CheckerClass(metafile, content) + parent = os.path.dirname(content) + itemWidgets = [] + for actual, expected, path, size in checker.iter_hashes(): + relpath = path.lstrip(parent) + if relpath not in itemWidgets: + length = checker.fileinfo[path]["length"] + tree.addPathChild.emit(relpath, length) + itemWidgets.append(relpath) + tree.valueUpdate.emit([actual, expected, relpath, size]) diff --git a/torrentfileQt/qss.py b/torrentfileQt/qss.py index 86a30e0..2933537 100644 --- a/torrentfileQt/qss.py +++ b/torrentfileQt/qss.py @@ -51,14 +51,22 @@ color: white; } QTreeWidget QProgressBar { - border: 8px solid black; - border-radius: 8px; + background-color: #7a7a7a; + border: 1px solid black; + border-radius: 3px; + margin-left: 2px; + margin-right: 2px; text-align: center; } QTreeWidget QProgressBar::chunk { - background-color: #3ab1de; - width: 20px; - margin: 1px; + background-color: #3ae1de; + margin-left: .5px; + margin-right: .5px; + margin-top: 1px; + margin-bottom: 1px; + border-radius: 3px; + width: 16px; + } """