It works.
This commit is contained in:
parent
fc32855c86
commit
e8861abbdc
176
BitMover_ui.py
176
BitMover_ui.py
|
@ -1,36 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
# import time
|
||||
|
||||
from PyQt6.QtCore import *
|
||||
from PyQt6.QtGui import *
|
||||
from PyQt6.QtWidgets import *
|
||||
|
||||
import traceback
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal, pyqtSlot, QRunnable, QObject, QThreadPool
|
||||
from PyQt6.QtWidgets import QMainWindow, QApplication
|
||||
from PyQt6.QtGui import QIcon,QPixmap
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from configure import CONFIG_FILE, Configure
|
||||
from file_stuff import is_file, get_t_files
|
||||
from file_stuff import is_file
|
||||
from BitMover_MainWindow import Ui_MainWindow
|
||||
|
||||
from get_image_tag import get_exif_tag
|
||||
|
||||
from media import Media
|
||||
|
||||
|
||||
from lumberjack import timber
|
||||
from raw_photo import extract_jpg_thumb
|
||||
from raw_photo import extract_jpg_thumb, get_raw_image_dimensions
|
||||
|
||||
log = timber(__name__)
|
||||
|
||||
class WorkerSignals(QObject):
|
||||
"""
|
||||
Defines the signals available from a running worker thread.
|
||||
Defines the signals avail from a running worker thread.
|
||||
|
||||
Supported signals are:
|
||||
|
||||
finished
|
||||
No data
|
||||
No Data
|
||||
|
||||
error
|
||||
tuple (exctype, value, traceback.format_exc() )
|
||||
|
@ -40,17 +36,16 @@ class WorkerSignals(QObject):
|
|||
|
||||
progress
|
||||
int indicating % progress
|
||||
|
||||
"""
|
||||
started = pyqtSignal()
|
||||
finished = pyqtSignal()
|
||||
error = pyqtSignal(tuple)
|
||||
result = pyqtSignal(object)
|
||||
progress = pyqtSignal(int)
|
||||
|
||||
|
||||
class Worker(QRunnable):
|
||||
"""
|
||||
Worker thread
|
||||
Worker Thread
|
||||
|
||||
Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
|
||||
|
||||
|
@ -61,10 +56,10 @@ class Worker(QRunnable):
|
|||
:param kwargs: Keywords to pass to the callback function
|
||||
"""
|
||||
|
||||
def __init__(self, fn, *args, **kwargs):
|
||||
super(Worker, self).__init__()
|
||||
def __init__(self,fn,*args,**kwargs):
|
||||
super(Worker,self).__init__()
|
||||
|
||||
# Store constructor arguments (re-used for processing)
|
||||
# Store constructor args (re-used for processing)
|
||||
self.fn = fn
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
@ -78,18 +73,18 @@ class Worker(QRunnable):
|
|||
"""
|
||||
Initialise the runner function with passed args, kwargs.
|
||||
"""
|
||||
|
||||
# Retrieve args/kwargs here; and fire processing using them
|
||||
try:
|
||||
self.signals.started.emit()
|
||||
result = self.fn(*self.args, **self.kwargs)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
exctype, value = sys.exc_info()[:2]
|
||||
self.signals.error.emit((exctype, value, traceback.format_exc()))
|
||||
self.signals.error.emit((exctype,value,traceback.format_exc()))
|
||||
else:
|
||||
self.signals.result.emit(result) # Return the result of the processing
|
||||
self.signals.result.emit(result)
|
||||
finally:
|
||||
self.signals.finished.emit() # Done
|
||||
self.signals.finished.emit()
|
||||
|
||||
# Subclass QMainWindow to customize your application's main window
|
||||
class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
|
@ -100,12 +95,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
c = Configure(CONFIG_FILE)
|
||||
self.config = c.load_config()
|
||||
self.total_files = 0
|
||||
|
||||
# self.t_find_files = threading.Thread(target=self.find_files)
|
||||
self.file_total = 0
|
||||
self.threads = {}
|
||||
self.lcd_files_found.display(int(0))
|
||||
self.set_progress(0, 0)
|
||||
|
||||
self.setWindowTitle("BitMover")
|
||||
self.setWindowIcon(QIcon('assets/forklift.png'))
|
||||
|
||||
self.threadpool = QThreadPool()
|
||||
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
|
||||
|
||||
self.src_dir = self.config['folders']['source']['base']
|
||||
self.dst_dir = self.config['folders']['destination']['base']
|
||||
|
||||
|
@ -117,20 +117,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.pushButton_src_browse.clicked.connect(self.select_src_directory)
|
||||
self.pushButton_dst_browse.clicked.connect(self.select_dst_directory)
|
||||
self.pushButton_3_scan_dir.clicked.connect(self.find_files)
|
||||
|
||||
self.toggle_scan_button(True)
|
||||
# self.pushButton_3_scan_dir.clicked.connect(self.t_find_files.start)
|
||||
self.lcd_files_found.display(int(0))
|
||||
self.set_progress(0,0)
|
||||
|
||||
|
||||
self.img_preview.setPixmap(QPixmap('assets/preview_placeholder.jpg'))
|
||||
self.img_preview.setScaledContents(True)
|
||||
# self.img_preview.setFixedWidth(preview_width)
|
||||
# self.img_preview.setFixedHeight(preview_height)
|
||||
|
||||
self.file_list.currentItemChanged.connect(self.index_changed)
|
||||
self.threadpool = QThreadPool()
|
||||
|
||||
self.files = {}
|
||||
|
||||
def toggle_scan_button(self,enable=True):
|
||||
if enable:
|
||||
self.pushButton_3_scan_dir.setEnabled(True)
|
||||
else:
|
||||
self.pushButton_3_scan_dir.setDisabled(True)
|
||||
|
||||
def index_changed(self,i):
|
||||
f = i.text()
|
||||
|
||||
|
@ -143,19 +147,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.label_data_date_time_created.setText(dtc)
|
||||
|
||||
if m.file_type == 'image':
|
||||
# img = Image.open(f)
|
||||
dpi = get_exif_tag(f,"xresolution")
|
||||
width = get_exif_tag(f,"image width")
|
||||
height = get_exif_tag(f,"image height")
|
||||
if width is None:
|
||||
get_exif_tag(f,"exifimagewidth")
|
||||
if height is None:
|
||||
get_exif_tag(f,"exifimagelength")
|
||||
# width = img.width
|
||||
# height = img.height
|
||||
if f.lower().endswith("jpg") or f.lower().endswith("jpeg"):
|
||||
img = Image.open(f)
|
||||
width = img.width
|
||||
height = img.height
|
||||
else:
|
||||
width = get_raw_image_dimensions(f)[1]
|
||||
height = get_raw_image_dimensions(f)[0]
|
||||
size = f'{width}x{height}'
|
||||
if width is not None and height is not None:
|
||||
mpixels = (width * height) / 1000000
|
||||
mpixels = round((width * height) / 1000000, 1)
|
||||
else:
|
||||
mpixels = ''
|
||||
iso = get_exif_tag(f,"iso")
|
||||
|
@ -191,7 +193,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
jpg = extract_jpg_thumb(f)
|
||||
self.img_preview.setPixmap(QPixmap(jpg))
|
||||
|
||||
|
||||
def select_src_directory(self):
|
||||
directory = QFileDialog.getExistingDirectory(self,
|
||||
"Select Directory",
|
||||
|
@ -212,74 +213,99 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.dst_dir = directory
|
||||
self.lineEdit_dst_dir.setText(self.dst_dir)
|
||||
|
||||
def set_total_files(self,t):
|
||||
self.total_files = t
|
||||
self.lcd_files_found.display(self.total_files)
|
||||
|
||||
def progress_fn(self,n):
|
||||
# print("%d%% done" % n)
|
||||
self.progressBar_overall.setValue(int(n))
|
||||
|
||||
def set_progress(self,p,t):
|
||||
"""
|
||||
set progress for bar,
|
||||
p = progress counter
|
||||
t = target total
|
||||
o = progress bar object
|
||||
"""
|
||||
if int(t) == 0:
|
||||
t += 1
|
||||
#
|
||||
# while QPainter.isActive(Ui_MainWindow.QPainter()):
|
||||
# print('painter active')
|
||||
# time.sleep(0.02)
|
||||
|
||||
percent_complete = (int(p) / int(t)) * 100
|
||||
self.progressBar_overall.setValue(int(percent_complete))
|
||||
|
||||
def print_output(self, s):
|
||||
print(s)
|
||||
|
||||
def thread_complete(self):
|
||||
print("THREAD COMPLETE!")
|
||||
|
||||
def thread_find_files(self):
|
||||
print('in thread_find_files')
|
||||
print(self.src_dir)
|
||||
worker = Worker(self.find_files())
|
||||
worker.signals.result.connect(self.print_output)
|
||||
worker.signals.finished.connect(self.thread_complete)
|
||||
worker.signals.progress.connect(self.progress_fn)
|
||||
self.threadpool.start(worker)
|
||||
|
||||
|
||||
|
||||
def find_files(self):
|
||||
""" find files to build a dictionary out of """
|
||||
log.info('In find_files')
|
||||
print(self.src_dir)
|
||||
def get_t_files(self):
|
||||
for folder, subfolders, filename in os.walk(self.src_dir):
|
||||
for f_type in self.file_types:
|
||||
for ext in self.file_types[f_type]:
|
||||
for file in filename:
|
||||
if file.lower().endswith(ext):
|
||||
current_file = os.path.join(folder, file)
|
||||
if is_file(current_file):
|
||||
self.file_total += int(1)
|
||||
else:
|
||||
print(f"Skipping {current_file} as it does not look like a real file.")
|
||||
|
||||
def t_find_files(self,progress_callback):
|
||||
file_count = int(0)
|
||||
file_total = get_t_files(self.src_dir,self.file_types)
|
||||
self.get_t_files()
|
||||
self.set_total_files(self.file_total)
|
||||
|
||||
for folder, subfolders, filename in os.walk(self.src_dir):
|
||||
for f_type in self.file_types:
|
||||
for ext in self.file_types[f_type]:
|
||||
# for file in tqdm(filename,
|
||||
# desc='Finding ' + ext + ' Files in ' + folder):
|
||||
for file in filename:
|
||||
if file.lower().endswith(ext):
|
||||
current_file = os.path.join(folder, file)
|
||||
if is_file(current_file):
|
||||
file_count += int(1)
|
||||
self.process_file(folder, file)
|
||||
self.set_progress(file_count,file_total)
|
||||
self.process_file(current_file)
|
||||
# self.set_progress(file_count,file_total)
|
||||
# time.sleep(.02)
|
||||
|
||||
else:
|
||||
print(f"Skipping {current_file} as it does not look like a real file.")
|
||||
|
||||
progress_callback.emit((file_count / file_total) * 100)
|
||||
progress_callback.emit((file_count / self.file_total) * 100)
|
||||
return "Done."
|
||||
|
||||
def print_output(self,s):
|
||||
print(s)
|
||||
|
||||
def scan_thread_started(self):
|
||||
print('scan thread started')
|
||||
self.toggle_scan_button(False)
|
||||
|
||||
def scan_thread_done(self):
|
||||
print('scan thread complete.')
|
||||
self.toggle_scan_button(True)
|
||||
|
||||
def thread_complete(self):
|
||||
print("THREAD COMPLETE.")
|
||||
|
||||
def find_files(self):
|
||||
""" find files to build a dictionary out of """
|
||||
worker = Worker(self.t_find_files)
|
||||
# worker.signals.started.connect(self.toggle_scan_button(enable=False))
|
||||
worker.signals.started.connect(self.scan_thread_started)
|
||||
worker.signals.result.connect(self.print_output)
|
||||
worker.signals.finished.connect(self.thread_complete)
|
||||
worker.signals.finished.connect(self.scan_thread_done)
|
||||
# worker.signals.finished.connect(self.toggle_scan_button(enable=True))
|
||||
worker.signals.progress.connect(self.progress_fn)
|
||||
|
||||
# Execute.
|
||||
self.threadpool.start(worker)
|
||||
|
||||
def get_event(self):
|
||||
event_name = self.eventName.text()
|
||||
return event_name
|
||||
|
||||
def process_file(self,path_name, f_name):
|
||||
def process_file(self,p):
|
||||
""" gather information and add to dictionary """
|
||||
|
||||
path_name = os.path.dirname(p)
|
||||
f_name = os.path.basename(p)
|
||||
|
||||
event = self.get_event()
|
||||
c = self.config
|
||||
|
||||
|
|
2
dedup.py
2
dedup.py
|
@ -19,7 +19,7 @@ args = parser.parse_args()
|
|||
if args.folder:
|
||||
FOLDER = args.folder
|
||||
else:
|
||||
print("you need to specify a folder.")
|
||||
print("you need to specify a folder. Dedup")
|
||||
sys.exit()
|
||||
if args.dryrun:
|
||||
dry_run = True
|
||||
|
|
|
@ -126,18 +126,3 @@ def validate_config_dir_access(config):
|
|||
accessible = True
|
||||
return accessible
|
||||
|
||||
def get_t_files(p,t):
|
||||
total = int(0)
|
||||
for folder, subfolders, filename in os.walk(p):
|
||||
for f_type in t:
|
||||
for ext in t[f_type]:
|
||||
# for file in tqdm(filename,
|
||||
# desc='Finding ' + ext + ' Files in ' + folder):
|
||||
for file in filename:
|
||||
if file.lower().endswith(ext):
|
||||
current_file = os.path.join(folder, file)
|
||||
if is_file(current_file):
|
||||
total += int(1)
|
||||
else:
|
||||
print(f"Skipping {current_file} as it does not look like a real file.")
|
||||
return total
|
10
raw_photo.py
10
raw_photo.py
|
@ -21,8 +21,8 @@ def extract_jpg_thumb(raw_file_path):
|
|||
|
||||
return 'thumbnail.jpg'
|
||||
|
||||
# thumbnail_path = extract_jpg_thumb('your_raw_image.nef')
|
||||
# if thumbnail_path:
|
||||
# print("Thumbnail extracted to:", thumbnail_path)
|
||||
# else:
|
||||
# print("No thumbnail found or unsupported format.")
|
||||
def get_raw_image_dimensions(raw_file_path):
|
||||
i = imread(raw_file_path)
|
||||
height, width = i.raw_image.shape[:2]
|
||||
|
||||
return height,width
|
Loading…
Reference in New Issue