Compare commits

...

2 Commits

Author SHA1 Message Date
Kameron Kenny 3e211a609a
checksum stuff 2024-10-06 15:46:11 -04:00
Kameron Kenny 4a6baea929
refactor dialogs 2024-10-06 15:45:05 -04:00
20 changed files with 471 additions and 220 deletions

View File

@ -14,7 +14,8 @@
<string>BitMover</string>
</property>
<property name="windowIcon">
<iconset theme="applications-science"/>
<iconset theme="applications-science">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
@ -95,7 +96,7 @@
<rect>
<x>910</x>
<y>610</y>
<width>311</width>
<width>541</width>
<height>211</height>
</rect>
</property>
@ -344,7 +345,7 @@
<height>41</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0" columnstretch="0,0,0,0,0">
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0" columnstretch="0,0,0,0,0">
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">

View File

@ -11,14 +11,15 @@ from PyQt6.QtWidgets import QMainWindow, QApplication, QFileDialog
from _BitMover_MainWindow import Ui_MainWindow
from _configure import CONFIG_FILE, Configure
from _find_files import FindFiles
from _find_files_dialog import FindProgress
from _import_dialog import DialogImport
from _dialog_find_files import FindProgress
from _dialog_import import DialogImport
from _dialog_checksum_progress import DialogChecksumProgress
# from _media_import import MediaImporter
from _preview import MediaPreview
from _thread_my_stuff import Worker
from _media_file import MediaFile
from _file_stuff import path_exists,is_dir,is_file,create_folder,cmp_files
from _hashing import hash_path
from _file_stuff import path_exists,is_file,create_folder,cmp_hashes
from _verify_file_checksum import FileHash
basedir = os.path.dirname(__file__)
@ -31,23 +32,23 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.setupUi(self)
self.setWindowTitle("BitMover")
self.setWindowIcon(QIcon(os.path.join(basedir,'assets', 'forklift.ico')))
self.threadpool = QThreadPool()
self.config = None
self.src_dir = None
self.dst_dir = None
self.verify_checksum = None
self.cleanup_files = None
self.store_originals = None
self.file_types = None
self.source_path_hash = None
self.search_types = None
self.chunk_size = (16 * 1024) * 1
self.threadpool = QThreadPool()
self.config = None
self.src_dir = None
self.dst_dir = None
self.verify_checksum = None
self.cleanup_files = None
self.store_originals = None
self.file_types = None
self.source_path_hash = None
self.search_types = None
self.chunk_size = (16 * 1024) * 1
self.load_config()
self.destination_original_path = None
self.path_file_source = None
self.path_file_destination = None
self.path_file_destination_original = None
self.path_file_source = None
self.path_file_destination = None
self.path_file_destination_original = None
self.checksum_fph = None
# File Stuff
self.total_files = 0
@ -58,6 +59,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.imp_dialog = DialogImport()
self.find_files_dialog = FindProgress()
self.checksum_progress_dialog = DialogChecksumProgress()
self.widgets_config()
@ -131,7 +133,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.lineEdit_dst_dir.setText(self.dst_dir)
def get_source_path_hash(self,f):
self.source_path_hash = hash_path(f)
self.source_path_hash = FileHash(f).path_hash
return self.source_path_hash
def verify_checksum_changed(self):
@ -407,8 +409,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback
):
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
""" Copy Files. """
count = int(0)
for line in range(self.file_list.count()):
@ -423,29 +427,37 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.files[sph]['name'])
self.path_file_destination = path.join(self.dst_dir,
self.files[sph]['name'])
self.destination_original_path = path.join(self.dst_dir,
self.files[sph]['folders']['destination_original'])
self.path_file_destination_original = path.join(self.dst_dir,
self.files[sph]['folders']['destination_original'],
self.files[sph]['name'])
self.imp_dialog.set_importing_file(self.path_file_source)
self.copy_a_file(
sph,
self.path_file_destination,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback
)
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
print(f'check_store_original({sph}): {self.check_store_original(sph)}')
if self.check_store_original(sph) is True:
self.path_file_destination_original = path.join(self.dst_dir,
self.files[sph]['folders']['destination_original'],
self.files[sph]['name'])
self.copy_a_file(sph,
self.path_file_destination_original,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback)
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
count += 1
@ -455,37 +467,48 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def copy_a_file(self,
fph,
target,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback):
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
size = path.getsize(self.path_file_source)
create_folder(self.dst_dir)
target_dir = os.path.dirname(target)
create_folder(target_dir)
self.check_duplicate(fph)
dup_check = self.check_duplicate(fph,target,target_dir,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
if dup_check is False:
if self.is_video(fph):
self.chunk_size = (1024 * 1024) * 5
else:
self.chunk_size = (16 * 1024) * 1
if self.is_video(fph):
self.chunk_size = (1024 * 1024) * 5
else:
self.chunk_size = (16 * 1024) * 1
with open(self.path_file_source, 'rb') as fs:
with open(self.path_file_destination, 'wb') as fd:
while True:
chunk = fs.read(self.chunk_size)
if not chunk:
break
fd.write(chunk)
dst_size = path.getsize(self.path_file_destination)
current_file_progress_callback.emit(round((dst_size / size) * 100, 1))
with open(self.path_file_source, 'rb') as fs:
with open(target, 'wb') as fd:
while True:
chunk = fs.read(self.chunk_size)
if not chunk:
break
fd.write(chunk)
dst_size = path.getsize(target)
current_file_progress_callback.emit(round((dst_size / size) * 100, 1))
def check_store_original(self,sph):
if self.config['store_originals'] is True:
if self.is_image(sph):
self.dst_dir = self.destination_original_path
self.path_file_destination = self.path_file_destination_original
r = True
else:
r = False
@ -494,15 +517,103 @@ class MainWindow(QMainWindow, Ui_MainWindow):
return r
def check_duplicate(self,sph):
if path_exists(self.path_file_destination):
check_match = cmp_files(self.path_file_source, self.path_file_destination)
def get_checksum(self,_pf,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
sph = FileHash(_pf).path_hash
self.path_file_source = os.path.join(self.files[sph]['folders']['source_path'],
self.files[sph]['name'])
self.path_file_destination = os.path.join(self.files[sph]['folders']['destination'],
self.files[sph]['name'])
if self.store_originals is True:
self.path_file_destination_original = os.path.join(
self.files[sph]['folders']['destination_original'],
self.files[sph]['name'])
def set_checksum(_pf):
print(f'set_checksum, _pf: {_pf}')
if path_exists(_pf) and is_file(_pf):
self.files[sph]['xx_checksum'][_pf] = FileHash(_pf).get_hash(_pf,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
else:
print(f"set_checksum: {_pf} doesn't exist yet or isn't a real file.")
if self.files[sph].get('xx_checksum') is None:
self.files[sph]['xx_checksum'] = {}
set_checksum(self.path_file_source)
set_checksum(self.path_file_destination)
if self.store_originals is True:
set_checksum(self.path_file_destination_original)
else:
if self.files[sph]['xx_checksum'].get(self.path_file_source) is None:
set_checksum(self.path_file_source)
if self.files[sph]['xx_checksum'].get(self.path_file_destination) is None:
set_checksum(self.path_file_destination)
if self.store_originals is True:
if self.files[sph]['xx_checksum'].get(self.path_file_destination_original) is None:
set_checksum(self.path_file_destination_original)
# self.checksum_progress_dialog.close_dialog()
def check_duplicate(self,
sph,
target,
target_dir,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
if path_exists(target):
print(f'Path Exists: path_file_source: {self.path_file_source}\ntarget: {target}')
self.get_checksum(self.path_file_source,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
hash1 = self.files[sph]['xx_checksum'][self.path_file_source]
hash2 = self.files[sph]['xx_checksum'][target]
check_match = cmp_hashes(hash1,hash2)
if check_match is False:
print(f'\nFound duplicate for {self.path_file_source}, renaming destination with hash appended.')
base, extension = path.splitext(self.files[sph]['name'])
f_xxhash = xx_hash(self.path_file_destination)
file_name_hash = base + '_' + f_xxhash + extension
rename(self.path_file_destination, path.join(self.dst_dir, file_name_hash))
file_name_hash = base + '_' + hash2 + extension
rename(target, path.join(target_dir, file_name_hash))
r = False # This is false because we move the original conflict out of the way.
else:
print(f"\n########################\nFound duplicate for: {self.path_file_source}\n"
f"at: {target}... \nHashes MATCH\n"
f"########################")
r = True
else:
# No duplicate
r = False
return r
# END from _media_import.py
@ -533,17 +644,99 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.thread_complete)
worker.signals.finished.connect(
self.worker_thread_done)
worker.signals.finished.connect(
self.compare_imported_checksums)
worker.signals.checksum_dialog_open.connect(
self.checksum_progress_dialog.open_dialog)
worker.signals.checksum_file.connect(
self.checksum_progress_dialog.set_file)
worker.signals.checksum_progress.connect(
self.checksum_progress_dialog.set_progress)
worker.signals.finished.connect(
self.checksum_progress_dialog.close_dialog)
# Execute
self.threadpool.start(worker)
def verify_checksum(self):
# fh_match = FileHash()
print(f'verify_checksum,self.config: {self.config}')
def compare_imported_checksums(self):
# if self.config['verify_checksum'] is True:
# self.checksum_fph = fph
# Initialize Widgets
self.checksum_progress_dialog.set_progress(0)
worker = Worker(self.t_compare_imported_checksums)
worker.signals.started.connect(
self.worker_thread_started)
worker.signals.started.connect(
self.checksum_progress_dialog.open_dialog)
worker.signals.found_file.connect(
self.checksum_progress_dialog.set_file)
worker.signals.progress.connect(
self.checksum_progress_dialog.set_progress)
worker.signals.finished.connect(
self.thread_complete)
worker.signals.finished.connect(
self.worker_thread_done)
worker.signals.finished.connect(
self.checksum_progress_dialog.close_dialog)
worker.signals.checksum_dialog_open.connect(
self.checksum_progress_dialog.open_dialog)
worker.signals.checksum_file.connect(
self.checksum_progress_dialog.set_file)
worker.signals.checksum_progress.connect(
self.checksum_progress_dialog.set_progress)
worker.signals.finished.connect(
self.checksum_progress_dialog.close_dialog)
# Execute
self.threadpool.start(worker)
def t_compare_imported_checksums(self,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
for file in self.files:
_pf = os.path.join(self.files[file]['folders']['source_path'],
self.files[file]['name'])
print(f"source_path: {self.files[file]['folders']['source_path']}")
print(f"name: {self.files[file]['name']}")
print(f'_pf: {_pf}')
self.get_checksum(_pf,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback)
i = 0
c = {}
for checksum in self.files[file]['xx_checksum']:
c[i] = self.files[file]['xx_checksum'][checksum]
if i > 0:
p = i - 1
if c[i] == c[p]:
self.files[file]['checksum_match'] = True
print(f'Checksums match for: {self.files[file]["name"]}')
else:
self.files[file]['checksum_match'] = False
print(f'Checksum failed for: {self.files[file]["name"]}')
i += 1
# Main App
app = QApplication(sys.argv)
# Main Window
window = MainWindow()
# Show Window
window.show()
app.exec()

View File

@ -50,7 +50,7 @@ class Ui_MainWindow(object):
self.file_list.setGeometry(QtCore.QRect(20, 160, 871, 701))
self.file_list.setObjectName("file_list")
self.gridLayoutWidget_2 = QtWidgets.QWidget(parent=self.centralwidget)
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(910, 610, 311, 211))
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(910, 610, 541, 211))
self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
self.grid_metadata = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
self.grid_metadata.setContentsMargins(0, 0, 0, 0)

View File

@ -62,35 +62,35 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<widget class="QLabel" name="label_4">
<widget class="QLabel" name="l_hash_dest">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<widget class="QLabel" name="l_path_file_source">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_3">
<widget class="QLabel" name="l_path_file_dest">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="l_hash_source">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="label_title_source">
<property name="maximumSize">
<size>
<width>80</width>
@ -109,7 +109,7 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<widget class="QLabel" name="label_title_dest">
<property name="maximumSize">
<size>
<width>80</width>
@ -129,7 +129,7 @@
</item>
</layout>
</widget>
<widget class="QLabel" name="label_5">
<widget class="QLabel" name="label_title_comparing_files">
<property name="geometry">
<rect>
<x>20</x>

View File

@ -0,0 +1,73 @@
# Form implementation generated from reading ui file '_ComparisonDialog.ui'
#
# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_FileComparisonDialog(object):
def setupUi(self, FileComparisonDialog):
FileComparisonDialog.setObjectName("FileComparisonDialog")
FileComparisonDialog.resize(1588, 753)
self.tableWidget = QtWidgets.QTableWidget(parent=FileComparisonDialog)
self.tableWidget.setGeometry(QtCore.QRect(20, 90, 1551, 651))
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
self.tableWidget.setTabKeyNavigation(False)
self.tableWidget.setProperty("showDropIndicator", False)
self.tableWidget.setRowCount(2)
self.tableWidget.setColumnCount(5)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.horizontalHeader().setDefaultSectionSize(300)
self.tableWidget.verticalHeader().setVisible(True)
self.gridLayoutWidget = QtWidgets.QWidget(parent=FileComparisonDialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(240, 11, 981, 71))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.l_hash_dest = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.l_hash_dest.setText("")
self.l_hash_dest.setObjectName("l_hash_dest")
self.gridLayout.addWidget(self.l_hash_dest, 2, 2, 1, 1)
self.l_path_file_source = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.l_path_file_source.setText("")
self.l_path_file_source.setObjectName("l_path_file_source")
self.gridLayout.addWidget(self.l_path_file_source, 0, 1, 1, 1)
self.l_path_file_dest = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.l_path_file_dest.setText("")
self.l_path_file_dest.setObjectName("l_path_file_dest")
self.gridLayout.addWidget(self.l_path_file_dest, 2, 1, 1, 1)
self.l_hash_source = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.l_hash_source.setText("")
self.l_hash_source.setObjectName("l_hash_source")
self.gridLayout.addWidget(self.l_hash_source, 0, 2, 1, 1)
self.label_title_source = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_title_source.setMaximumSize(QtCore.QSize(80, 16777215))
self.label_title_source.setBaseSize(QtCore.QSize(0, 0))
self.label_title_source.setObjectName("label_title_source")
self.gridLayout.addWidget(self.label_title_source, 0, 0, 1, 1)
self.label_title_dest = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_title_dest.setMaximumSize(QtCore.QSize(80, 16777215))
self.label_title_dest.setBaseSize(QtCore.QSize(0, 0))
self.label_title_dest.setObjectName("label_title_dest")
self.gridLayout.addWidget(self.label_title_dest, 2, 0, 1, 1)
self.label_title_comparing_files = QtWidgets.QLabel(parent=FileComparisonDialog)
self.label_title_comparing_files.setGeometry(QtCore.QRect(20, 10, 231, 61))
font = QtGui.QFont()
font.setPointSize(28)
self.label_title_comparing_files.setFont(font)
self.label_title_comparing_files.setObjectName("label_title_comparing_files")
self.retranslateUi(FileComparisonDialog)
QtCore.QMetaObject.connectSlotsByName(FileComparisonDialog)
def retranslateUi(self, FileComparisonDialog):
_translate = QtCore.QCoreApplication.translate
FileComparisonDialog.setWindowTitle(_translate("FileComparisonDialog", "Dialog"))
self.label_title_source.setText(_translate("FileComparisonDialog", "Source"))
self.label_title_dest.setText(_translate("FileComparisonDialog", "Destination"))
self.label_title_comparing_files.setText(_translate("FileComparisonDialog", "Comparing Files"))

View File

@ -1,73 +0,0 @@
# Form implementation generated from reading ui file '_ComparisonDialog.ui'
#
# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_FileComparisonDialog(object):
def setupUi(self, FileComparisonDialog):
FileComparisonDialog.setObjectName("FileComparisonDialog")
FileComparisonDialog.resize(1588, 753)
self.tableWidget = QtWidgets.QTableWidget(parent=FileComparisonDialog)
self.tableWidget.setGeometry(QtCore.QRect(20, 90, 1551, 651))
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
self.tableWidget.setTabKeyNavigation(False)
self.tableWidget.setProperty("showDropIndicator", False)
self.tableWidget.setRowCount(2)
self.tableWidget.setColumnCount(5)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.horizontalHeader().setDefaultSectionSize(300)
self.tableWidget.verticalHeader().setVisible(True)
self.gridLayoutWidget = QtWidgets.QWidget(parent=FileComparisonDialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(240, 11, 981, 71))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.label_4 = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 2, 2, 1, 1)
self.label = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 1, 1, 1)
self.label_3 = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
self.label_6 = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_6.setMaximumSize(QtCore.QSize(80, 16777215))
self.label_6.setBaseSize(QtCore.QSize(0, 0))
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 0, 0, 1, 1)
self.label_7 = QtWidgets.QLabel(parent=self.gridLayoutWidget)
self.label_7.setMaximumSize(QtCore.QSize(80, 16777215))
self.label_7.setBaseSize(QtCore.QSize(0, 0))
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 2, 0, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=FileComparisonDialog)
self.label_5.setGeometry(QtCore.QRect(20, 10, 231, 61))
font = QtGui.QFont()
font.setPointSize(28)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.retranslateUi(FileComparisonDialog)
QtCore.QMetaObject.connectSlotsByName(FileComparisonDialog)
def retranslateUi(self, FileComparisonDialog):
_translate = QtCore.QCoreApplication.translate
FileComparisonDialog.setWindowTitle(_translate("FileComparisonDialog", "Dialog"))
self.label_4.setText(_translate("FileComparisonDialog", "TextLabel"))
self.label.setText(_translate("FileComparisonDialog", "TextLabel"))
self.label_3.setText(_translate("FileComparisonDialog", "TextLabel"))
self.label_2.setText(_translate("FileComparisonDialog", "TextLabel"))
self.label_6.setText(_translate("FileComparisonDialog", "Source"))
self.label_7.setText(_translate("FileComparisonDialog", "Destination"))
self.label_5.setText(_translate("FileComparisonDialog", "Comparing Files"))

