1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2025-05-08 09:49:51 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
78fb052d77
Add more progress details to getmatches, ref #700 2021-08-28 04:58:22 -05:00
9805cba10d
Use different message for direct delete success, close #904 2021-08-28 04:27:34 -05:00
4c3dfe2f1f
Provide more feedback during scans
- Add output for number of collected files / folders
- Update to allow indeterminate progress bar
- Remove unused hscommon\jobprogress\qt.py
2021-08-28 04:05:07 -05:00
6 changed files with 33 additions and 64 deletions

View File

@ -308,11 +308,14 @@ class DupeGuru(Broadcaster):
self.problem_dialog.refresh() self.problem_dialog.refresh()
self.view.show_problem_dialog() self.view.show_problem_dialog()
else: else:
msg = { if jobid == JobType.COPY:
JobType.COPY: tr("All marked files were copied successfully."), msg = tr("All marked files were copied successfully.")
JobType.MOVE: tr("All marked files were moved successfully."), elif jobid == JobType.MOVE:
JobType.DELETE: tr("All marked files were successfully sent to Trash."), msg = tr("All marked files were moved successfully.")
}[jobid] elif jobid == JobType.DELETE and self.deletion_options.direct:
msg = tr("All marked files were deleted successfully.")
else:
msg = tr("All marked files were successfully sent to Trash.")
self.view.show_message(msg) self.view.show_message(msg)
def _job_error(self, jobid, err): def _job_error(self, jobid, err):

View File

@ -11,6 +11,7 @@ import logging
from hscommon.jobprogress import job from hscommon.jobprogress import job
from hscommon.path import Path from hscommon.path import Path
from hscommon.util import FileOrPath from hscommon.util import FileOrPath
from hscommon.trans import tr
from . import fs from . import fs
@ -182,8 +183,12 @@ class Directories:
""" """
if fileclasses is None: if fileclasses is None:
fileclasses = [fs.File] fileclasses = [fs.File]
file_count = 0
for path in self._dirs: for path in self._dirs:
for file in self._get_files(path, fileclasses=fileclasses, j=j): for file in self._get_files(path, fileclasses=fileclasses, j=j):
file_count += 1
if type(j) != job.NullJob:
j.set_progress(-1, tr("Collected {} files to scan").format(file_count))
yield file yield file
def get_folders(self, folderclass=None, j=job.nulljob): def get_folders(self, folderclass=None, j=job.nulljob):
@ -193,9 +198,13 @@ class Directories:
""" """
if folderclass is None: if folderclass is None:
folderclass = fs.Folder folderclass = fs.Folder
folder_count = 0
for path in self._dirs: for path in self._dirs:
from_folder = folderclass(path) from_folder = folderclass(path)
for folder in self._get_folders(from_folder, j): for folder in self._get_folders(from_folder, j):
folder_count += 1
if type(j) != job.NullJob:
j.set_progress(-1, tr("Collected {} folders to scan").format(folder_count))
yield folder yield folder
def get_state(self, path): def get_state(self, path):

View File

