From 17348f7acf786d0d1036a758f98e6b95f8cb3f03 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 17 Jan 2024 20:53:18 +0100 Subject: [PATCH] Documentation, cleanup --- .../5.4/loop.py | 2 +- .../5.4/preferences.py | 61 ++++++++----------- .../5.4/scripts/cinnamon_pref_handler.py | 3 + .../5.4/scripts/dialogs.py | 61 +++++++++++++++++++ .../5.4/scripts/file_chooser.py | 32 ---------- .../5.4/scripts/images.py | 49 ++++++++++++++- .../5.4/scripts/location.py | 9 ++- .../5.4/scripts/suntimes.py | 10 ++- .../5.4/scripts/time_bar_chart.py | 13 +++- 9 files changed, 165 insertions(+), 75 deletions(-) create mode 100644 cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/dialogs.py delete mode 100644 cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/file_chooser.py diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/loop.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/loop.py index a4a3039..916e6e4 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/loop.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/loop.py @@ -19,7 +19,7 @@ class Loop(): # Position should estimate by network if self.prefs.period_source == PeriodSourceEnum.NETWORKLOCATION: - current_location = self.location.run() + current_location = self.location.get_location() self.suntimes.calc_suntimes(float(current_location["latitude"]), float(current_location["longitude"])) self.start_times = self.suntimes.day_periods diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/preferences.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/preferences.py index 2bc5fb2..c169665 100755 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/preferences.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/preferences.py @@ -8,10 +8,10 @@ from scripts.cinnamon_pref_handler import * from scripts.suntimes import * from scripts.location import * from scripts.images import * +from scripts.dialogs import * from enums.ImageSourceEnum import ImageSourceEnum from enums.PeriodSourceEnum import PeriodSourceEnum from loop import * -from scripts.file_chooser import * gi.require_version("Gtk", "3.0") from gi.repository import Gtk, GdkPixbuf @@ -37,7 +37,7 @@ class Preferences: self.suntimes = Suntimes() self.images = Images() self.location = Location() - self.file_chooser = FileChooser() + self.dialogs = Dialogs() # Glade self.builder = Gtk.Builder() @@ -365,7 +365,6 @@ class Preferences: for i in range(0, 10): self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i]) else: - # todo: Message to user print("No image files!") @@ -397,7 +396,6 @@ class Preferences: for i in range(0, 10): self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i]) else: - # todo: Message to user print("No image files!") @@ -438,32 +436,29 @@ class Preferences: # +----------------------------------------------+ def on_fc_heic_file_file_set(self, fc_button: Gtk.FileChooser): + """ User has a heic file selected with the FileChooserDialog + + Args: + fc_button (Gtk.FileChooser): Parameter about the selected file + """ + # The the absolute path to the heic file file_path: str = fc_button.get_filename() - extract_folder: str = PREFERENCES_URI + "/images/extracted_images/" - - file_name: str = file_path[file_path.rfind("/") + 1:] - file_name = file_name[:file_name.rfind(".")] + + # Extract the heic file + result = self.images.extract_heic_file(file_path) + + # Load images only if the extraction was successfully + if result: + # Collect all extracted images and push them to the comboboxes + image_names = self.images.get_images_from_folder(self.prefs.source_folder) + self.load_image_options_to_combo_boxes(image_names) + else: + self.dialogs.message_dialog("Error during extraction") + # Update the preferences self.prefs.selected_image_set = "" - self.prefs.source_folder = extract_folder - - # Create the buffer folder if its not existing - try: - os.mkdir(extract_folder) - except: - pass - - # Cleanup the folder - for file in self.images.get_images_from_folder(extract_folder): - os.remove(extract_folder + file) - - # Extract the HEIC file - os.system("heif-convert '" + file_path + "' '" + extract_folder + file_name + ".jpg'") - - # Collect all extracted images and push them to the comboboxes - image_names = self.images.get_images_from_folder(self.prefs.source_folder) - self.load_image_options_to_combo_boxes(image_names) + self.prefs.source_folder = PREFERENCES_URI + "/images/extracted_images/" # +------------------------------------------------------------+ @@ -477,7 +472,7 @@ class Preferences: Args: button (Gtk.Button): The clicked button """ - folder = self.file_chooser.on_btn_source_folder_clicked() + folder = self.dialogs.source_folder_dialog() files = self.images.get_images_from_folder(folder) # Update the preferences @@ -495,14 +490,8 @@ class Preferences: self.cb_periods[i].set_active(0) #self.set_active_combobox_item(self.cb_periods[i], "") #self.prefs.period_images[i]) - - if len(files) != 0: - pass - - - else: - # todo: Message to user - print("No image files!") + if len(files) == 1: + self.dialogs.message_dialog("No image files found!") def on_cb_period_preview_changed(self, combobox: Gtk.ComboBox): @@ -543,7 +532,7 @@ class Preferences: # Display the location in the UI - current_location = self.location.run() + current_location = self.location.get_location() self.lb_current_location.set_text("Latitude: " + current_location["latitude"] + \ ", Longitude: " + current_location["longitude"]) diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/cinnamon_pref_handler.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/cinnamon_pref_handler.py index 825a608..37794dc 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/cinnamon_pref_handler.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/cinnamon_pref_handler.py @@ -1,6 +1,8 @@ import os, json class Cinnamon_Pref_Handler: + """ Class to work with the Cinnamon Extension preference format + """ def __init__(self) -> None: # Location of the Cinnamon preference file since Cinnamon 5.4 self.pref_location = os.path.expanduser("~") + \ @@ -54,6 +56,7 @@ class Cinnamon_Pref_Handler: pref_data['period_9_custom_start_time']['value'] ] + def store_preferences(self): """ Store the values of the Preference object to the JSON file """ diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/dialogs.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/dialogs.py new file mode 100644 index 0000000..75c020b --- /dev/null +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/dialogs.py @@ -0,0 +1,61 @@ +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +class Dialogs(Gtk.Window): + """ All used Gtk dialogs + + Args: + Gtk (Gtk.Window): Window of Gtk application + """ + def __init__(self) -> None: + super().__init__() + + + def source_folder_dialog(self) -> str: + """ Display a FileChooser dialog where the user choose a folder + + Returns: + str: Absolute path to the selected folder + """ + dialog = Gtk.FileChooserDialog( + title= "Please choose a folder with images", + parent=self, + action=Gtk.FileChooserAction.SELECT_FOLDER + ) + + dialog.add_buttons( + Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK + ) + + dialog.set_default_size(800, 400) + + response = dialog.run() + + if response == Gtk.ResponseType.OK: + location = dialog.get_filename() + elif response == Gtk.ResponseType.CANCEL: + location = "" + + dialog.destroy() + + return location + + + def message_dialog(self, message: str): + """ Displaying a Gtk Message dialog to the user + + Args: + message (str): Message which appear in the dialog + """ + dialog = Gtk.MessageDialog( + transient_for=self, + flags=0, + message_type=Gtk.MessageType.INFO, + buttons=Gtk.ButtonsType.OK, + text=message + ) + + dialog.run() + dialog.destroy() diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/file_chooser.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/file_chooser.py deleted file mode 100644 index 2a1baf1..0000000 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/file_chooser.py +++ /dev/null @@ -1,32 +0,0 @@ -import gi - -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk - -class FileChooser(Gtk.Window): - def __init__(self) -> None: - super().__init__() - - def on_btn_source_folder_clicked(self) -> str: - dialog = Gtk.FileChooserDialog( - title= "Please choose a folder with images", - parent=self, - action=Gtk.FileChooserAction.SELECT_FOLDER - ) - - dialog.add_buttons( - Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK - ) - - dialog.set_default_size(800, 400) - - response = dialog.run() - - if response == Gtk.ResponseType.OK: - location = dialog.get_filename() - elif response == Gtk.ResponseType.CANCEL: - location = "" - - dialog.destroy() - - return location diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/images.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/images.py index 9151ab2..a05dde0 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/images.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/images.py @@ -1,15 +1,60 @@ import os class Images: + """ Class for image operations + """ def __init__(self) -> None: pass + def get_images_from_folder(self, URI: str) -> list: + """ List all images in a folder + + Args: + URI (str): Absolute path of the folder + + Returns: + list: List of file names which are images + """ items = [] for file in os.listdir(URI): - if file.endswith("jpg") or file.endswith("jpeg") or file.endswith("png") or file.endswith("bmp"): + if file.endswith(("jpg", "jpeg", "png", "bmp", "svg")): items.append(file) items.sort() - return items \ No newline at end of file + return items + + + def extract_heic_file(self, file_uri: str) -> bool: + """ Extract a heic file to an internal folder + + Args: + file_uri (str): Absolute path to the heic file + + Returns: + bool: Extraction was successful + """ + try: + extract_folder = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)) + \ + "/images/extracted_images/" + + file_name: str = file_uri[file_uri.rfind("/") + 1:] + file_name = file_name[:file_name.rfind(".")] + + # Create the buffer folder if its not existing + try: + os.mkdir(extract_folder) + except: + pass + + # Cleanup the folder + for file in self.get_images_from_folder(extract_folder): + os.remove(extract_folder + file) + + # Extract the HEIC file + os.system("heif-convert '" + file_uri + "' '" + extract_folder + file_name + ".jpg'") + + return True + except: + return False diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/location.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/location.py index ea90f1c..bc8169f 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/location.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/location.py @@ -1,10 +1,17 @@ import urllib.request, json class Location(): + """ Class to handle location requests + """ def __init__(self): self.GEO_URL = "https://get.geojs.io/v1/ip/geo.json" - def run(self) -> dict: + def get_location(self) -> dict: + """ Request the location via network + + Returns: + dict: latitude and longitude + """ request = urllib.request.urlopen(self.GEO_URL) data = json.load(request) diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/suntimes.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/suntimes.py index 52f9954..02e8fde 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/suntimes.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/suntimes.py @@ -19,6 +19,12 @@ class Suntimes: def calc_suntimes(self, latitude: float, longitude: float) -> None: + """ Start the calculation process + + Args: + latitude (float): Current latitude + longitude (float): Current longitude + """ self.latitude = latitude self.longitude = longitude self.calc_sun_events() @@ -43,6 +49,8 @@ class Suntimes: def calc_sun_events(self): + """ Parent sun event calculater. Calls calc_sunrise_sunset_time() for every time period + """ civial_dawn_start = self.calc_sunrise_sunset_time(True, 96) sunrise_start = self.calc_sunrise_sunset_time(True) morning_start = self.calc_sunrise_sunset_time(True, 89.167) @@ -71,8 +79,6 @@ class Suntimes: ] - - def calc_sunrise_sunset_time(self, is_sunrise: bool, zenith=90.833) -> datetime: """ Calculate all values to estimate the day periods """ diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/time_bar_chart.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/time_bar_chart.py index 1bb355b..a33c88a 100644 --- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/time_bar_chart.py +++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/scripts/time_bar_chart.py @@ -1,6 +1,8 @@ import math class Time_Bar_Chart: + """ Class to handle the creation of the day time period bar + """ def __init__(self) -> None: self.image_code = [] @@ -21,9 +23,10 @@ class Time_Bar_Chart: def create_bar_chart_with_polylines(self, save_location: str, image_width: int, image_height: int, times: list): - """ Create a time bar chart + """ Create a time bar chart WITH polylines Args: + save_location (str): Absolute path to store image_width (int): Width of the image in pixel image_height (int): Height of the image in pixel times (list): List of start times of the periods in minutes since midnight @@ -45,6 +48,14 @@ class Time_Bar_Chart: def create_bar_chart(self, save_location: str, image_width: int, image_height: int, times: list): + """ Create a time bar chart WITHOUT polylines + + Args: + save_location (str): Absolute path to store + image_width (int): Width of the image in pixel + image_height (int): Height of the image in pixel + times (list): List of start times of the periods in minutes since midnight + """ self.create_bar(image_width, image_height, times) self.create_time_markers(image_width, image_height)