View File

@ -0,0 +1,39 @@
from PyQt6.QtWidgets import QDialog
from _Window_checksum_progress_dialog import Ui_ChecksumProgressDialog
class DialogChecksumProgress(QDialog, Ui_ChecksumProgressDialog):
def __init__(self,*args,**kwargs):
super(DialogChecksumProgress,self).__init__(*args,**kwargs)
self.setupUi(self)
# self.import_dialog = UI_DialogImport()
# self.ui_import_dialog = Ui_DialogImport()
print('DialogImport')
def is_shown(self):
print(f'is_shown: {self.isVisible()}')
return self.isVisible()
def open_dialog(self,should_be_open):
if should_be_open is True:
if self.is_shown() is False:
print(f'open_checksum_dialog: {self.is_shown()}')
self.show()
else:
print('Checksum dialog already open.')
else:
self.close_dialog()
def close_dialog(self):
print('close_import_dialog')
if self.is_shown():
print('inside self.is_shown()')
print('hiding window')
self.hide()
def set_progress(self, n):
# print("%d%% done" % n)
self.progressBar_getting_checksum.setValue(int(n))
# self.lcd_import_progress.display(n)
def set_file(self,f):
self.l_content_checksum_filename.setText(f)

View File

@ -1,5 +1,5 @@
from PyQt6.QtWidgets import QDialog
from _finding_files_dialog_Window import Ui_FindProgress
from _Window_finding_files_dialog import Ui_FindProgress
class FindProgress(QDialog, Ui_FindProgress):
def __init__(self,*args,**kwargs):
@ -26,6 +26,6 @@ class FindProgress(QDialog, Ui_FindProgress):
self.hide()
def set_progress_finding_files(self,n):
print("%d%% done" % n)
# print("%d%% done" % n)
self.progressBar_importing.setValue(float(n))
self.lcd_import_progress.display(n)

