From bfb2628afd2a702af7c1e690213bf21a0c1ec1c4 Mon Sep 17 00:00:00 2001 From: Chris Busillo Date: Wed, 12 Jun 2024 11:12:15 -0400 Subject: [PATCH] add time and emoji to start/stop --- bd_to_avp/gui/main_window.py | 46 +++++++++++++++++++++++------------- bd_to_avp/gui/processing.py | 3 ++- bd_to_avp/modules/util.py | 15 ++++++++++++ pyproject.toml | 2 ++ 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/bd_to_avp/gui/main_window.py b/bd_to_avp/gui/main_window.py index 749fda9..71b06cb 100644 --- a/bd_to_avp/gui/main_window.py +++ b/bd_to_avp/gui/main_window.py @@ -1,3 +1,4 @@ +from datetime import datetime from pathlib import Path from typing import Callable @@ -25,7 +26,7 @@ from bd_to_avp.gui.widget import FileFolderPicker, LabeledComboBox, LabeledLineEdit, LabeledSpinBox from bd_to_avp.modules.config import config, Stage from bd_to_avp.modules.disc import DiscInfo, MKVCreationError -from bd_to_avp.modules.util import Spinner, get_common_language_options +from bd_to_avp.modules.util import Spinner, formatted_time_elapsed, format_timestamp, get_common_language_options # noinspection PyAttributeOutsideInit @@ -43,7 +44,12 @@ def __init__(self) -> None: super().__init__() self.setup_window() self.create_main_layout() - self.create_menu_bar() + + self.processing_thread = ProcessingThread(main_window=self) + self.processing_thread.signals.progress_updated.connect(self.update_processing_output) + self.processing_thread.error_occurred.connect(self.handle_processing_error) + self.processing_thread.mkv_creation_error.connect(self.handle_mkv_creation_error) + self.processing_thread.process_completed.connect(self.finished_processing) def setup_window(self) -> None: app = QApplication.instance() @@ -202,33 +208,29 @@ def create_status_bar(self) -> None: self.splitter.splitterMoved.connect(self.update_status_bar) - self.processing_thread = ProcessingThread(main_window=self) - self.processing_thread.signals.progress_updated.connect(self.update_processing_output) - self.processing_thread.error_occurred.connect(self.handle_processing_error) - self.processing_thread.mkv_creation_error.connect(self.handle_mkv_creation_error) - def create_menu_bar(self) -> None: menu_bar = self.menuBar() - self.setMenuBar(self.menuBar()) app_menu = menu_bar.addMenu(QApplication.applicationName()) - about_action = QAction(f"About {QApplication.applicationName()}", self) - about_action.triggered.connect(self.show_about_dialog) - app_menu.addAction(about_action) - file_menu = menu_bar.addMenu("File") + help_menu = menu_bar.addMenu("Help") + file_menu.addAction(QAction("Open", self)) - help_menu = menu_bar.addMenu("Help") update_action = QAction("Update", self) update_action.triggered.connect(self.show_about_dialog) - help_menu.addAction(update_action) - self.setMenuBar(menu_bar) + about_action = QAction(f"About {QApplication.applicationName()}", self) + about_action.triggered.connect(self.show_about_dialog) + + app_menu.addAction(about_action) + help_menu.addAction(update_action) + # self.setMenuBar(menu_bar) def handle_processing_error(self, error: Exception) -> None: QMessageBox.warning(self, "Warning", "Failure in processing.") - self.update_processing_output(str(error)) + time_elapsed = formatted_time_elapsed(self.process_start_time) + self.update_processing_output(str(error) + f"\nāŒ Processing failed in {time_elapsed} āŒ") self.stop_processing() self.process_button.setText(self.START_PROCESSING_TEXT) @@ -298,6 +300,7 @@ def toggle_processing(self) -> None: if (source_folder_set and source_file_set) or (not source_folder_set and not source_file_set): QMessageBox.warning(self, "Warning", "Either Source Folder or Source File must be set, but not both.") return + self.start_processing() self.process_button.setText(self.STOP_PROCESSING_TEXT) else: @@ -310,9 +313,16 @@ def toggle_processing(self) -> None: def start_processing(self, is_continuing: bool = False) -> None: if not is_continuing: self.save_config() - + start_time = format_timestamp(datetime.now()) + self.processing_output_textedit.append(f"šŸŸ¢ Processing started at {start_time} šŸŸ¢") + self.process_start_time = datetime.now() self.processing_thread.start() + def finished_processing(self) -> None: + time_elapsed = formatted_time_elapsed(self.process_start_time) + self.processing_output_textedit.append(f"āœ… Processing completed in {time_elapsed} āœ…") + self.process_button.setText(self.START_PROCESSING_TEXT) + def save_config_to_file(self) -> None: self.save_config() config.save_config_to_file() @@ -350,6 +360,8 @@ def save_config(self) -> None: config.language_code = pycountry.languages.get(name=self.language_combobox.current_text()).alpha_3 def stop_processing(self) -> None: + time_elapsed = formatted_time_elapsed(self.process_start_time) + self.processing_output_textedit.append(f"šŸ›‘ Processing stopped after {time_elapsed} šŸ›‘") self.processing_thread.terminate() def update_processing_output(self, message: str) -> None: diff --git a/bd_to_avp/gui/processing.py b/bd_to_avp/gui/processing.py index ea773d2..ad2a047 100644 --- a/bd_to_avp/gui/processing.py +++ b/bd_to_avp/gui/processing.py @@ -19,6 +19,7 @@ class ProcessingSignals(QObject): class ProcessingThread(QThread): error_occurred = Signal(Exception) mkv_creation_error = Signal(MKVCreationError) + process_completed = Signal() def __init__(self, main_window: "MainWindow", parent: QWidget | None = None) -> None: super().__init__(parent) @@ -31,13 +32,13 @@ def run(self) -> None: try: process() + self.process_completed.emit() except MKVCreationError as error: self.mkv_creation_error.emit(error) except (RuntimeError, ValueError) as error: self.error_occurred.emit(error) finally: sys.stdout = sys.__stdout__ - self.signals.progress_updated.emit("Process Completed.") self.main_window.process_button.setText(self.main_window.START_PROCESSING_TEXT) def terminate(self) -> None: diff --git a/bd_to_avp/modules/util.py b/bd_to_avp/modules/util.py index 03965e7..7322366 100644 --- a/bd_to_avp/modules/util.py +++ b/bd_to_avp/modules/util.py @@ -5,11 +5,13 @@ import threading import time import tomllib +from datetime import datetime, timedelta from pathlib import Path from typing import Any, Callable, Iterable import ffmpeg +import humanize from bd_to_avp.modules.config import config @@ -215,3 +217,16 @@ def get_common_language_options() -> list[str]: "Korean", ] return common_languages + + +def format_timestamp(timestamp: datetime) -> str: + return timestamp.strftime("%I:%M:%S %p on %Y-%m-%d") + + +def format_timedelta(seconds_elapsed: int) -> str: + time_difference = timedelta(seconds=seconds_elapsed) + return humanize.naturaldelta(time_difference) + + +def formatted_time_elapsed(start_time: datetime) -> str: + return format_timedelta(int((datetime.now() - start_time).total_seconds())) diff --git a/pyproject.toml b/pyproject.toml index bbe44f1..92700bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ psutil = "^5.9.8" pyside6 = "^6.7.1" pygithub = "^2.3.0" pycountry = "^24.6.1" +humanize = "^4.9.0" [tool.poetry.group.dev.dependencies] black = "^24.2.0" @@ -61,6 +62,7 @@ requires = [ "psutil", "pygithub", "pycountry", + "humanize", ]