dev #1
120
BitMover_ui.py
120
BitMover_ui.py
|
@ -1,7 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
|
from os import path
|
||||||
|
from os import rename
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
|
|
||||||
from PyQt6.QtCore import QThreadPool
|
from PyQt6.QtCore import QThreadPool
|
||||||
from PyQt6.QtGui import QIcon, QPixmap
|
from PyQt6.QtGui import QIcon, QPixmap
|
||||||
|
@ -16,9 +17,7 @@ from _import_dialog import DialogImport
|
||||||
from _preview import MediaPreview
|
from _preview import MediaPreview
|
||||||
from _thread_my_stuff import Worker
|
from _thread_my_stuff import Worker
|
||||||
from _media_file import MediaFile
|
from _media_file import MediaFile
|
||||||
from _file_stuff import (path_exists,
|
from _file_stuff import path_exists,is_dir,is_file,create_folder,cmp_files
|
||||||
is_dir,
|
|
||||||
is_file)
|
|
||||||
from _hashing import hash_path
|
from _hashing import hash_path
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,8 +172,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
return preview
|
return preview
|
||||||
|
|
||||||
def update_preview(self,preview):
|
def update_preview(self,preview):
|
||||||
|
if preview.file_type.lower() == 'video':
|
||||||
|
thumb_ratio = 16 / 9 # 1.77
|
||||||
|
elif preview.file_type.lower() == 'image':
|
||||||
|
thumb_ratio = preview.thumbnail_ratio
|
||||||
|
else:
|
||||||
|
thumb_ratio = 1
|
||||||
|
|
||||||
self.set_thumbnail(preview.thumbnail,
|
self.set_thumbnail(preview.thumbnail,
|
||||||
ratio=preview.thumbnail_ratio)
|
ratio=thumb_ratio)
|
||||||
|
|
||||||
def update_metadata(self,preview):
|
def update_metadata(self,preview):
|
||||||
self.clear_metadata()
|
self.clear_metadata()
|
||||||
|
@ -204,7 +210,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.l_meta_content_03.setText(str(f_photo['iso']))
|
self.l_meta_content_03.setText(str(f_photo['iso']))
|
||||||
self.l_meta_content_04.setText(str(f_photo['lens_model']))
|
self.l_meta_content_04.setText(str(f_photo['lens_model']))
|
||||||
self.l_meta_content_05.setText(str(f_photo['lens_focal_length']))
|
self.l_meta_content_05.setText(str(f_photo['lens_focal_length']))
|
||||||
self.l_meta_content_06.setText(str("f_photo['camera_brand']} {f_photo['camera_model']}"))
|
self.l_meta_content_06.setText(str(f"{f_photo['camera_brand']} {f_photo['camera_model']}"))
|
||||||
self.l_meta_content_07.setText(str(f_photo['aperture']))
|
self.l_meta_content_07.setText(str(f_photo['aperture']))
|
||||||
self.l_meta_content_08.setText(str(f_photo['size']['megapixels']))
|
self.l_meta_content_08.setText(str(f_photo['size']['megapixels']))
|
||||||
|
|
||||||
|
@ -221,13 +227,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.l_meta_08.setText('Pix Format')
|
self.l_meta_08.setText('Pix Format')
|
||||||
|
|
||||||
self.l_meta_content_01.setText(str(f_video['size']['width_height']))
|
self.l_meta_content_01.setText(str(f_video['size']['width_height']))
|
||||||
self.l_meta_content_02.setText(str(f_video['r_framerate']))
|
self.l_meta_content_02.setText(str(f_video['r_frame_rate']))
|
||||||
self.l_meta_content_03.setText(str(f_video['bit_depth']))
|
self.l_meta_content_03.setText(str(f_video['bits_per_raw_sample']))
|
||||||
self.l_meta_content_04.setText(str(f_video['duration']))
|
self.l_meta_content_04.setText(str(f_video['duration']))
|
||||||
self.l_meta_content_05.setText(str(f_video['encoding']))
|
self.l_meta_content_05.setText(str(f_video['encoding_brand']))
|
||||||
self.l_meta_content_06.setText(str(f_video['codec']))
|
self.l_meta_content_06.setText(str(f_video['codec_long_name']))
|
||||||
self.l_meta_content_07.setText(str(f_video['profile']))
|
self.l_meta_content_07.setText(str(f_video['profile']))
|
||||||
self.l_meta_content_08.setText(str(f_video['pix_format']))
|
self.l_meta_content_08.setText(str(f_video['pix_fmt']))
|
||||||
|
|
||||||
def clear_metadata(self):
|
def clear_metadata(self):
|
||||||
self.l_meta_01.setText('')
|
self.l_meta_01.setText('')
|
||||||
|
@ -252,6 +258,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
if i is None:
|
if i is None:
|
||||||
self.set_default_thumbnail()
|
self.set_default_thumbnail()
|
||||||
else:
|
else:
|
||||||
|
self.process_file(i.text())
|
||||||
print(f'index changed to: {i.text()}')
|
print(f'index changed to: {i.text()}')
|
||||||
preview = self.get_preview(i.text())
|
preview = self.get_preview(i.text())
|
||||||
self.update_preview(preview)
|
self.update_preview(preview)
|
||||||
|
@ -309,7 +316,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
def worker_thread_done(self):
|
def worker_thread_done(self):
|
||||||
print('scan thread complete.')
|
print('scan thread complete.')
|
||||||
self.toggle_scan_button(True)
|
self.toggle_scan_button(True)
|
||||||
if 0 < len(self.files):
|
if 0 < len(self.file_list):
|
||||||
self.toggle_import_button(True)
|
self.toggle_import_button(True)
|
||||||
else:
|
else:
|
||||||
self.toggle_import_button(False)
|
self.toggle_import_button(False)
|
||||||
|
@ -319,6 +326,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
print("THREAD COMPLETE.")
|
print("THREAD COMPLETE.")
|
||||||
|
|
||||||
def add_found_file_to_list(self,f):
|
def add_found_file_to_list(self,f):
|
||||||
|
sph = self.get_source_path_hash(f)
|
||||||
|
self.files[sph] = {}
|
||||||
self.file_list.addItem(f)
|
self.file_list.addItem(f)
|
||||||
|
|
||||||
def gen_file_dict(self,d):
|
def gen_file_dict(self,d):
|
||||||
|
@ -342,7 +351,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.file_total = self.get_t_files()
|
self.file_total = self.get_t_files()
|
||||||
self.set_total_files(self.file_total)
|
self.set_total_files(self.file_total)
|
||||||
|
|
||||||
time.sleep(3)
|
# time.sleep(3)
|
||||||
|
|
||||||
file_finder = FindFiles(search_types=self.search_types,
|
file_finder = FindFiles(search_types=self.search_types,
|
||||||
src_dir=self.src_dir,
|
src_dir=self.src_dir,
|
||||||
|
@ -358,8 +367,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.find_files_dialog.set_progress_finding_files)
|
self.find_files_dialog.set_progress_finding_files)
|
||||||
worker.signals.found_file.connect(
|
worker.signals.found_file.connect(
|
||||||
self.add_found_file_to_list)
|
self.add_found_file_to_list)
|
||||||
worker.signals.found_file.connect(
|
# worker.signals.found_file.connect(
|
||||||
self.process_file)
|
# self.process_file)
|
||||||
worker.signals.total_file_count.connect(
|
worker.signals.total_file_count.connect(
|
||||||
self.set_total_files)
|
self.set_total_files)
|
||||||
# worker.signals.result.connect(
|
# worker.signals.result.connect(
|
||||||
|
@ -375,16 +384,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.threadpool.start(worker)
|
self.threadpool.start(worker)
|
||||||
|
|
||||||
# From _media_import.py
|
# From _media_import.py
|
||||||
def is_video(self,f):
|
def is_video(self,sph):
|
||||||
if self.files[f]['type'] == 'video':
|
print(f"Should be sph: {sph}")
|
||||||
|
print(f"Should be filetype: {self.files[sph]['file_type']}")
|
||||||
|
if self.files[sph]['file_type'] == 'video':
|
||||||
r = True
|
r = True
|
||||||
else:
|
else:
|
||||||
r = False
|
r = False
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def is_image(self,f):
|
def is_image(self,sph):
|
||||||
if self.files[f]['type'] == 'image':
|
if self.files[sph]['file_type'] == 'image':
|
||||||
r = True
|
r = True
|
||||||
else:
|
else:
|
||||||
r = False
|
r = False
|
||||||
|
@ -392,51 +403,70 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def t_copy_files(self,
|
def t_copy_files(self,
|
||||||
import_progress_callback,
|
progress_callback,
|
||||||
current_file_progress_callback,
|
current_file_progress_callback,
|
||||||
imported_file_count_callback
|
imported_file_count_callback,
|
||||||
|
found_file_callback,
|
||||||
|
total_file_count_callback
|
||||||
):
|
):
|
||||||
""" Copy Files. """
|
""" Copy Files. """
|
||||||
count = int(0)
|
count = int(0)
|
||||||
for file in self.files:
|
for line in range(self.file_list.count()):
|
||||||
self.src_dir = self.files[file]['folders']['source_path']
|
item = self.file_list.item(line)
|
||||||
self.dst_dir = self.files[file]['folders']['destination']
|
file = item.text()
|
||||||
|
self.process_file(file)
|
||||||
|
sph = self.get_source_path_hash(file)
|
||||||
|
print(sph)
|
||||||
|
self.src_dir = self.files[sph]['folders']['source_path']
|
||||||
|
self.dst_dir = self.files[sph]['folders']['destination']
|
||||||
self.path_file_source = path.join(self.src_dir,
|
self.path_file_source = path.join(self.src_dir,
|
||||||
self.files[file]['name'])
|
self.files[sph]['name'])
|
||||||
self.path_file_destination = path.join(self.dst_dir,
|
self.path_file_destination = path.join(self.dst_dir,
|
||||||
self.files[file]['name'])
|
self.files[sph]['name'])
|
||||||
self.destination_original_path = path.join(self.dst_dir,
|
self.destination_original_path = path.join(self.dst_dir,
|
||||||
self.files[file]['folders']['destination_original'])
|
self.files[sph]['folders']['destination_original'])
|
||||||
self.path_file_destination_original = path.join(self.dst_dir,
|
self.path_file_destination_original = path.join(self.dst_dir,
|
||||||
self.files[file]['folders']['destination_original'],
|
self.files[sph]['folders']['destination_original'],
|
||||||
self.files[file]['name'])
|
self.files[sph]['name'])
|
||||||
|
|
||||||
self.imp_dialog.set_importing_file(self.path_file_source)
|
self.imp_dialog.set_importing_file(self.path_file_source)
|
||||||
|
|
||||||
self.copy_a_file(
|
self.copy_a_file(
|
||||||
file,
|
sph,
|
||||||
current_file_progress_callback)
|
progress_callback,
|
||||||
|
current_file_progress_callback,
|
||||||
|
imported_file_count_callback,
|
||||||
|
found_file_callback,
|
||||||
|
total_file_count_callback
|
||||||
|
)
|
||||||
|
|
||||||
if self.check_store_original(file) is True:
|
if self.check_store_original(sph) is True:
|
||||||
self.copy_a_file(file,
|
self.copy_a_file(sph,
|
||||||
current_file_progress_callback)
|
progress_callback,
|
||||||
|
current_file_progress_callback,
|
||||||
|
imported_file_count_callback,
|
||||||
|
found_file_callback,
|
||||||
|
total_file_count_callback)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
imported_file_count_callback.emit(count)
|
imported_file_count_callback.emit(count)
|
||||||
import_progress_callback.emit(round((count / self.file_total) * 100, 1))
|
progress_callback.emit(round((count / self.file_total) * 100, 1))
|
||||||
self.imp_dialog.add_to_imported_list(self.path_file_source)
|
self.imp_dialog.add_to_imported_list(self.path_file_source)
|
||||||
|
|
||||||
def copy_a_file(self,
|
def copy_a_file(self,
|
||||||
_f,
|
fph,
|
||||||
current_file_progress_callback):
|
progress_callback,
|
||||||
|
current_file_progress_callback,
|
||||||
|
imported_file_count_callback,
|
||||||
|
found_file_callback,
|
||||||
|
total_file_count_callback):
|
||||||
|
|
||||||
size = path.getsize(self.path_file_source)
|
size = path.getsize(self.path_file_source)
|
||||||
create_folder(self.dst_dir)
|
create_folder(self.dst_dir)
|
||||||
|
|
||||||
self.check_duplicate(_f)
|
self.check_duplicate(fph)
|
||||||
|
|
||||||
if self.is_video(_f):
|
if self.is_video(fph):
|
||||||
self.chunk_size = (1024 * 1024) * 5
|
self.chunk_size = (1024 * 1024) * 5
|
||||||
else:
|
else:
|
||||||
self.chunk_size = (16 * 1024) * 1
|
self.chunk_size = (16 * 1024) * 1
|
||||||
|
@ -451,9 +481,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
dst_size = path.getsize(self.path_file_destination)
|
dst_size = path.getsize(self.path_file_destination)
|
||||||
current_file_progress_callback.emit(round((dst_size / size) * 100, 1))
|
current_file_progress_callback.emit(round((dst_size / size) * 100, 1))
|
||||||
|
|
||||||
def check_store_original(self,_f):
|
def check_store_original(self,sph):
|
||||||
if self.config['store_originals'] is True:
|
if self.config['store_originals'] is True:
|
||||||
if self.is_image(_f):
|
if self.is_image(sph):
|
||||||
self.dst_dir = self.destination_original_path
|
self.dst_dir = self.destination_original_path
|
||||||
self.path_file_destination = self.path_file_destination_original
|
self.path_file_destination = self.path_file_destination_original
|
||||||
r = True
|
r = True
|
||||||
|
@ -464,12 +494,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def check_duplicate(self,_f):
|
def check_duplicate(self,sph):
|
||||||
if path_exists(self.path_file_destination):
|
if path_exists(self.path_file_destination):
|
||||||
check_match = cmp_files(self.path_file_source, self.path_file_destination)
|
check_match = cmp_files(self.path_file_source, self.path_file_destination)
|
||||||
if check_match is False:
|
if check_match is False:
|
||||||
print(f'\nFound duplicate for {self.path_file_source}, renaming destination with hash appended.')
|
print(f'\nFound duplicate for {self.path_file_source}, renaming destination with hash appended.')
|
||||||
base, extension = path.splitext(self.files[_f]['name'])
|
base, extension = path.splitext(self.files[sph]['name'])
|
||||||
f_xxhash = xx_hash(self.path_file_destination)
|
f_xxhash = xx_hash(self.path_file_destination)
|
||||||
file_name_hash = base + '_' + f_xxhash + extension
|
file_name_hash = base + '_' + f_xxhash + extension
|
||||||
rename(self.path_file_destination, path.join(self.dst_dir, file_name_hash))
|
rename(self.path_file_destination, path.join(self.dst_dir, file_name_hash))
|
||||||
|
@ -491,7 +521,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
self.worker_thread_started)
|
self.worker_thread_started)
|
||||||
worker.signals.started.connect(
|
worker.signals.started.connect(
|
||||||
self.imp_dialog.open_import_dialog)
|
self.imp_dialog.open_import_dialog)
|
||||||
worker.signals.import_progress.connect(
|
worker.signals.progress.connect(
|
||||||
self.imp_dialog.set_progress_importing)
|
self.imp_dialog.set_progress_importing)
|
||||||
worker.signals.current_file_progress.connect(
|
worker.signals.current_file_progress.connect(
|
||||||
self.imp_dialog.set_progress_current_file)
|
self.imp_dialog.set_progress_current_file)
|
||||||
|
|
|
@ -21,7 +21,7 @@ class MediaFile:
|
||||||
self.config = config
|
self.config = config
|
||||||
self.event_name = str(event_name)
|
self.event_name = str(event_name)
|
||||||
self.store_originals = self.config['store_originals']
|
self.store_originals = self.config['store_originals']
|
||||||
self.src_dir = self.config['folders']['source']['base']
|
self.src_dir = os.path.dirname(self.path_file_name)
|
||||||
self.base_dst_dir = self.config['folders']['destination']['base']
|
self.base_dst_dir = self.config['folders']['destination']['base']
|
||||||
self.source_path_hash = hash_path(self.path_file_name)
|
self.source_path_hash = hash_path(self.path_file_name)
|
||||||
self.file_name = get_file_name(self.path_file_name)
|
self.file_name = get_file_name(self.path_file_name)
|
||||||
|
@ -61,7 +61,7 @@ class MediaFile:
|
||||||
p = f'{p1}/{p2}/{p3}' # <--- Dumb.
|
p = f'{p1}/{p2}/{p3}' # <--- Dumb.
|
||||||
if self.event_name:
|
if self.event_name:
|
||||||
p4 = '-' + self.event_name
|
p4 = '-' + self.event_name
|
||||||
p = os.path.join(p,p4)
|
p = p + p4
|
||||||
|
|
||||||
if self.file_type == 'image':
|
if self.file_type == 'image':
|
||||||
p = os.path.join(p,'PHOTO')
|
p = os.path.join(p,'PHOTO')
|
||||||
|
|
|
@ -15,15 +15,15 @@ class MediaPreview:
|
||||||
self.source_path_hash = hash_path(self.path_file_name)
|
self.source_path_hash = hash_path(self.path_file_name)
|
||||||
# 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')
|
# 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.thumbnail = 'thumbnail.jpg'
|
||||||
self.thumbnail_ratio = self.media_files_list[self.source_path_hash]['image_meta']['photo']['size']['ratio']
|
|
||||||
self.file_type = self.media_files_list[self.source_path_hash]['file_type']
|
self.file_type = self.media_files_list[self.source_path_hash]['file_type']
|
||||||
|
|
||||||
if self.media_files_list[self.source_path_hash]['file_type'] == 'image':
|
if self.media_files_list[self.source_path_hash]['file_type'] == 'image':
|
||||||
|
self.thumbnail_ratio = self.media_files_list[self.source_path_hash]['image_meta']['photo']['size']['ratio']
|
||||||
|
self.mpixels = self.media_files_list[self.source_path_hash]['image_meta']['photo']['size']['megapixels']
|
||||||
self._img_preview()
|
self._img_preview()
|
||||||
elif self.media_files_list[self.source_path_hash]['file_type'] == 'video':
|
elif self.media_files_list[self.source_path_hash]['file_type'] == 'video':
|
||||||
self._video_preview()
|
self._video_preview()
|
||||||
|
|
||||||
self.mpixels = self.media_files_list[self.source_path_hash]['image_meta']['photo']['size']['megapixels']
|
|
||||||
|
|
||||||
def _img_preview(self):
|
def _img_preview(self):
|
||||||
if self.media_files_list[self.source_path_hash]['image_meta']['photo']['is_jpg'] is True:
|
if self.media_files_list[self.source_path_hash]['image_meta']['photo']['is_jpg'] is True:
|
||||||
|
@ -52,7 +52,7 @@ class MediaPreview:
|
||||||
self.thumbnail = extract_jpg_thumb(self.path_file_name)
|
self.thumbnail = extract_jpg_thumb(self.path_file_name)
|
||||||
|
|
||||||
def _video_preview(self):
|
def _video_preview(self):
|
||||||
vid = VideoFile(file=self.path_file_name)
|
vid = VideoFile(path_file_name=self.path_file_name)
|
||||||
self.thumbnail = vid.gen_video_thumbnail()
|
self.thumbnail = vid.gen_video_thumbnail()
|
||||||
|
|
||||||
self.width = self.media_files_list[self.source_path_hash]['video_meta']['video']['size']['width']
|
self.width = self.media_files_list[self.source_path_hash]['video_meta']['video']['size']['width']
|
||||||
|
|
|
@ -39,6 +39,7 @@ class VideoFile:
|
||||||
"""
|
"""
|
||||||
Generate a thumbnail from a video
|
Generate a thumbnail from a video
|
||||||
"""
|
"""
|
||||||
|
self.video_meta()
|
||||||
time_seconds = self.stream['video']['seconds'] // 5
|
time_seconds = self.stream['video']['seconds'] // 5
|
||||||
v_width = int(self.stream['video']['size']['width'])
|
v_width = int(self.stream['video']['size']['width'])
|
||||||
width = self.set_thumb_width(v_width)
|
width = self.set_thumb_width(v_width)
|
||||||
|
@ -117,6 +118,7 @@ class VideoFile:
|
||||||
'video': {
|
'video': {
|
||||||
'bits_per_raw_sample': self.video_stream['bits_per_raw_sample'],
|
'bits_per_raw_sample': self.video_stream['bits_per_raw_sample'],
|
||||||
'codec_long_name': self.video_stream['codec_long_name'],
|
'codec_long_name': self.video_stream['codec_long_name'],
|
||||||
|
'seconds': float(self.video_stream['duration']),
|
||||||
'duration': self.convert_from_seconds(float(self.video_stream['duration'])),
|
'duration': self.convert_from_seconds(float(self.video_stream['duration'])),
|
||||||
'encoding_brand': self.format_stream['tags']['major_brand'],
|
'encoding_brand': self.format_stream['tags']['major_brand'],
|
||||||
'pix_fmt': self.video_stream['pix_fmt'],
|
'pix_fmt': self.video_stream['pix_fmt'],
|
||||||
|
|
Loading…
Reference in New Issue