View File

@ -1,5 +1,5 @@
from PyQt6.QtWidgets import QDialog
from _import_dialog_Window import Ui_DialogImport
from _Window_import_dialog import Ui_DialogImport
class DialogImport(QDialog, Ui_DialogImport):
def __init__(self,*args,**kwargs):
@ -14,11 +14,16 @@ class DialogImport(QDialog, Ui_DialogImport):
return self.isVisible()
def open_import_dialog(self):
print(f'open_import_dialog: {self.is_shown()}')
if not self.is_shown():
print('Inside if not self.is_shown')
print('showing window')
self.show()
if self.is_shown() is False:
print(f'open_import_dialog: {self.is_shown()}')
if not self.is_shown():
print('Inside if not self.is_shown')
print('showing window')
self.show()
else:
print('Import Dialog already open.')
else:
self.close_import_dialog()
def close_import_dialog(self):
print('close_import_dialog')
@ -28,12 +33,12 @@ class DialogImport(QDialog, Ui_DialogImport):
self.hide()
def set_progress_importing(self, n):
print("%d%% done" % n)
# print("%d%% done" % n)
self.progressBar_importing.setValue(int(n))
self.lcd_import_progress.display(n)
def set_progress_current_file(self, n):
print("%d%% done" % n)
# print("%d%% done" % n)
self.progressBar_importing_2.setValue(int(n))
self.lcd_current_file_progress.display(n)