@ -24,6 +24,7 @@ from hscommon.jobprogress import job
) = range(3) ) = range(3)
JOB_REFRESH_RATE = 100 JOB_REFRESH_RATE = 100
PROGRESS_MESSAGE = tr("%d matches found from %d groups")
def getwords(s): def getwords(s):
@ -248,10 +249,11 @@ def getmatches(
match_flags.append(MATCH_SIMILAR_WORDS) match_flags.append(MATCH_SIMILAR_WORDS)
if no_field_order: if no_field_order:
match_flags.append(NO_FIELD_ORDER) match_flags.append(NO_FIELD_ORDER)
j.start_job(len(word_dict), tr("0 matches found")) j.start_job(len(word_dict), PROGRESS_MESSAGE % (0, 0))
compared = defaultdict(set) compared = defaultdict(set)
result = [] result = []
try: try:
word_count = 0
# This whole 'popping' thing is there to avoid taking too much memory at the same time. # This whole 'popping' thing is there to avoid taking too much memory at the same time.
while word_dict: while word_dict:
items = word_dict.popitem()[1] items = word_dict.popitem()[1]
@ -266,7 +268,8 @@ def getmatches(
result.append(m) result.append(m)
if len(result) >= LIMIT: if len(result) >= LIMIT:
return result return result
j.add_progress(desc=tr("%d matches found") % len(result)) word_count += 1
j.add_progress(desc=PROGRESS_MESSAGE % (len(result), word_count))
except MemoryError: except MemoryError:
# This is the place where the memory usage is at its peak during the scan. # This is the place where the memory usage is at its peak during the scan.
# Just continue the process with an incomplete list of matches. # Just continue the process with an incomplete list of matches.
@ -291,7 +294,8 @@ def getmatches_by_contents(files, bigsize=0, j=job.nulljob):
possible_matches = [files for files in size2files.values() if len(files) > 1] possible_matches = [files for files in size2files.values() if len(files) > 1]
del size2files del size2files
result = [] result = []
j.start_job(len(possible_matches), tr("0 matches found")) j.start_job(len(possible_matches), PROGRESS_MESSAGE % (0, 0))
group_count = 0
for group in possible_matches: for group in possible_matches:
for first, second in itertools.combinations(group, 2): for first, second in itertools.combinations(group, 2):
if first.is_ref and second.is_ref: if first.is_ref and second.is_ref:
@ -303,7 +307,8 @@ def getmatches_by_contents(files, bigsize=0, j=job.nulljob):
else: else:
if first.md5 == second.md5: if first.md5 == second.md5:
result.append(Match(first, second, 100)) result.append(Match(first, second, 100))
j.add_progress(desc=tr("%d matches found") % len(result)) group_count += 1
j.add_progress(desc=PROGRESS_MESSAGE % (len(result), group_count))
return result return result

View File

@ -139,8 +139,6 @@ class Job:
self._progress = progress self._progress = progress
if self._progress > self._currmax: if self._progress > self._currmax:
self._progress = self._currmax self._progress = self._currmax
if self._progress < 0:
self._progress = 0
self._do_update(desc) self._do_update(desc)

View File

@ -1,52 +0,0 @@
# Created By: Virgil Dupras
# Created On: 2009-09-14
# Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.gnu.org/licenses/gpl-3.0.html
from PyQt5.QtCore import pyqtSignal, Qt, QTimer
from PyQt5.QtWidgets import QProgressDialog
from . import performer
class Progress(QProgressDialog, performer.ThreadedJobPerformer):
finished = pyqtSignal(["QString"])
def __init__(self, parent):
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
QProgressDialog.__init__(self, "", "Cancel", 0, 100, parent, flags)
self.setModal(True)
self.setAutoReset(False)
self.setAutoClose(False)
self._timer = QTimer()
self._jobid = ""
self._timer.timeout.connect(self.updateProgress)
def updateProgress(self):
# the values might change before setValue happens
last_progress = self.last_progress
last_desc = self.last_desc
if not self._job_running or last_progress is None:
self._timer.stop()
self.close()
if not self.job_cancelled:
self.finished.emit(self._jobid)
return
if self.wasCanceled():
self.job_cancelled = True
return
if last_desc:
self.setLabelText(last_desc)
self.setValue(last_progress)
def run(self, jobid, title, target, args=()):
self._jobid = jobid
self.reset()
self.setLabelText("")
self.run_threaded(target, args)
self.setWindowTitle(title)
self.show()
self._timer.start(500)

View File

@ -7,6 +7,8 @@
from PyQt5.QtCore import Qt, QTimer from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QProgressDialog from PyQt5.QtWidgets import QProgressDialog
from hscommon.trans import tr
class ProgressWindow: class ProgressWindow:
def __init__(self, parent, model): def __init__(self, parent, model):
@ -27,11 +29,15 @@ class ProgressWindow:
def set_progress(self, last_progress): def set_progress(self, last_progress):
if self._window is not None: if self._window is not None:
if last_progress < 0:
self._window.setRange(0, 0)
else:
self._window.setRange(0, 100)
self._window.setValue(last_progress) self._window.setValue(last_progress)
def show(self): def show(self):
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
self._window = QProgressDialog("", "Cancel", 0, 100, self.parent, flags) self._window = QProgressDialog("", tr("Cancel"), 0, 100, self.parent, flags)
self._window.setModal(True) self._window.setModal(True)
self._window.setAutoReset(False) self._window.setAutoReset(False)
self._window.setAutoClose(False) self._window.setAutoClose(False)