Documentation, cleanup

This commit is contained in:
2024-01-17 20:53:18 +01:00
parent e1b464e36c
commit 17348f7acf
9 changed files with 165 additions and 75 deletions

View File

@@ -19,7 +19,7 @@ class Loop():
# Position should estimate by network # Position should estimate by network
if self.prefs.period_source == PeriodSourceEnum.NETWORKLOCATION: 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.suntimes.calc_suntimes(float(current_location["latitude"]), float(current_location["longitude"]))
self.start_times = self.suntimes.day_periods self.start_times = self.suntimes.day_periods

View File

@@ -8,10 +8,10 @@ from scripts.cinnamon_pref_handler import *
from scripts.suntimes import * from scripts.suntimes import *
from scripts.location import * from scripts.location import *
from scripts.images import * from scripts.images import *
from scripts.dialogs import *
from enums.ImageSourceEnum import ImageSourceEnum from enums.ImageSourceEnum import ImageSourceEnum
from enums.PeriodSourceEnum import PeriodSourceEnum from enums.PeriodSourceEnum import PeriodSourceEnum
from loop import * from loop import *
from scripts.file_chooser import *
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf from gi.repository import Gtk, GdkPixbuf
@@ -37,7 +37,7 @@ class Preferences:
self.suntimes = Suntimes() self.suntimes = Suntimes()
self.images = Images() self.images = Images()
self.location = Location() self.location = Location()
self.file_chooser = FileChooser() self.dialogs = Dialogs()
# Glade # Glade
self.builder = Gtk.Builder() self.builder = Gtk.Builder()
@@ -365,7 +365,6 @@ class Preferences:
for i in range(0, 10): for i in range(0, 10):
self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i]) self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i])
else: else:
# todo: Message to user
print("No image files!") print("No image files!")
@@ -397,7 +396,6 @@ class Preferences:
for i in range(0, 10): for i in range(0, 10):
self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i]) self.set_active_combobox_item(self.cb_periods[i], self.prefs.period_images[i])
else: else:
# todo: Message to user
print("No image files!") print("No image files!")
@@ -438,32 +436,29 @@ class Preferences:
# +----------------------------------------------+ # +----------------------------------------------+
def on_fc_heic_file_file_set(self, fc_button: Gtk.FileChooser): def on_fc_heic_file_file_set(self, fc_button: Gtk.FileChooser):
file_path: str = fc_button.get_filename() """ User has a heic file selected with the FileChooserDialog
extract_folder: str = PREFERENCES_URI + "/images/extracted_images/"
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 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")
file_name: str = file_path[file_path.rfind("/") + 1:]
file_name = file_name[:file_name.rfind(".")]
# Update the preferences # Update the preferences
self.prefs.selected_image_set = "" self.prefs.selected_image_set = ""
self.prefs.source_folder = extract_folder self.prefs.source_folder = PREFERENCES_URI + "/images/extracted_images/"
# 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)
# +------------------------------------------------------------+ # +------------------------------------------------------------+
@@ -477,7 +472,7 @@ class Preferences:
Args: Args:
button (Gtk.Button): The clicked button 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) files = self.images.get_images_from_folder(folder)
# Update the preferences # Update the preferences
@@ -495,14 +490,8 @@ class Preferences:
self.cb_periods[i].set_active(0) self.cb_periods[i].set_active(0)
#self.set_active_combobox_item(self.cb_periods[i], "") #self.prefs.period_images[i]) #self.set_active_combobox_item(self.cb_periods[i], "") #self.prefs.period_images[i])
if len(files) == 1:
if len(files) != 0: self.dialogs.message_dialog("No image files found!")
pass
else:
# todo: Message to user
print("No image files!")
def on_cb_period_preview_changed(self, combobox: Gtk.ComboBox): def on_cb_period_preview_changed(self, combobox: Gtk.ComboBox):
@@ -543,7 +532,7 @@ class Preferences:
# Display the location in the UI # 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"] + \ self.lb_current_location.set_text("Latitude: " + current_location["latitude"] + \
", Longitude: " + current_location["longitude"]) ", Longitude: " + current_location["longitude"])

View File

@@ -1,6 +1,8 @@
import os, json import os, json
class Cinnamon_Pref_Handler: class Cinnamon_Pref_Handler:
""" Class to work with the Cinnamon Extension preference format
"""
def __init__(self) -> None: def __init__(self) -> None:
# Location of the Cinnamon preference file since Cinnamon 5.4 # Location of the Cinnamon preference file since Cinnamon 5.4
self.pref_location = os.path.expanduser("~") + \ self.pref_location = os.path.expanduser("~") + \
@@ -54,6 +56,7 @@ class Cinnamon_Pref_Handler:
pref_data['period_9_custom_start_time']['value'] pref_data['period_9_custom_start_time']['value']
] ]
def store_preferences(self): def store_preferences(self):
""" Store the values of the Preference object to the JSON file """ Store the values of the Preference object to the JSON file
""" """

View File

@@ -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()

View File

@@ -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

View File

@@ -1,15 +1,60 @@
import os import os
class Images: class Images:
""" Class for image operations
"""
def __init__(self) -> None: def __init__(self) -> None:
pass pass
def get_images_from_folder(self, URI: str) -> list: 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 = [] items = []
for file in os.listdir(URI): 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.append(file)
items.sort() items.sort()
return items 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

View File

@@ -1,10 +1,17 @@
import urllib.request, json import urllib.request, json
class Location(): class Location():
""" Class to handle location requests
"""
def __init__(self): def __init__(self):
self.GEO_URL = "https://get.geojs.io/v1/ip/geo.json" 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) request = urllib.request.urlopen(self.GEO_URL)
data = json.load(request) data = json.load(request)

View File

@@ -19,6 +19,12 @@ class Suntimes:
def calc_suntimes(self, latitude: float, longitude: float) -> None: 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.latitude = latitude
self.longitude = longitude self.longitude = longitude
self.calc_sun_events() self.calc_sun_events()
@@ -43,6 +49,8 @@ class Suntimes:
def calc_sun_events(self): 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) civial_dawn_start = self.calc_sunrise_sunset_time(True, 96)
sunrise_start = self.calc_sunrise_sunset_time(True) sunrise_start = self.calc_sunrise_sunset_time(True)
morning_start = self.calc_sunrise_sunset_time(True, 89.167) 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: def calc_sunrise_sunset_time(self, is_sunrise: bool, zenith=90.833) -> datetime:
""" Calculate all values to estimate the day periods """ Calculate all values to estimate the day periods
""" """

View File

@@ -1,6 +1,8 @@
import math import math
class Time_Bar_Chart: class Time_Bar_Chart:
""" Class to handle the creation of the day time period bar
"""
def __init__(self) -> None: def __init__(self) -> None:
self.image_code = [] 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): 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: Args:
save_location (str): Absolute path to store
image_width (int): Width of the image in pixel image_width (int): Width of the image in pixel
image_height (int): Height 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 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): 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_bar(image_width, image_height, times)
self.create_time_markers(image_width, image_height) self.create_time_markers(image_width, image_height)