View File

@ -9,7 +9,8 @@ import yaml
from tqdm import tqdm
### Local Imports
from _hashing import xx_hash
# from _hashing import xx_hash
from _verify_file_checksum import FileHash
def check_log_dir(d):
create_folder(d)
@ -38,10 +39,14 @@ def cmp_files(f1,f2):
#TODO: Determine if path is actually a file
#TODO: Determine if the hash has already been stored and use it if so
hash1 = xx_hash(f1)
hash2 = xx_hash(f2)
hash1 = FileHash(f1).file_hash
hash2 = FileHash(f2).file_hash
return hash1 == hash2
def cmp_hashes(h1,h2):
""" compare two files """
return h1 == h2
def path_access_read(path):
""" make sure we can read from the path """
val = os.access(path, os.R_OK)

View File

@ -29,7 +29,10 @@ class FindFiles:
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback):
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
file_count = int(0)
if len(self.search_types) > 0:
for folder, subfolders, filename in os.walk(self.src_dir):

View File

@ -8,28 +8,24 @@ import os
import xxhash
from tqdm import tqdm
def xx_hash(file):
""" calculates and returns file hash based on xxHash """
size = os.path.getsize(file)
hasher = xxhash.xxh64()
# def xx_hash(file):
# """ calculates and returns file hash based on xxHash """
# size = os.path.getsize(file)
# hasher = xxhash.xxh64()
#
# with open(file, 'rb') as f:
# with tqdm(total=size,
# unit='B',
# unit_scale=True,
# desc=f'Getting hash for {os.path.basename(file)}') as pbar:
# for chunk in iter(lambda: f.read(4096), b""):
# hasher.update(chunk)
# pbar.update(len(chunk))
# file_hash = hasher.hexdigest()
#
# return file_hash
with open(file, 'rb') as f:
with tqdm(total=size,
unit='B',
unit_scale=True,
desc=f'Getting hash for {os.path.basename(file)}') as pbar:
for chunk in iter(lambda: f.read(4096), b""):
hasher.update(chunk)
pbar.update(len(chunk))
file_hash = hasher.hexdigest()
return file_hash
def hash_path(path):
""" hashes a string passed as a path """
hasher = xxhash.xxh64(path)
return hasher.hexdigest()
def gen_xxhashes(f):
""" Generate xxHashes """

