diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/extension.js b/cinnamon-dynamic-wallpaper@TobiZog/5.4/extension.js
index 0fd8ab6..43e6c51 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/extension.js
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/extension.js
@@ -96,7 +96,7 @@ CinnamonDynamicWallpaperExtension.prototype = {
_loop: function () {
if (looping) {
try {
- Util.spawnCommandLine("/usr/bin/env python3 " + DIRECTORY.path + "/loop.py")
+ Util.spawnCommandLine("/usr/bin/env python3 " + DIRECTORY.path + "/src/main.py loop")
} catch(e) {
this.showNotification("Error!",
"Cinnamon Dynamic Wallpaper got an error while running the loop script. Please create an issue on GitHub.")
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/res/preferences.glade b/cinnamon-dynamic-wallpaper@TobiZog/5.4/res/preferences.glade
index fefd337..6478fe2 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/res/preferences.glade
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/res/preferences.glade
@@ -1221,6 +1221,7 @@
False
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/settings-schema.json b/cinnamon-dynamic-wallpaper@TobiZog/5.4/settings-schema.json
index 94b2cf0..61fa3b5 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/settings-schema.json
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/settings-schema.json
@@ -71,6 +71,10 @@
"type": "generic",
"default": 15
},
+ "network_location_provider": {
+ "type": "generic",
+ "default": "geojs.io"
+ },
"latitude_auto": {
"type": "generic",
"default": 0
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/enums/NetworkLocationProvider.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/enums/NetworkLocationProvider.py
index 02d4486..e1de45c 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/enums/NetworkLocationProvider.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/enums/NetworkLocationProvider.py
@@ -1,5 +1,4 @@
-from enum import Enum
-
-class NetworkLocationProvider(Enum):
- GEOJS = "https://get.geojs.io/v1/ip/geo.json"
- IPAPI = "http://ip-api.com/json/?fields=61439"
\ No newline at end of file
+class NetworkLocationProvider(enumerate):
+ GEOJS = "geojs.io"
+ IPAPI = "ip-api.com"
+ IPWHOIS = "ipwho.is"
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/loop.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/loop.py
deleted file mode 100644
index 916e6e4..0000000
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/loop.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/python3
-
-from scripts.cinnamon_pref_handler import *
-from scripts.suntimes import *
-from datetime import datetime, time
-from enums.PeriodSourceEnum import *
-from scripts.location import *
-from gi.repository import Gio
-from PIL import Image
-
-
-class Loop():
- def __init__(self) -> None:
- self.prefs = Cinnamon_Pref_Handler()
-
- self.suntimes = Suntimes()
- self.location = Location()
- self.background_settings = Gio.Settings.new("org.cinnamon.desktop.background")
-
- # Position should estimate by network
- if self.prefs.period_source == PeriodSourceEnum.NETWORKLOCATION:
- 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
-
- # Position is given by user
- elif self.prefs.period_source == PeriodSourceEnum.CUSTOMLOCATION:
- self.suntimes.calc_suntimes(float(self.prefs.latitude_custom), float(self.prefs.longitude_custom))
- self.start_times = self.suntimes.day_periods
-
- # No position, concrete times
- else:
- def string_to_time_converter(raw_str: str) -> time:
- hour = raw_str[0:raw_str.find(":")]
- minute = raw_str[raw_str.find(":") + 1:]
-
- return time(hour=int(hour), minute=int(minute))
-
- self.start_times = [
- string_to_time_converter(self.prefs.period_custom_start_time[0]),
- string_to_time_converter(self.prefs.period_custom_start_time[1]),
- string_to_time_converter(self.prefs.period_custom_start_time[2]),
- string_to_time_converter(self.prefs.period_custom_start_time[3]),
- string_to_time_converter(self.prefs.period_custom_start_time[4]),
- string_to_time_converter(self.prefs.period_custom_start_time[5]),
- string_to_time_converter(self.prefs.period_custom_start_time[6]),
- string_to_time_converter(self.prefs.period_custom_start_time[7]),
- string_to_time_converter(self.prefs.period_custom_start_time[8]),
- string_to_time_converter(self.prefs.period_custom_start_time[9])
- ]
-
-
- def exchange_image(self):
- """ Replace the desktop image
- """
- # Get the time of day
- time_now = time(datetime.now().hour, datetime.now().minute)
-
- # Assign the last image as fallback
- self.current_image_uri = self.prefs.source_folder + self.prefs.period_images[9]
-
- for i in range(0, 9):
- # Replace the image URI, if it's not the last time period of the day
- if self.start_times[i] <= time_now and time_now < self.start_times[i + 1]:
- self.current_image_uri = self.prefs.source_folder + self.prefs.period_images[i]
- break
-
- # Set the background
- self.background_settings['picture-uri'] = "file://" + self.current_image_uri
-
- # Set background stretching
- self.background_settings['picture-options'] = self.prefs.picture_aspect
-
- self.set_background_gradient()
-
-
- def set_background_gradient(self):
- """ Setting a gradient background to hide images, which are not high enough
- """
- # Load the image
- try:
- im = Image.open(self.current_image_uri)
- pix = im.load()
-
- # Width and height of the current setted image
- width, height = im.size
-
- # Color of the top and bottom pixel in the middle of the image
- top_color = pix[width / 2,0]
- bottom_color = pix[width / 2, height - 1]
-
- # Create the gradient
- self.background_settings['color-shading-type'] = "vertical"
-
- if self.prefs.dynamic_background_color:
- self.background_settings['primary-color'] = f"#{top_color[0]:x}{top_color[1]:x}{top_color[2]:x}"
- self.background_settings['secondary-color'] = f"#{bottom_color[0]:x}{bottom_color[1]:x}{bottom_color[2]:x}"
- else:
- self.background_settings['primary-color'] = "#000000"
- self.background_settings['secondary-color'] = "#000000"
- except:
- self.background_settings['primary-color'] = "#000000"
- self.background_settings['secondary-color'] = "#000000"
-
-
-# Needed for JavaScript
-if __name__ == "__main__":
- l = Loop()
- l.exchange_image()
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/main.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/main.py
new file mode 100755
index 0000000..5b5175a
--- /dev/null
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/main.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python3
+
+import sys
+from ui.main_window import *
+from model.main_view_model import *
+
+if __name__ == "__main__":
+ if len(sys.argv) == 1:
+ # Load the configuration window
+ main = Main_Window()
+ main.show()
+
+ elif sys.argv[1] == "loop":
+ # Run the methods which updates the data
+ view_model = Main_View_Model()
+ view_model.refresh_image()
+ view_model.set_background_gradient()
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/model/main_view_model.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/model/main_view_model.py
index a8fd7f1..e962098 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/model/main_view_model.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/model/main_view_model.py
@@ -1,10 +1,12 @@
import os, json
-from pathlib import Path
+from PIL import Image
+from gi.repository import Gio
from service.display import *
from service.cinnamon_pref_handler import *
from service.suntimes import *
from service.time_bar_chart import *
+from service.location import *
from enums.PeriodSourceEnum import *
class Main_View_Model:
@@ -22,13 +24,16 @@ class Main_View_Model:
# Datasets
self.image_sets = ["aurora", "beach", "bitday", "cliffs", "earth", "gradient", "lakeside", "mountains", "sahara"]
self.picture_aspects = ["centered", "scaled", "stretched", "zoom", "spanned"]
- self.network_location_provider = ["geojs.io", "ip-api.com"]
+ self.network_location_provider = ["geojs.io", "ip-api.com", "ipwho.is"]
# Objects from scripts
self.screen_height = Display().get_screen_height()
self.cinnamon_prefs = Cinnamon_Pref_Handler()
self.time_bar_chart = Time_Bar_Chart()
self.suntimes = Suntimes()
+ self.location = Location()
+
+ self.background_settings = Gio.Settings.new("org.cinnamon.desktop.background")
# Breakpoint for smaller UI
self.breakpoint_ui = 1000
@@ -47,25 +52,15 @@ class Main_View_Model:
if self.cinnamon_prefs.period_source == PeriodSourceEnum.NETWORKLOCATION:
self.suntimes.calc_suntimes(float(self.cinnamon_prefs.latitude_auto), float(self.cinnamon_prefs.longitude_auto))
else:
- pass
- # todo self.suntimes.calc_suntimes(float(self.ui.etr_latitude.get_text()), float(self.ui.etr_longitude.get_text()))
+ self.suntimes.calc_suntimes(float(self.cinnamon_prefs.latitude_custom), float(self.cinnamon_prefs.longitude_custom))
# Get all time periods. Store the minutes to the list and print the values to the text views
for i in range(0, 10):
time_range_now = self.suntimes.day_periods[i]
-
- if i != 9:
- time_range_next = self.suntimes.day_periods[i + 1]
- else:
- time_range_next = time(hour=23, minute=59)
-
- # todo self.ui.etr_periods[i].set_text(
- # str(time_range_now.hour).rjust(2, '0') + ":" + str(time_range_now.minute).rjust(2, '0') + \
- # " - " + str(time_range_next.hour).rjust(2, '0') + ":" + str(time_range_next.minute).rjust(2, '0'))
-
time_periods_min.append(time_range_now.hour * 60 + time_range_now.minute)
+
# Create time bar
# Reduce size for small displays
if self.screen_height < self.breakpoint_ui:
@@ -78,4 +73,115 @@ class Main_View_Model:
self.time_bar_chart.create_bar_chart_with_polylines(self.TIMEBAR_URI_POLYLINES, bar_width, bar_height, time_periods_min)
self.time_bar_chart.create_bar_chart(self.TIMEBAR_URI, bar_width, bar_height, time_periods_min)
-
+
+ def refresh_location(self) -> bool:
+ """ Updating the location by IP, store the result to cinnamon_prefs
+
+ Returns:
+ bool: Successful or not
+ """
+ current_location = self.location.get_location(self.cinnamon_prefs.network_location_provider)
+
+ if current_location['success']:
+ self.cinnamon_prefs.latitude_auto = current_location['latitude']
+ self.cinnamon_prefs.longitude_auto = current_location['longitude']
+
+ return current_location['success']
+
+
+ def string_to_time_converter(raw_str: str) -> time:
+ """ Convert a time string like "12:34" to a time object
+
+ Args:
+ raw_str (str): Raw string
+
+ Returns:
+ time: Time object
+ """
+ hour = raw_str[0:raw_str.find(":")]
+ minute = raw_str[raw_str.find(":") + 1:]
+
+ return time(hour=int(hour), minute=int(minute))
+
+
+ def calulate_time_periods(self) -> list:
+ if self.cinnamon_prefs.period_source == PeriodSourceEnum.CUSTOMTIMEPERIODS:
+ # User uses custom time periods
+ return [
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[0]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[1]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[2]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[3]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[4]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[5]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[6]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[7]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[8]),
+ self.string_to_time_converter(self.cinnamon_prefs.period_custom_start_time[9])
+ ]
+ else:
+ # Time periods have to be estimate by coordinates
+ if self.cinnamon_prefs.period_source == PeriodSourceEnum.NETWORKLOCATION:
+ # Get coordinates from the network
+ self.refresh_location()
+ self.suntimes.calc_suntimes(self.cinnamon_prefs.latitude_auto, self.cinnamon_prefs.longitude_auto)
+
+ elif self.cinnamon_prefs.period_source == PeriodSourceEnum.CUSTOMLOCATION:
+ # Get coordinates from user input
+ self.suntimes.calc_suntimes(self.cinnamon_prefs.latitude_custom, self.cinnamon_prefs.longitude_custom)
+
+ # Return the time periods
+ return self.suntimes.day_periods
+
+
+ def refresh_image(self):
+ """ Replace the desktop image if needed
+ """
+ start_times = self.calulate_time_periods()
+
+ # Get the time of day
+ time_now = time(datetime.now().hour, datetime.now().minute)
+
+ # Assign the last image as fallback
+ self.current_image_uri = self.cinnamon_prefs.source_folder + self.cinnamon_prefs.period_images[9]
+
+ for i in range(0, 9):
+ # Replace the image URI, if it's not the last time period of the day
+ if start_times[i] <= time_now and time_now < start_times[i + 1]:
+ self.current_image_uri = self.cinnamon_prefs.source_folder + self.cinnamon_prefs.period_images[i]
+ break
+
+ # Set the background
+ self.background_settings['picture-uri'] = "file://" + self.current_image_uri
+
+ # Set background stretching
+ self.background_settings['picture-options'] = self.cinnamon_prefs.picture_aspect
+
+
+ def set_background_gradient(self):
+ """ Setting a gradient background to hide images, which are not high enough
+ """
+ # Load the image
+ try:
+ im = Image.open(self.current_image_uri)
+ pix = im.load()
+
+ # Width and height of the current setted image
+ width, height = im.size
+
+ # Color of the top and bottom pixel in the middle of the image
+ top_color = pix[width / 2,0]
+ bottom_color = pix[width / 2, height - 1]
+
+ # Create the gradient
+ self.background_settings['color-shading-type'] = "vertical"
+
+ if self.cinnamon_prefs.dynamic_background_color:
+ self.background_settings['primary-color'] = f"#{top_color[0]:x}{top_color[1]:x}{top_color[2]:x}"
+ self.background_settings['secondary-color'] = f"#{bottom_color[0]:x}{bottom_color[1]:x}{bottom_color[2]:x}"
+ else:
+ self.background_settings['primary-color'] = "#000000"
+ self.background_settings['secondary-color'] = "#000000"
+ except:
+ self.background_settings['primary-color'] = "#000000"
+ self.background_settings['secondary-color'] = "#000000"
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/preferences.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/preferences.py
deleted file mode 100755
index da0326d..0000000
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/preferences.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/python3
-
-############################################################
-# Imports #
-############################################################
-
-# Packages
-import gi, os, subprocess, time
-from datetime import timedelta
-
-# Local scripts
-from scripts import cinnamon_pref_handler, dialogs, display, images, location, suntimes, time_bar_chart, ui
-from loop import *
-from enums.ImageSourceEnum import ImageSourceEnum
-from enums.PeriodSourceEnum import PeriodSourceEnum
-from enums.NetworkLocationProvider import NetworkLocationProvider
-
-gi.require_version("Gtk", "3.0")
-from gi.repository import Gtk, GdkPixbuf
-
-
-
-
-
-
-class Preferences:
- """ Preference window class
- """
-
- ############################################################
- # Lifecycle #
- ############################################################
-
- def __init__(self) -> None:
- # UI helper object
- self.ui = ui.UI(self.builder)
-
- # Layout breakpoint for smaller displays
- self.smaller_ui_height = 1000
-
-
- def show(self):
- """ Display the window to the screen
- """
- self.ui.show_main_window(self.builder, self.smaller_ui_height, self.prefs)
-
- # Time diagram
- try:
- self.refresh_chart()
- except:
- self.dialogs.message_dialog("Error on creating time bar!")
-
-
-
-
-if __name__ == "__main__":
- Preferences().show()
\ No newline at end of file
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/cinnamon_pref_handler.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/cinnamon_pref_handler.py
index 37794dc..5162ec3 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/cinnamon_pref_handler.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/cinnamon_pref_handler.py
@@ -10,91 +10,123 @@ class Cinnamon_Pref_Handler:
self.load_preferences()
+
+ def extract_json(self, parameter: str) -> str:
+ """ Get a parameter from the json dictionary safely
+
+ Args:
+ parameter (str): Parameter to request
+
+ Returns:
+ str: Value of the parameter (or "" if not existing)
+ """
+ try:
+ return self.pref_data[parameter]['value']
+ except:
+ return ""
+
def load_preferences(self):
""" Load the JSON preferences to the Preference object
"""
with open(self.pref_location, "r") as pref_file:
- pref_data = json.load(pref_file)
+ self.pref_data = json.load(pref_file)
- self.picture_aspect = pref_data['picture_aspect']['value']
- self.dynamic_background_color = pref_data['dynamic_background_color']['value']
- self.image_source = pref_data['image_source']['value']
- self.selected_image_set = pref_data['selected_image_set']['value']
- self.source_folder = pref_data['source_folder']['value']
+ self.picture_aspect = self.extract_json('picture_aspect')
+ self.dynamic_background_color = self.extract_json('dynamic_background_color')
+ self.image_source = self.extract_json('image_source')
+ self.selected_image_set = self.extract_json('selected_image_set')
+ self.source_folder = self.extract_json('source_folder')
self.period_images = [
- pref_data['period_0_image']['value'],
- pref_data['period_1_image']['value'],
- pref_data['period_2_image']['value'],
- pref_data['period_3_image']['value'],
- pref_data['period_4_image']['value'],
- pref_data['period_5_image']['value'],
- pref_data['period_6_image']['value'],
- pref_data['period_7_image']['value'],
- pref_data['period_8_image']['value'],
- pref_data['period_9_image']['value']
+ self.extract_json('period_0_image'),
+ self.extract_json('period_1_image'),
+ self.extract_json('period_2_image'),
+ self.extract_json('period_3_image'),
+ self.extract_json('period_4_image'),
+ self.extract_json('period_5_image'),
+ self.extract_json('period_6_image'),
+ self.extract_json('period_7_image'),
+ self.extract_json('period_8_image'),
+ self.extract_json('period_9_image')
]
- self.period_source = pref_data['period_source']['value']
- self.location_refresh_intervals = pref_data['location_refresh_intervals']['value']
- self.latitude_auto = pref_data['latitude_auto']['value']
- self.longitude_auto = pref_data['longitude_auto']['value']
- self.latitude_custom = pref_data['latitude_custom']['value']
- self.longitude_custom = pref_data['longitude_custom']['value']
+ self.period_source =self.extract_json('period_source')
+ self.location_refresh_intervals =self.extract_json('location_refresh_intervals')
+ self.network_location_provider =self.extract_json('network_location_provider')
+ self.latitude_auto =self.extract_json('latitude_auto')
+ self.longitude_auto =self.extract_json('longitude_auto')
+ self.latitude_custom =self.extract_json('latitude_custom')
+ self.longitude_custom =self.extract_json('longitude_custom')
self.period_custom_start_time = [
- pref_data['period_0_custom_start_time']['value'],
- pref_data['period_1_custom_start_time']['value'],
- pref_data['period_2_custom_start_time']['value'],
- pref_data['period_3_custom_start_time']['value'],
- pref_data['period_4_custom_start_time']['value'],
- pref_data['period_5_custom_start_time']['value'],
- pref_data['period_6_custom_start_time']['value'],
- pref_data['period_7_custom_start_time']['value'],
- pref_data['period_8_custom_start_time']['value'],
- pref_data['period_9_custom_start_time']['value']
- ]
+ self.extract_json('period_0_custom_start_time'),
+ self.extract_json('period_1_custom_start_time'),
+ self.extract_json('period_2_custom_start_time'),
+ self.extract_json('period_3_custom_start_time'),
+ self.extract_json('period_4_custom_start_time'),
+ self.extract_json('period_5_custom_start_time'),
+ self.extract_json('period_6_custom_start_time'),
+ self.extract_json('period_7_custom_start_time'),
+ self.extract_json('period_8_custom_start_time'),
+ self.extract_json('period_9_custom_start_time')
+ ]
+
+
+ def value_to_json(self, parameter: str, value: str):
+ """ Storing safely a value to the dictionary
+
+ Args:
+ parameter (str): Parameter to write
+ value (str): Value to write
+ """
+ try:
+ self.pref_data[parameter]['value'] = value
+ except:
+ self.pref_data[parameter] = {
+ 'type': 'generic',
+ 'value': value
+ }
+ print(self.pref_data)
def store_preferences(self):
""" Store the values of the Preference object to the JSON file
"""
- with open(self.pref_location, "r") as pref_file:
- pref_data = json.load(pref_file)
+ self.value_to_json('picture_aspect', self.picture_aspect)
+ self.value_to_json('dynamic_background_color', self.dynamic_background_color)
+ self.value_to_json('image_source', self.image_source)
+ self.value_to_json('selected_image_set', self.selected_image_set)
+ self.value_to_json('source_folder', self.source_folder)
+ self.value_to_json('period_0_image', self.period_images[0])
+ self.value_to_json('period_1_image', self.period_images[1])
+ self.value_to_json('period_2_image', self.period_images[2])
+ self.value_to_json('period_3_image', self.period_images[3])
+ self.value_to_json('period_4_image', self.period_images[4])
+ self.value_to_json('period_5_image', self.period_images[5])
+ self.value_to_json('period_6_image', self.period_images[6])
+ self.value_to_json('period_7_image', self.period_images[7])
+ self.value_to_json('period_8_image', self.period_images[8])
+ self.value_to_json('period_9_image', self.period_images[9])
+ self.value_to_json('period_source', self.period_source)
+ self.value_to_json('location_refresh_intervals', self.location_refresh_intervals)
+ self.value_to_json('network_location_provider', self.network_location_provider)
+ self.value_to_json('latitude_auto', self.latitude_auto)
+ self.value_to_json('longitude_auto', self.longitude_auto)
+ self.value_to_json('latitude_custom', self.latitude_custom)
+ self.value_to_json('longitude_custom', self.longitude_custom)
+ self.value_to_json('period_0_custom_start_time', self.period_custom_start_time[0])
+ self.value_to_json('period_1_custom_start_time', self.period_custom_start_time[1])
+ self.value_to_json('period_2_custom_start_time', self.period_custom_start_time[2])
+ self.value_to_json('period_3_custom_start_time', self.period_custom_start_time[3])
+ self.value_to_json('period_4_custom_start_time', self.period_custom_start_time[4])
+ self.value_to_json('period_5_custom_start_time', self.period_custom_start_time[5])
+ self.value_to_json('period_6_custom_start_time', self.period_custom_start_time[6])
+ self.value_to_json('period_7_custom_start_time', self.period_custom_start_time[7])
+ self.value_to_json('period_8_custom_start_time', self.period_custom_start_time[8])
+ self.value_to_json('period_9_custom_start_time', self.period_custom_start_time[9])
- pref_data['picture_aspect']['value'] = self.picture_aspect
- pref_data['dynamic_background_color']['value'] = self.dynamic_background_color
- pref_data['image_source']['value'] = self.image_source
- pref_data['selected_image_set']['value'] = self.selected_image_set
- pref_data['source_folder']['value'] = self.source_folder
- pref_data['period_0_image']['value'] = self.period_images[0]
- pref_data['period_1_image']['value'] = self.period_images[1]
- pref_data['period_2_image']['value'] = self.period_images[2]
- pref_data['period_3_image']['value'] = self.period_images[3]
- pref_data['period_4_image']['value'] = self.period_images[4]
- pref_data['period_5_image']['value'] = self.period_images[5]
- pref_data['period_6_image']['value'] = self.period_images[6]
- pref_data['period_7_image']['value'] = self.period_images[7]
- pref_data['period_8_image']['value'] = self.period_images[8]
- pref_data['period_9_image']['value'] = self.period_images[9]
- pref_data['period_source']['value'] = self.period_source
- pref_data['location_refresh_intervals']['value'] = self.location_refresh_intervals
- pref_data['latitude_auto']['value'] = self.latitude_auto
- pref_data['longitude_auto']['value'] = self.longitude_auto
- pref_data['latitude_custom']['value'] = self.latitude_custom
- pref_data['longitude_custom']['value'] = self.longitude_custom
- pref_data['period_0_custom_start_time']['value'] = self.period_custom_start_time[0]
- pref_data['period_1_custom_start_time']['value'] = self.period_custom_start_time[1]
- pref_data['period_2_custom_start_time']['value'] = self.period_custom_start_time[2]
- pref_data['period_3_custom_start_time']['value'] = self.period_custom_start_time[3]
- pref_data['period_4_custom_start_time']['value'] = self.period_custom_start_time[4]
- pref_data['period_5_custom_start_time']['value'] = self.period_custom_start_time[5]
- pref_data['period_6_custom_start_time']['value'] = self.period_custom_start_time[6]
- pref_data['period_7_custom_start_time']['value'] = self.period_custom_start_time[7]
- pref_data['period_8_custom_start_time']['value'] = self.period_custom_start_time[8]
- pref_data['period_9_custom_start_time']['value'] = self.period_custom_start_time[9]
# Write to file
with open(self.pref_location, "w") as pref_file:
- json.dump(pref_data, pref_file, separators=(',', ':'), indent=4)
+ json.dump(self.pref_data, pref_file, separators=(',', ':'), indent=4)
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/location.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/location.py
index 0794971..40831a1 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/location.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/service/location.py
@@ -4,26 +4,36 @@ from enums.NetworkLocationProvider import NetworkLocationProvider
class Location():
""" Class to handle location requests
"""
- def __init__(self):
- pass
-
def get_location(self, provider: NetworkLocationProvider) -> dict:
""" Request the location via network
Returns:
dict: latitude and longitude
"""
- request = urllib.request.urlopen(provider.value)
-
- data = json.load(request)
-
if provider == NetworkLocationProvider.GEOJS:
- return {
- "latitude": data["latitude"],
- "longitude": data["longitude"]
- }
+ url = "http://get.geojs.io/v1/ip/geo.json"
elif provider == NetworkLocationProvider.IPAPI:
+ url = "http://ip-api.com/json/?fields=61439"
+ elif provider == NetworkLocationProvider.IPWHOIS:
+ url = "http://ipwho.is"
+
+ try:
+ request = urllib.request.urlopen(url)
+ data = json.load(request)
+
+ if provider == NetworkLocationProvider.GEOJS or provider == NetworkLocationProvider.IPWHOIS:
+ param_lat = "latitude"
+ param_lon = "longitude"
+ else:
+ param_lat = "lat"
+ param_lon = "lon"
+
return {
- "latitude": data["lat"],
- "longitude": data["lon"]
+ "latitude": float(data[param_lat]),
+ "longitude": float(data[param_lon]),
+ "success": True
+ }
+ except:
+ return {
+ "success": False
}
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/test.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/test.py
deleted file mode 100755
index dcbe5d1..0000000
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/test.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/python3
-
-import ui.main_window
-
-main = ui.main_window.Main_Window()
-main.show()
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/dialogs.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/dialogs.py
index 75c020b..c0a8cd8 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/dialogs.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/dialogs.py
@@ -43,7 +43,7 @@ class Dialogs(Gtk.Window):
return location
- def message_dialog(self, message: str):
+ def message_dialog(self, message: str, type: Gtk.MessageType = Gtk.MessageType.INFO):
""" Displaying a Gtk Message dialog to the user
Args:
@@ -52,7 +52,7 @@ class Dialogs(Gtk.Window):
dialog = Gtk.MessageDialog(
transient_for=self,
flags=0,
- message_type=Gtk.MessageType.INFO,
+ message_type=type,
buttons=Gtk.ButtonsType.OK,
text=message
)
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/main_window.py b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/main_window.py
index 42e1db9..16f3b13 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/main_window.py
+++ b/cinnamon-dynamic-wallpaper@TobiZog/5.4/src/ui/main_window.py
@@ -14,7 +14,6 @@ from datetime import timedelta
# Local scripts
from model.main_view_model import *
from service.images import *
-from service.location import *
from service.suntimes import *
from service.time_bar_chart import *
from ui.dialogs import *
@@ -46,7 +45,6 @@ class Main_Window:
# Objects from scripts
self.images = Images()
self.dialogs = Dialogs()
- self.location = Location()
self.suntimes = Suntimes()
self.time_bar_chart = Time_Bar_Chart()
@@ -160,6 +158,8 @@ class Main_Window:
def show(self):
+ """ Display the window to the screen
+ """
self.builder.get_object("window_main").show_all()
# Smaller UI handling
@@ -265,9 +265,12 @@ class Main_Window:
image_preview.set_from_pixbuf(pixbuf)
except:
- pass
+ self.dialogs.message_dialog("Error on load images. Please check the configuration!", Gtk.MessageType.ERROR)
+
def refresh_charts(self):
+ """ Refresh the charts and put them to the image views
+ """
self.view_model.refresh_charts()
# Load to the views
@@ -285,7 +288,21 @@ class Main_Window:
############################################################
## Image Configuration
-
+
+ def show_image_configuration_entries(self, button_id: int):
+ self.tb_image_set.set_active(button_id == 1)
+ self.tb_heic_file.set_active(button_id == 2)
+ self.tb_source_folder.set_active(button_id == 3)
+
+ self.lbr_image_set.set_visible(button_id == 1)
+ self.lbr_heic_file.set_visible(button_id == 2)
+ self.lbr_source_folder.set_visible(button_id == 3)
+
+ # Make the comboboxes invisible
+ for combobox in self.cb_periods:
+ combobox.set_visible(button_id != 1)
+
+
# +-----------+-----------+---------------+
# | Image Set | HEIC file | Source Folder |
# +-----------+-----------+---------------+
@@ -298,12 +315,7 @@ class Main_Window:
"""
if button.get_active():
self.view_model.cinnamon_prefs.image_source = ImageSourceEnum.IMAGESET
- self.tb_heic_file.set_active(False)
- self.tb_source_folder.set_active(False)
-
- self.lbr_image_set.set_visible(True)
- self.lbr_heic_file.set_visible(False)
- self.lbr_source_folder.set_visible(False)
+ self.show_image_configuration_entries(1)
self.set_active_combobox_item(self.cb_image_set, self.view_model.cinnamon_prefs.selected_image_set)
@@ -311,10 +323,6 @@ class Main_Window:
selected_image_name = self.view_model.cinnamon_prefs.period_images[i]
self.set_active_combobox_item(combobox, selected_image_name)
- # Make the comboboxes invisible
- for combobox in self.cb_periods:
- combobox.set_visible(False)
-
def on_toggle_button_heic_file_clicked(self, button: Gtk.ToggleButton):
""" Clicked on ToggleButton "Heic file"
@@ -324,16 +332,7 @@ class Main_Window:
"""
if button.get_active():
self.view_model.cinnamon_prefs.image_source = ImageSourceEnum.HEICFILE
- self.tb_image_set.set_active(False)
- self.tb_source_folder.set_active(False)
-
- self.lbr_image_set.set_visible(False)
- self.lbr_heic_file.set_visible(True)
- self.lbr_source_folder.set_visible(False)
-
- # Make the comboboxes visible
- for combobox in self.cb_periods:
- combobox.set_visible(True)
+ self.show_image_configuration_entries(2)
# Load images from source folder
files = self.images.get_images_from_folder(self.view_model.cinnamon_prefs.source_folder)
@@ -356,16 +355,7 @@ class Main_Window:
"""
if button.get_active():
self.view_model.cinnamon_prefs.image_source = ImageSourceEnum.SOURCEFOLDER
- self.tb_image_set.set_active(False)
- self.tb_heic_file.set_active(False)
-
- self.lbr_image_set.set_visible(False)
- self.lbr_heic_file.set_visible(False)
- self.lbr_source_folder.set_visible(True)
-
- # Make the comboboxes visible
- for combobox in self.cb_periods:
- combobox.set_visible(True)
+ self.show_image_configuration_entries(3)
# Load the source folder to the view
# This will update the comboboxes in the preview to contain the right items
@@ -414,8 +404,7 @@ class Main_Window:
# Image sets have the same names for the images:
# 9.jpg = Period 0
# 1.jpg = Period 1
- # 2.jpg = Period 2
- # and so on....
+ # 2.jpg = Period 2...
for i in range(0, 10):
self.cb_periods[i].set_active(i + 1)
@@ -446,7 +435,7 @@ class Main_Window:
image_names = self.images.get_images_from_folder(self.view_model.cinnamon_prefs.source_folder)
self.load_image_options_to_combo_boxes(image_names)
else:
- self.dialogs.message_dialog("Error during extraction")
+ self.dialogs.message_dialog("Error during extraction!", Gtk.MessageType.ERROR)
# +------------------------------------------------------------+
@@ -507,6 +496,25 @@ class Main_Window:
## Location & Times
+
+ def show_location_times_entries(self, button_id: int):
+ """ Show or hide parts of the Locations & Times menu
+
+ Args:
+ button_id (int): ID of the button, 1 = Network, 2 = Custom Location, 3 = Custom Time Periods
+ """
+ self.tb_network_location.set_active(button_id == 1)
+ self.tb_custom_location.set_active(button_id == 2)
+ self.tb_time_periods.set_active(button_id == 3)
+
+ # Show/Hide the right ListBoxRows
+ self.lbr_network_refresh_time.set_visible(button_id == 1)
+ self.lbr_network_provider.set_visible(button_id == 1)
+ self.lbr_current_location.set_visible(button_id == 1)
+ self.lbr_custom_location_longitude.set_visible(button_id == 2)
+ self.lbr_custom_location_latitude.set_visible(button_id == 2)
+ self.lbr_time_periods.set_visible(button_id == 3)
+
def on_toggle_button_network_location_clicked(self, button: Gtk.ToggleButton):
""" User clicks on the ToggleButton for the network location
@@ -516,26 +524,10 @@ class Main_Window:
"""
if button.get_active():
self.view_model.cinnamon_prefs.period_source = PeriodSourceEnum.NETWORKLOCATION
- self.tb_custom_location.set_active(False)
- self.tb_time_periods.set_active(False)
-
- self.lbr_network_refresh_time.set_visible(True)
- self.lbr_current_location.set_visible(True)
- self.lbr_custom_location_longitude.set_visible(False)
- self.lbr_custom_location_latitude.set_visible(False)
- self.lbr_time_periods.set_visible(False)
+ self.show_location_times_entries(1)
self.spb_network_refresh_time.set_value(self.view_model.cinnamon_prefs.location_refresh_intervals)
-
-
- # Display the location in the UI
- current_location = self.location.get_location(NetworkLocationProvider.GEOJS)
- self.lb_current_location.set_text("Latitude: " + current_location["latitude"] + \
- ", Longitude: " + current_location["longitude"])
-
- # Store the location to the preferences
- self.view_model.cinnamon_prefs.latitude_auto = float(current_location["latitude"])
- self.view_model.cinnamon_prefs.longitude_auto = float(current_location["longitude"])
+ self.set_active_combobox_item(self.cb_network_provider, self.view_model.cinnamon_prefs.network_location_provider)
self.refresh_charts()
@@ -543,14 +535,7 @@ class Main_Window:
def on_toggle_button_custom_location_clicked(self, button: Gtk.ToggleButton):
if button.get_active():
self.view_model.cinnamon_prefs.period_source = PeriodSourceEnum.CUSTOMLOCATION
- self.tb_network_location.set_active(False)
- self.tb_time_periods.set_active(False)
-
- self.lbr_network_refresh_time.set_visible(False)
- self.lbr_current_location.set_visible(False)
- self.lbr_custom_location_longitude.set_visible(True)
- self.lbr_custom_location_latitude.set_visible(True)
- self.lbr_time_periods.set_visible(False)
+ self.show_location_times_entries(2)
self.etr_latitude.set_text(str(self.view_model.cinnamon_prefs.latitude_custom))
self.etr_longitude.set_text(str(self.view_model.cinnamon_prefs.longitude_custom))
@@ -559,15 +544,7 @@ class Main_Window:
def on_toggle_button_time_periods_clicked(self, button: Gtk.ToggleButton):
if button.get_active():
self.view_model.cinnamon_prefs.period_source = PeriodSourceEnum.CUSTOMTIMEPERIODS
- self.tb_network_location.set_active(False)
- self.tb_custom_location.set_active(False)
-
- self.lbr_network_refresh_time.set_visible(False)
- self.lbr_current_location.set_visible(False)
- self.lbr_custom_location_longitude.set_visible(False)
- self.lbr_custom_location_latitude.set_visible(False)
- self.lbr_time_periods.set_visible(True)
-
+ self.show_location_times_entries(3)
for i in range(0, 9):
pref_value = self.view_model.cinnamon_prefs.period_custom_start_time[i + 1]
@@ -577,7 +554,6 @@ class Main_Window:
self.spb_periods_minute[i].set_value(time_parts[1])
-
def on_spb_period_value_changed(self, spin_button: Gtk.SpinButton):
""" Callback if one of the time spinners (minute or hour) will be clicked
@@ -616,6 +592,28 @@ class Main_Window:
self.view_model.cinnamon_prefs.location_refresh_intervals = spin_button.get_value()
+ def on_cb_network_provider_changed(self, combobox: Gtk.ComboBox):
+ """ User changed the provider to estimate the location
+
+ Args:
+ combobox (Gtk.ComboBox): The used ComboBox
+ """
+ tree_iter = combobox.get_active_iter()
+
+ if tree_iter is not None:
+ model = combobox.get_model()
+ self.view_model.cinnamon_prefs.network_location_provider = model[tree_iter][0]
+
+ success = self.view_model.refresh_location()
+
+ if success:
+ self.lb_current_location.set_text(\
+ "Latitude: " + str(self.view_model.cinnamon_prefs.latitude_auto) + ", Longitude: " + str(self.view_model.cinnamon_prefs.longitude_auto))
+ else:
+ self.dialogs.message_dialog("Error during fetching location. Are you connected to the network?", Gtk.MessageType.ERROR)
+ self.lb_current_location.set_text("Latitude: ?, Longitude: ?")
+
+
def on_etr_longitude_changed(self, entry: Gtk.Entry):
""" User changes the value of the longitude Entry
@@ -624,7 +622,7 @@ class Main_Window:
"""
try:
self.view_model.cinnamon_prefs.longitude_custom = float(entry.get_text())
- self.refresh_chart()
+ self.refresh_charts()
except:
pass
@@ -637,7 +635,7 @@ class Main_Window:
"""
try:
self.view_model.cinnamon_prefs.latitude_custom = float(entry.get_text())
- self.refresh_chart()
+ self.refresh_charts()
except:
pass
@@ -645,13 +643,25 @@ class Main_Window:
# Behaviour
def on_cb_picture_aspect_changed(self, combobox: Gtk.ComboBox):
+ """ User changes the value for the picture aspect ratio
+
+ Args:
+ combobox (Gtk.ComboBox): The used ComboBox
+ """
tree_iter = combobox.get_active_iter()
if tree_iter is not None:
model = combobox.get_model()
self.view_model.cinnamon_prefs.picture_aspect = model[tree_iter][0]
-
- def on_sw_dynamic_background_color_state_set(self, switch: Gtk.Switch, state):
+
+
+ def on_sw_dynamic_background_color_state_set(self, _: Gtk.Switch, state: bool):
+ """ User switches dynamic background on or off
+
+ Args:
+ _ (Gtk.Switch): Used Switch
+ state (bool): Current state
+ """
self.view_model.cinnamon_prefs.dynamic_background_color = state
diff --git a/cinnamon-dynamic-wallpaper@TobiZog/metadata.json b/cinnamon-dynamic-wallpaper@TobiZog/metadata.json
index cc6bfbe..2ead12b 100644
--- a/cinnamon-dynamic-wallpaper@TobiZog/metadata.json
+++ b/cinnamon-dynamic-wallpaper@TobiZog/metadata.json
@@ -1,5 +1,5 @@
{
- "external-configuration-app": "src/test.py",
+ "external-configuration-app": "src/main.py",
"uuid": "cinnamon-dynamic-wallpaper@TobiZog",
"name": "Cinnamon Dynamic Wallpaper",
"description": "Cinnamon extension for dynamic desktop backgrounds based on time and location",