Now works with optima35 0.5.0

This commit is contained in:
Mr Finchum 2025-01-02 15:11:15 +01:00
parent 1bc135e8c3
commit ad62200bb5
2 changed files with 189 additions and 172 deletions

226
gui.py
View file

@ -26,48 +26,48 @@ from PySide6.QtWidgets import (
class Optima35GUI(QMainWindow, Ui_MainWindow): class Optima35GUI(QMainWindow, Ui_MainWindow):
def __init__(self, exif_file): def __init__(self, exif_file):
super(Optima35GUI, self).__init__() super(Optima35GUI, self).__init__()
self.name = "GUI35"
self.version = "0.1.0"
self.ui = Ui_MainWindow() self.ui = Ui_MainWindow()
self.ui.setupUi(self) self.ui.setupUi(self)
self.o = OPTIMA35() self.o = OPTIMA35()
self.u = Utilities() self.u = Utilities()
self.exif_file = exif_file self.exif_file = exif_file
self.exif_data = None self.available_exif_data = None
self.settings = {}
self.setWindowTitle(f"{self.o.name} {self.o.version}") self.setWindowTitle(f"{self.name} v{self.version} for {self.o.name} {self.o.version}")
self.default_ui_layout() self._default_ui_layout()
self.define_gui_interaction() self._define_gui_interaction()
if exif_file == "config/exif_example.yaml": if exif_file == "config/exif_example.yaml":
self.change_statusbar("Using example exif...", 10000) self._change_statusbar("Using example exif...", 10000)
def default_ui_layout(self): def _default_ui_layout(self):
self.ui.png_quality_spinBox.setVisible(False) self.ui.png_quality_spinBox.setVisible(False)
def define_gui_interaction(self): def _define_gui_interaction(self):
self.ui.input_folder_button.clicked.connect(self.browse_input_folder) self.ui.input_folder_button.clicked.connect(self._browse_input_folder)
self.ui.output_folder_button.clicked.connect(self.browse_output_folder) self.ui.output_folder_button.clicked.connect(self._browse_output_folder)
self.ui.start_button.clicked.connect(self.process) self.ui.start_button.clicked.connect(self._process)
self.ui.image_type.currentIndexChanged.connect(self.update_quality_options) self.ui.image_type.currentIndexChanged.connect(self._update_quality_options)
self.ui.exif_checkbox.stateChanged.connect( self.ui.exif_checkbox.stateChanged.connect(
lambda state: self.handle_checkbox_state(state, 2, self.populate_exif) lambda state: self._handle_checkbox_state(state, 2, self._populate_exif)
) )
self.ui.tabWidget.currentChanged.connect(self.on_tab_changed) self.ui.tabWidget.currentChanged.connect(self._on_tab_changed)
self.ui.edit_exif_button.clicked.connect(self.open_exif_editor) self.ui.edit_exif_button.clicked.connect(self._open_exif_editor)
self.ui.restart_button.clicked.connect(self.restart_app)
def process(self): def _process(self):
#self.ui.start_button.setEnabled(False) self.ui.start_button.setEnabled(False)
#self.ui.restart_button.setEnabled(False) self._update_settings() # Get all user selected data
self.check_options() # Get all user selected data input_folder_valid = os.path.exists(self.settings["input_folder"])
input_folder_valid = os.path.exists(self.o.settings["input_folder"]) output_folder_valid = os.path.exists(self.settings["output_folder"])
output_folder_valid = os.path.exists(self.o.settings["output_folder"])
if not input_folder_valid or not output_folder_valid: if not input_folder_valid or not output_folder_valid:
QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...") QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...")
return return
input_folder = self.o.settings["input_folder"] input_folder = self.settings["input_folder"]
output_folder = self.o.settings["output_folder"] output_folder = self.settings["output_folder"]
image_files = [ image_files = [
f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")) f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
@ -75,52 +75,66 @@ class Optima35GUI(QMainWindow, Ui_MainWindow):
i = 1 i = 1
for image_file in image_files: for image_file in image_files:
input_path = os.path.join(input_folder, image_file) input_path = os.path.join(input_folder, image_file)
if self.o.settings["new_file_names"] != False: if self.settings["new_file_names"] != False:
image_name = self.o.name_images(self.o.settings["new_file_names"], i, len(image_files), self.o.settings["invert_image_order"]) image_name = self.u.append_number_to_name(self.settings["new_file_names"], i, len(image_files), self.settings["invert_image_order"])
else: else:
image_name = os.path.splitext(image_file)[0] image_name = os.path.splitext(image_file)[0]
output_path = os.path.join(output_folder, image_name) output_path = os.path.join(output_folder, image_name)
self.o.process(input_path, output_path) self.o.process_image(
self.handle_qprogressbar(i, len(image_files)) image_input_file = input_path,
image_output_file = output_path,
file_type = self.settings["file_format"],
quality = self.settings["jpg_quality"],
compressing = self.settings["png_compression"],
optimize = self.ui.optimize_checkBox.isChecked(),
resize = self.settings["resize"],
watermark = self.settings["watermark"],
font_size = self.settings["font_size"],
grayscale = self.settings["grayscale"],
brightness = self.settings["brightness"],
contrast = self.settings["contrast"],
dict_for_exif = self.user_selected_exif,
gps = self.settings["gps"],
copy_exif = self.settings["copy_exif"])
self._handle_qprogressbar(i, len(image_files))
i += 1 i += 1
QMessageBox.information(self, "Information", "Finished") QMessageBox.information(self, "Information", "Finished")
#self.ui.start_button.setEnabled(True) self.ui.start_button.setEnabled(True)
#self.ui.restart_button.setEnabled(True)
self.ui.progressBar.setValue(0) self.ui.progressBar.setValue(0)
def open_exif_editor(self): def _open_exif_editor(self):
"""Open the EXIF Editor.""" """Open the EXIF Editor."""
self.exif_editor = ExifEditor(self.exif_data) self.exif_editor = ExifEditor(self.available_exif_data)
self.exif_editor.exif_data_updated.connect(self.update_exif_data) self.exif_editor.exif_data_updated.connect(self._update_exif_data)
self.exif_editor.show() self.exif_editor.show()
def update_exif_data(self, updated_exif_data): def _update_exif_data(self, updated_exif_data):
"""Update the EXIF data.""" """Update the EXIF data."""
self.exif_data = updated_exif_data self.exif_data = updated_exif_data
self.populate_exif() self._populate_exif()
def handle_checkbox_state(self, state, desired_state, action): def _handle_checkbox_state(self, state, desired_state, action):
"""Perform an action based on the checkbox state and a desired state. Have to use lambda when calling.""" """Perform an action based on the checkbox state and a desired state. Have to use lambda when calling."""
if state == desired_state: if state == desired_state:
action() action()
def on_tab_changed(self, index): def _on_tab_changed(self, index):
"""Handle tab changes.""" """Handle tab changes."""
# chatgpt # chatgpt
if index == 1: # EXIF Tab if index == 1: # EXIF Tab
self.handle_exif_file("read") self._handle_exif_file("read")
elif index == 0: # Main Tab elif index == 0: # Main Tab
self.handle_exif_file("write") self._handle_exif_file("write")
def handle_exif_file(self, do): def _handle_exif_file(self, do):
if do == "read": if do == "read":
self.exif_data = self.u.read_yaml(self.exif_file) self.available_exif_data = self.u.read_yaml(self.exif_file)
elif do == "write": elif do == "write":
self.u.write_yaml(self.exif_file, self.exif_data) self.u.write_yaml(self.exif_file, self.available_exif_data)
def populate_exif(self): def _populate_exif(self):
# partly chatGPT # partly chatGPT
# Mapping of EXIF fields to comboboxes in the UI # Mapping of EXIF fields to comboboxes in the UI
combo_mapping = { combo_mapping = {
@ -133,16 +147,16 @@ class Optima35GUI(QMainWindow, Ui_MainWindow):
"artist": self.ui.artist_comboBox, "artist": self.ui.artist_comboBox,
"copyright_info": self.ui.copyright_info_comboBox, "copyright_info": self.ui.copyright_info_comboBox,
} }
self.populate_comboboxes(combo_mapping) self._populate_comboboxes(combo_mapping)
def populate_comboboxes(self, combo_mapping): def _populate_comboboxes(self, combo_mapping):
"""Populate comboboxes with EXIF data.""" """Populate comboboxes with EXIF data."""
# ChatGPT # ChatGPT
for field, comboBox in combo_mapping.items(): for field, comboBox in combo_mapping.items():
comboBox.clear() # Clear existing items comboBox.clear() # Clear existing items
comboBox.addItems(map(str, self.exif_data.get(field, []))) comboBox.addItems(map(str, self.available_exif_data.get(field, [])))
def update_quality_options(self): def _update_quality_options(self):
"""Update visibility of quality settings based on selected format.""" """Update visibility of quality settings based on selected format."""
# ChatGPT # ChatGPT
selected_format = self.ui.image_type.currentText() selected_format = self.ui.image_type.currentText()
@ -157,82 +171,88 @@ class Optima35GUI(QMainWindow, Ui_MainWindow):
elif selected_format == "png": elif selected_format == "png":
self.ui.png_quality_spinBox.setVisible(True) self.ui.png_quality_spinBox.setVisible(True)
def browse_input_folder(self): def _browse_input_folder(self):
folder = QFileDialog.getExistingDirectory(self, "Select Input Folder") folder = QFileDialog.getExistingDirectory(self, "Select Input Folder")
if folder: if folder:
self.ui.input_path.setText(folder) self.ui.input_path.setText(folder)
def browse_output_folder(self): def _browse_output_folder(self):
folder = QFileDialog.getExistingDirectory(self, "Select Output Folder") folder = QFileDialog.getExistingDirectory(self, "Select Output Folder")
if folder: if folder:
self.ui.output_path.setText(folder) self.ui.output_path.setText(folder)
def change_statusbar(self, msg, timeout = 500): def _change_statusbar(self, msg, timeout = 500):
self.ui.statusBar.showMessage(msg, timeout) self.ui.statusBar.showMessage(msg, timeout)
def handle_qprogressbar(self, current, total): def _handle_qprogressbar(self, current, total):
progress = int((100 / total) * current) progress = int((100 / total) * current)
self.ui.progressBar.setValue(progress) self.ui.progressBar.setValue(progress)
def check_options(self): def _get_checkbox_value(self, checkbox, default=None):
try: """Helper function to get the value of a checkbox or a default value."""
self.o.settings["input_folder"] = self.ui.input_path.text() return checkbox.isChecked() if checkbox else default
self.o.settings["output_folder"] = self.ui.output_path.text()
self.o.settings["file_format"] = self.ui.image_type.currentText()
self.o.settings["jpg_quality"] = int(self.ui.jpg_quality_spinBox.text())
self.o.settings["png_compression"] = int(self.ui.png_quality_spinBox.text())
self.o.settings["invert_image_order"] = self.ui.revert_checkbox.isChecked()
self.o.settings["grayscale"] = self.ui.grayscale_checkBox.isChecked()
self.o.settings["copy_exif"] = self.ui.exif_copy_checkBox.isChecked()
self.o.settings["own_exif"] = self.ui.exif_checkbox.isChecked()
self.o.settings["font_size"] = self.ui.font_size_comboBox.currentIndex() + 1
self.o.settings["optimize"] = self.ui.optimize_checkBox.isChecked()
self.o.settings["own_date"] = self.ui.add_date_checkBox.isChecked()
if self.ui.resize_checkbox.isChecked(): def _get_spinbox_value(self, spinbox, default=None):
self.o.settings["resize"] = int(self.ui.resize_spinBox.text()) """Helper function to get the value of a spinbox and handle empty input."""
return int(spinbox.text()) if spinbox.text() else default
if self.ui.brightness_checkbox.isChecked(): def _get_combobox_value(self, combobox, default=None):
self.o.settings["brightness"] = int(self.ui.brightness_spinBox.text()) """Helper function to get the value of a combobox."""
return combobox.currentIndex() + 1 if combobox.currentIndex() != -1 else default
if self.ui.contrast_checkbox.isChecked(): def _get_text_value(self, lineedit, default=None):
self.o.settings["contrast"] = int(self.ui.contrast_spinBox.text()) """Helper function to get the value of a text input field."""
return lineedit.text() if lineedit.text() else default
if self.ui.rename_checkbox.isChecked(): def _get_selected_exif(self):
if self.ui.filename.text() != "": """Collect selected EXIF data and handle date and GPS if necessary."""
self.o.settings["new_file_names"] = self.ui.filename.text() selected_exif = self._collect_selected_exif() if self.ui.exif_checkbox.isChecked() else None
else: if selected_exif:
self.o.settings["new_file_names"] = False
else:
self.o.settings["new_file_names"] = False
if self.ui.watermark_checkbox.isChecked():
if self.ui.watermark_lineEdit.text() != "":
self.o.settings["watermark"] = self.ui.watermark_lineEdit.text()
else:
self.o.settings["watermark"] = False
else:
self.o.settings["watermark"] = False
if self.o.settings["own_exif"]:
self.o.selected_exif = self.collect_selected_exif()
if self.ui.add_date_checkBox.isChecked(): if self.ui.add_date_checkBox.isChecked():
self.o.selected_exif["date_time_original"] = self.get_date() selected_exif["date_time_original"] = self._get_date()
if self.ui.gps_checkBox.isChecked(): if self.ui.gps_checkBox.isChecked():
self.o.settings["gps"] = [self.ui.lat_lineEdit.text(), self.ui.long_lineEdit.text()] self.settings["gps"] = [self.ui.lat_lineEdit.text(), self.ui.long_lineEdit.text()]
else: else:
self.o.settings["gps"] = False self.settings["gps"] = None
return selected_exif
except Exception as e: def _update_settings(self):
print(f"Whoops: {e}") """Update .settings from all GUI elements."""
# General settings
self.settings["input_folder"] = self._get_text_value(self.ui.input_path)
self.settings["output_folder"] = self._get_text_value(self.ui.output_path)
self.settings["file_format"] = self.ui.image_type.currentText()
self.settings["jpg_quality"] = self._get_spinbox_value(self.ui.jpg_quality_spinBox)
self.settings["png_compression"] = self._get_spinbox_value(self.ui.png_quality_spinBox)
self.settings["invert_image_order"] = self._get_checkbox_value(self.ui.revert_checkbox)
self.settings["grayscale"] = self._get_checkbox_value(self.ui.grayscale_checkBox)
self.settings["copy_exif"] = self._get_checkbox_value(self.ui.exif_copy_checkBox)
self.settings["own_exif"] = self._get_checkbox_value(self.ui.exif_checkbox)
self.settings["font_size"] = self._get_combobox_value(self.ui.font_size_comboBox)
self.settings["optimize"] = self._get_checkbox_value(self.ui.optimize_checkBox)
self.settings["own_date"] = self._get_checkbox_value(self.ui.add_date_checkBox)
def get_date(self): # Conditional settings with logic
self.settings["resize"] = self._get_spinbox_value(self.ui.resize_spinBox) if self.ui.resize_checkbox.isChecked() else None
self.settings["brightness"] = self._get_spinbox_value(self.ui.brightness_spinBox) if self.ui.brightness_checkbox.isChecked() else None
self.settings["contrast"] = self._get_spinbox_value(self.ui.contrast_spinBox) if self.ui.contrast_checkbox.isChecked() else None
self.settings["new_file_names"] = self._get_text_value(self.ui.filename, False) if self.ui.rename_checkbox.isChecked() else False
self.settings["watermark"] = self._get_text_value(self.ui.watermark_lineEdit) if self.ui.watermark_checkbox.isChecked() else None
# Handle EXIF data selection
if self.settings["own_exif"]:
self.user_selected_exif = self._get_selected_exif()
else:
self.user_selected_exif = None
self.settings["gps"] = None
def _get_date(self):
date_input = self.ui.dateEdit.date().toString("yyyy-MM-dd") date_input = self.ui.dateEdit.date().toString("yyyy-MM-dd")
new_date = datetime.strptime(date_input, "%Y-%m-%d") new_date = datetime.strptime(date_input, "%Y-%m-%d")
return new_date.strftime("%Y:%m:%d 00:00:00") return new_date.strftime("%Y:%m:%d 00:00:00")
def collect_selected_exif(self): def _collect_selected_exif(self):
user_data = {} user_data = {}
user_data["make"] = self.ui.make_comboBox.currentText() user_data["make"] = self.ui.make_comboBox.currentText()
user_data["model"] = self.ui.model_comboBox.currentText() user_data["model"] = self.ui.model_comboBox.currentText()
@ -245,18 +265,6 @@ class Optima35GUI(QMainWindow, Ui_MainWindow):
user_data["software"] = f"{self.o.name} {self.o.version}" user_data["software"] = f"{self.o.name} {self.o.version}"
return user_data return user_data
def rebuild_ui(self):
# Define the bash script to execute
bash_script = "/home/sam/git/gitlab_public/optima-35/rebuild_ui.sh"
os.system(bash_script)
def restart_app(self):
"""Restarts the application."""
self.rebuild_ui()
# chatGPT
python = sys.executable # Path to the Python interpreter
os.execv(python, [python] + sys.argv)
def main(exif_file): def main(exif_file):
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
window = Optima35GUI(exif_file=exif_file) window = Optima35GUI(exif_file=exif_file)

135
tui.py
View file

@ -7,11 +7,13 @@ from ui.simple_tui import SimpleTUI
class Optima35TUI(): class Optima35TUI():
def __init__(self, exif_file, settings_file): def __init__(self, exif_file, settings_file):
self.name = "TUI35"
self.version = "0.1.0"
self.o = OPTIMA35() self.o = OPTIMA35()
self.u = Utilities() self.u = Utilities()
self.tui = SimpleTUI() self.tui = SimpleTUI()
self.exif_file = exif_file self.exif_file = exif_file
self.exif_data = self.u.read_yaml(exif_file) self.available_exif_data = self.u.read_yaml(exif_file)
self.setting_file = settings_file self.setting_file = settings_file
self.settings = { self.settings = {
"input_folder": None, "input_folder": None,
@ -36,19 +38,16 @@ class Optima35TUI():
"brightness" "brightness"
] ]
def process(self): def _process(self):
if "Change EXIF" in self.settings["modifications"]: self._check_options() # Get all user selected data
self.selected_exif = self.collect_exif_data() input_folder_valid = os.path.exists(self.settings["input_folder"])
self.check_options() # Get all user selected data output_folder_valid = os.path.exists(self.settings["output_folder"])
input_folder_valid = os.path.exists(self.o.settings["input_folder"])
output_folder_valid = os.path.exists(self.o.settings["output_folder"])
if not input_folder_valid or not output_folder_valid: if not input_folder_valid or not output_folder_valid:
print("Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...") print("Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...")
return return
input_folder = self.o.settings["input_folder"] input_folder = self.settings["input_folder"]
output_folder = self.o.settings["output_folder"] output_folder = self.settings["output_folder"]
image_files = [ image_files = [
f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")) f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
@ -56,80 +55,90 @@ class Optima35TUI():
i = 1 i = 1
for image_file in image_files: for image_file in image_files:
input_path = os.path.join(input_folder, image_file) input_path = os.path.join(input_folder, image_file)
if self.o.settings["new_file_names"] != False: if self.settings["new_file_names"] != False:
image_name = self.o.name_images(self.o.settings["new_file_names"], i, len(image_files), self.o.settings["invert_image_order"]) image_name = self.u.append_number_to_name(self.settings["new_file_names"], i, len(image_files), self.settings["invert_image_order"])
else: else:
image_name = os.path.splitext(image_file)[0] image_name = os.path.splitext(image_file)[0]
output_path = os.path.join(output_folder, image_name) output_path = os.path.join(output_folder, image_name)
self.o.process(input_path, output_path) self.o.process_image(
image_input_file = input_path,
image_output_file = output_path,
file_type = self.settings["file_format"],
quality = self.settings["jpg_quality"],
compressing = self.settings["png_compression"],
optimize = self.settings["optimize"],
resize = self.settings["resize"],
watermark = self.settings["watermark"],
font_size = self.settings["font_size"],
grayscale = self.settings["grayscale"],
brightness = self.settings["brightness"],
contrast = self.settings["contrast"],
dict_for_exif = self.selected_exif,
gps = self.settings["gps"],
copy_exif = self.settings["copy_exif"])
self.u.progress_bar(i, len(image_files)) self.u.progress_bar(i, len(image_files))
i += 1 i += 1
def check_options(self): def _check_options(self):
try: try:
if "Resize image" in self.settings["modifications"]: if "Resize image" in self.settings["modifications"]:
self.o.settings["resize"] = self.settings["resize"] self.settings["resize"] = self.settings["resize"]
else: else:
self.o.settings["resize"] = False self.settings["resize"] = None
if "Convert to grayscale" in self.settings["modifications"]: if "Convert to grayscale" in self.settings["modifications"]:
self.o.settings["grayscale"] = True self.settings["grayscale"] = True
else: else:
self.o.settings["grayscale"] = False self.settings["grayscale"] = False
if "Change contrast" in self.settings["modifications"]: if "Change contrast" in self.settings["modifications"]:
self.o.settings["contrast"] = self.settings["contrast"] self.settings["contrast"] = self.settings["contrast"]
else: else:
self.o.settings["contrast"] = False self.settings["contrast"] = None
if "Change brightness" in self.settings["modifications"]: if "Change brightness" in self.settings["modifications"]:
self.o.settings["brightness"] = self.settings["brightness"] self.settings["brightness"] = self.settings["brightness"]
else: else:
self.o.settings["brightness"] = False self.settings["brightness"] = None
if "Rename images" in self.settings["modifications"]: if "Rename images" in self.settings["modifications"]:
self.o.settings["new_file_names"] = self.settings["new_file_names"] self.settings["new_file_names"] = self.settings["new_file_names"]
else: else:
self.o.settings["new_file_names"] = False self.settings["new_file_names"] = False
if "Invert image order" in self.settings["modifications"]: if "Invert image order" in self.settings["modifications"]:
self.o.settings["invert_image_order"] = True self.settings["invert_image_order"] = True
else: else:
self.o.settings["invert_image_order"] = False self.settings["invert_image_order"] = False
if "Add Watermark" in self.settings["modifications"]: if "Add Watermark" in self.settings["modifications"]:
self.o.settings["watermark"] = self.settings["watermark"] self.settings["watermark"] = self.settings["watermark"]
else: else:
self.o.settings["watermark"] = False self.settings["watermark"] = None
self.o.settings["optimize"] = self.settings["optimize"] self.settings["optimize"] = self.settings["optimize"]
self.o.settings["png_compression"] = self.settings["png_compression"] self.settings["png_compression"] = self.settings["png_compression"]
self.o.settings["jpg_quality"] = self.settings["jpg_quality"] self.settings["jpg_quality"] = self.settings["jpg_quality"]
self.o.settings["input_folder"] = self.settings["input_folder"] self.settings["input_folder"] = self.settings["input_folder"]
self.o.settings["output_folder"] = self.settings["output_folder"] self.settings["output_folder"] = self.settings["output_folder"]
self.o.settings["file_format"] = self.settings["file_format"] self.settings["file_format"] = self.settings["file_format"]
self.o.settings["font_size"] = 2 # need to add option to select size self.settings["font_size"] = 2 # need to add option to select size
self.o.settings["copy_exif"] = self.settings["copy_exif"] self.settings["copy_exif"] = self.settings["copy_exif"]
if "Change EXIF" in self.settings["modifications"]: #missing if "Change EXIF" in self.settings["modifications"]: #missing
self.o.selected_exif = self.selected_exif # self.selected_exif = self._collect_exif_data() #
self.o.settings["own_exif"] = True
if self.settings["gps"] != None:
self.o.settings["gps"] = self.settings["gps"]
else: else:
self.o.settings["gps"] = False self.selected_exif = None
else:
self.o.settings["own_exif"] = False
except Exception as e: except Exception as e:
print(f"Whoops: {e}") print(f"Whoops: {e}")
def load_or_ask_settings(self): def _load_or_ask_settings(self):
"""Load settings from a YAML file or ask the user if not present or incomplete.""" """Load settings from a YAML file or ask the user if not present or incomplete."""
try: try:
if self.read_settings(self.settings_to_save): if self._read_settings(self.settings_to_save):
for item in self.settings_to_save: for item in self.settings_to_save:
print(f"{item}: {self.settings[item]}") print(f"{item}: {self.settings[item]}")
use_saved = self.tui.yes_no_menu("Use these settings?") use_saved = self.tui.yes_no_menu("Use these settings?")
@ -137,12 +146,12 @@ class Optima35TUI():
return return
else: else:
print("No settings found...") print("No settings found...")
self.ask_for_settings() self._ask_for_settings()
except Exception as e: except Exception as e:
print(f"Error: {e}") print(f"Error: {e}")
self.ask_for_settings() self._ask_for_settings()
def ask_for_settings(self): def _ask_for_settings(self):
print("Asking for new settings...\n") print("Asking for new settings...\n")
self.settings["resize"] = self.take_input_and_validate(question = "Default resize percentage (below 100 downscale, above upscale): ", accepted_type = int, min_value = 10, max_value = 200) self.settings["resize"] = self.take_input_and_validate(question = "Default resize percentage (below 100 downscale, above upscale): ", accepted_type = int, min_value = 10, max_value = 200)
self.settings["contrast"] = self.take_input_and_validate(question = "Default contrast percentage (negative = decrease, positive = increase): ", accepted_type = int, min_value = -100, max_value = 100) self.settings["contrast"] = self.take_input_and_validate(question = "Default contrast percentage (negative = decrease, positive = increase): ", accepted_type = int, min_value = -100, max_value = 100)
@ -151,16 +160,16 @@ class Optima35TUI():
self.settings["png_compression"] = self.take_input_and_validate(question = "PNG compression level (0-9, 6 default): ", accepted_type = int, min_value = 0, max_value = 9) self.settings["png_compression"] = self.take_input_and_validate(question = "PNG compression level (0-9, 6 default): ", accepted_type = int, min_value = 0, max_value = 9)
self.settings["optimize"] = self.tui.yes_no_menu("Optimize images i.e. compressing?") self.settings["optimize"] = self.tui.yes_no_menu("Optimize images i.e. compressing?")
self.write_settings(self.settings_to_save) self._write_settings(self.settings_to_save)
def write_settings(self, keys_to_save): def _write_settings(self, keys_to_save):
""""Write self.setting, but only specific values""" """"Write self.setting, but only specific values"""
keys = keys_to_save keys = keys_to_save
filtered_settings = {key: self.settings[key] for key in keys if key in self.settings} filtered_settings = {key: self.settings[key] for key in keys if key in self.settings}
self.u.write_yaml(self.setting_file, filtered_settings) self.u.write_yaml(self.setting_file, filtered_settings)
print("New settings saved successfully.") print("New settings saved successfully.")
def read_settings(self, keys_to_load): def _read_settings(self, keys_to_load):
""" """
Read settings from the settings file and update self.settings Read settings from the settings file and update self.settings
with the values for specific keys without overwriting existing values. with the values for specific keys without overwriting existing values.
@ -178,7 +187,7 @@ class Optima35TUI():
print("Settings file empty.") print("Settings file empty.")
return False return False
def collect_exif_data(self): def _collect_exif_data(self):
"""Collect EXIF data based on user input.""" """Collect EXIF data based on user input."""
user_data = {} user_data = {}
fields = [ fields = [
@ -187,24 +196,24 @@ class Optima35TUI():
] ]
for field in fields: for field in fields:
choise = self.tui.choose_menu(f"Enter {field.replace('_', ' ').title()}", self.exif_data[field]) choise = self.tui.choose_menu(f"Enter {field.replace('_', ' ').title()}", self.available_exif_data[field])
user_data[field] = choise user_data[field] = choise
user_data["software"] = f"{self.o.name} {self.o.version}" user_data["software"] = f"{self.o.name} {self.o.version}"
new_date = self.get_date_input() new_date = self._get_date_input()
if new_date: if new_date:
user_data["date_time_original"] = new_date user_data["date_time_original"] = new_date
self.settings["gps"] = self.get_gps_input(user_data) self.settings["gps"] = self._get_gps_input(user_data)
return user_data return user_data
def get_gps_input(self, test_exif): def _get_gps_input(self, test_exif):
while True: while True:
lat = input("Enter Latitude (xx.xxxxxx): ") lat = input("Enter Latitude (xx.xxxxxx): ")
if lat == "": if lat == "":
return False return None
long = input("Enter Longitude (xx.xxxxxx): ") long = input("Enter Longitude (xx.xxxxxx): ")
try: try:
self.o.exif_handler.add_geolocation_to_exif(test_exif, float(lat), float(long)) self.o.exif_handler.add_geolocation_to_exif(test_exif, float(lat), float(long))
@ -212,7 +221,7 @@ class Optima35TUI():
except Exception: except Exception:
print("Invalid GPS formate, try again...") print("Invalid GPS formate, try again...")
def get_date_input(self): def _get_date_input(self):
# Partially chatGPT # Partially chatGPT
while True: while True:
date_input = input("Enter a date (yyyy-mm-dd): ") date_input = input("Enter a date (yyyy-mm-dd): ")
@ -224,7 +233,7 @@ class Optima35TUI():
except ValueError: except ValueError:
print("Invalid date format. Please enter the date in yyyy-mm-dd format.") print("Invalid date format. Please enter the date in yyyy-mm-dd format.")
def get_user_settings(self): def _get_user_settings(self):
"""Get initial settings from the user.""" """Get initial settings from the user."""
menu_options = [ menu_options = [
"Resize image", "Resize image",
@ -241,7 +250,7 @@ class Optima35TUI():
self.settings["output_folder"] = input("Enter path of output folder: ").strip() self.settings["output_folder"] = input("Enter path of output folder: ").strip()
self.settings["file_format"] = self.take_input_and_validate(question = "Enter export file format (jpg, png, webp): ", accepted_input = ["jpg", "png", "webp"], accepted_type = str) self.settings["file_format"] = self.take_input_and_validate(question = "Enter export file format (jpg, png, webp): ", accepted_input = ["jpg", "png", "webp"], accepted_type = str)
self.settings["modifications"] = self.tui.multi_select_menu( self.settings["modifications"] = self.tui.multi_select_menu(
f"\n{self.o.name} v.{self.o.version} \nSelect what you want to do (esc or q to exit)", f"\n{self.name} v{self.version} for {self.o.name} v.{self.o.version} \nSelect what you want to do (esc or q to exit)",
menu_options menu_options
) )
if "Change EXIF" not in self.settings["modifications"]: if "Change EXIF" not in self.settings["modifications"]:
@ -304,9 +313,9 @@ class Optima35TUI():
def run(self): def run(self):
"""Run the main program.""" """Run the main program."""
self.load_or_ask_settings() self._load_or_ask_settings()
self.get_user_settings() self._get_user_settings()
self.process() self._process()
print("Done") print("Done")