View File

@ -2,7 +2,7 @@ import os.path
import sys
from _audio import AudioFile
from _hashing import hash_path
from _verify_file_checksum import FileHash
from _video import VideoFile
from _photo import PhotoFile
from _file_stuff import (get_file_name,
@ -23,7 +23,7 @@ class MediaFile:
self.store_originals = self.config['store_originals']
self.src_dir = os.path.dirname(self.path_file_name)
self.base_dst_dir = self.config['folders']['destination']['base']
self.source_path_hash = hash_path(self.path_file_name)
self.source_path_hash = FileHash(self.path_file_name).path_file
self.file_name = get_file_name(self.path_file_name)
self.dotted_file_ext = get_dotted_file_ext(self.file_name)
self.file_ext = get_file_ext(self.file_name)

View File

@ -1,10 +1,8 @@
#!/usr/bin/env python
from PIL import Image
from _media_file import MediaFile
from _raw_photo import extract_jpg_thumb
from _video import VideoFile
from _hashing import hash_path
from _verify_file_checksum import FileHash
class MediaPreview:
def __init__(self,path_file_name,media_files):
@ -12,7 +10,7 @@ class MediaPreview:
self.path_file_name = path_file_name
self.media_files_list = media_files
# self.media_file = MediaFile(self.path_file_name)
self.source_path_hash = hash_path(self.path_file_name)
self.source_path_hash = FileHash(self.path_file_name).path_hash
# print(f'_preview.py,MediaPreview:\n\tpath_file_name: {self.path_file_name}\n\thash: {self.source_path_hash}\n\tmedia_files_list: {self.media_files_list}\n')
self.thumbnail = 'thumbnail.jpg'
self.file_type = self.media_files_list[self.source_path_hash]['file_type']

View File

@ -31,6 +31,9 @@ class WorkerSignals(QObject):
imported_file_count = pyqtSignal(int)
found_file = pyqtSignal(str)
total_file_count = pyqtSignal(int)
checksum_progress = pyqtSignal(int)
checksum_file = pyqtSignal(str)
checksum_dialog_open = pyqtSignal(bool)
class Worker(QRunnable):
"""
@ -60,6 +63,9 @@ class Worker(QRunnable):
self.kwargs['imported_file_count_callback'] = self.signals.imported_file_count
self.kwargs['found_file_callback'] = self.signals.found_file
self.kwargs['total_file_count_callback'] = self.signals.total_file_count
self.kwargs['checksum_file_callback'] = self.signals.checksum_file
self.kwargs['checksum_progress_callback'] = self.signals.checksum_progress
self.kwargs['checksum_dialog_open_callback'] = self.signals.checksum_dialog_open
@pyqtSlot()
def run(self):

View File

@ -2,47 +2,52 @@ import os
import xxhash
class FileHash:
def __init__(self,files,*args,**kwargs):
def __init__(self,
path_file,
chunk_size=1024 * 1024,
*args,
**kwargs):
super(FileHash,self).__init__(*args,**kwargs)
self.files = files
self.chunk_size = kwargs['chunk_size']
self.path_file = path_file
self._path = os.path.dirname(self.path_file)
self.chunk_size = chunk_size
self.path_hasher = xxhash.xxh64(self._path)
# noinspection PyArgumentList
# self.file_hash = self.get_hash(self.path_file)
self.path_hash = self.hash_path()
def get_hash(self,f,
progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file_callback,
total_file_count_callback,
checksum_file_callback,
checksum_progress_callback,
checksum_dialog_open_callback):
checksum_dialog_open_callback.emit(True)
@staticmethod
def xx_hash(self,f,progress_callback):
size = os.path.getsize(f)
hasher = xxhash.xxh64()
#todo: add callbacks
chunk_count = 0
checksum_file_callback.emit(f)
with open(f, 'rb') as f:
for chunk in iter(lambda: f.read(self.chunk_size),b""):
hasher.update(chunk)
chunk_count += 1
hashed_size = chunk_count * self.chunk_size
progress_callback.emit(round((hashed_size / size) * 100, 1))
checksum_progress_callback.emit(round((hashed_size / size) * 100, 1))
file_hash = hasher.hexdigest()
checksum_dialog_open_callback.emit(False)
return file_hash
@staticmethod
def t_verify_checksum(self,
progress_callback,
import_progress_callback,
current_file_progress_callback,
imported_file_count_callback,
found_file,
total_file_count):
def hash_path(self):
""" hashes a string passed as a path """
for file in self.files:
i = 0
c = {}
for checksum in self.files[file]['xx_checksum']:
c[i] = self.files[file]['xx_checksum'][checksum]
if i > 0:
p = i - 1
if c[i] == c[p]:
self.files[file]['checksum_match'] = True
else:
self.files[file]['checksum_match'] = False
i += 1
return self.files
return self.path_hasher.hexdigest()

View File

@ -1,5 +1,5 @@
pyuic6 BitMover.ui -o _BitMover_MainWindow.py
pyuic6 import_dialogue.ui -o _import_dialog_Window.py
pyuic6 _finding_files_dialog.ui -o _finding_files_dialog_Window.py
pyuic6 _ComparisonDialog.ui -o _comparison_dialog_Window.py
pyuic6 _checksum_progress_dialog.ui -o _checksum_progress_dialog_Window.py
pyuic6 import_dialogue.ui -o _Window_import_dialog.py
pyuic6 _finding_files_dialog.ui -o _Window_finding_files_dialog.py
pyuic6 _ComparisonDialog.ui -o _Window_comparison_dialog.py
pyuic6 _checksum_progress_dialog.ui -o _Window_checksum_progress_dialog.py