diff --git a/ks_includes/config.py b/ks_includes/config.py index b3006911..83c8eaed 100644 --- a/ks_includes/config.py +++ b/ks_includes/config.py @@ -166,6 +166,7 @@ class KlipperScreenConfig: strs = ( 'default_printer', 'language', 'print_sort_dir', 'theme', 'screen_blanking_printing', 'font_size', 'print_estimate_method', 'screen_blanking', "screen_on_devices", "screen_off_devices", 'print_view', + 'version_info', ) numbers = ( 'job_complete_timeout', 'job_error_timeout', 'move_speed_xy', 'move_speed_z', @@ -320,6 +321,7 @@ class KlipperScreenConfig: {"print_view": {"section": "main", "type": None, "value": "thumbs"}}, {"language": {"section": "main", "name": _("Language"), "type": None, "value": "system_lang"}}, {"onboarding": {"section": "main", "type": None, "value": "False"}}, + {"version_info": {"section": "main","name": _("Stable"), "type": None, "value": "stable"}}, ] self.configurable_options.extend(panel_options) diff --git a/panels/factory_settings.py b/panels/factory_settings.py index 332d799f..8e8565a0 100644 --- a/panels/factory_settings.py +++ b/panels/factory_settings.py @@ -1,3 +1,4 @@ +import configparser import logging import os.path import pathlib @@ -5,6 +6,8 @@ import pathlib import gi gi.require_version("Gtk", "3.0") +from datetime import datetime + from gi.repository import GLib, Gtk from ks_includes.ModelConfig import ModelConfig @@ -15,6 +18,7 @@ class Panel(ScreenPanel): def __init__(self, screen, title): title = title or "factory settings" super().__init__(screen, title) + self.last_drop_time = datetime.now() self.factory_settings_list = [ { "Select Model": { @@ -32,16 +36,33 @@ class Panel(ScreenPanel): "callback": self.enable_guide, } }, + { + "version_info": { + "section": "main", + "name": _("Version Selection"), + "type": "dropdown", + "value": "stable", + "callback": self.version_selection, + "options": [ + {"name": _("Stable") + " " + _("(default)"), "value": "stable"}, + {"name": _("Beta"), "value": "beta"}, + {"name": _("Dev"), "value": "dev"}, + ], + } + }, ] self.settings = {} self.select_model = False self.labels["setting_menu"] = self._gtk.ScrolledWindow() self.labels["settings"] = Gtk.Grid() self.labels["setting_menu"].add(self.labels["settings"]) - + self.option_res = {} for option in self.factory_settings_list: name = list(option)[0] - self.add_option("settings", self.settings, name, option[name]) + self.option_res.update(self.add_option("settings", self.settings, name, option[name])) + + version_dropdown = self.option_res.get("version_info") + version_dropdown.connect("notify::popup-shown", self.on_popup_shown) self.content.add(self.labels["setting_menu"]) self.content.show_all() @@ -52,6 +73,23 @@ class Panel(ScreenPanel): return True return False + def on_popup_shown(self, combo_box, param): + if combo_box.get_property("popup-shown"): + logging.debug("Dropdown popup show") + self.last_drop_time = datetime.now() + else: + elapsed = (datetime.now() - self.last_drop_time).total_seconds() + if elapsed < 0.2: + logging.debug(f"Dropdown closed too fast ({elapsed}s)") + GLib.timeout_add(50, lambda: self.dropdown_keep_open(combo_box)) + return + logging.debug("Dropdown popup close") + + def dropdown_keep_open(self, combo_box): + if isinstance(combo_box, Gtk.ComboBox): + combo_box.popup() + return False + def show_select_model(self, widget, option): self.create_select_model() for child in self.content.get_children(): @@ -97,3 +135,42 @@ class Panel(ScreenPanel): self._config.set("main", "onboarding", "True") self._config.save_user_config_options() self._screen.show_popup_message("Successfully enabled the guide page", level=1) + + def version_selection(self, val): + config_updater = ConfigMoonrakerUpdateManager() + config_updater.enable_version_selection(val) + if val == "stable": + self._screen._send_action(None, "machine.update.rollback", {"name": "klipper"}) + self._screen._send_action(None, "machine.update.rollback", {"name": "KlipperScreen"}) + self._screen._send_action(None, "machine.update.rollback", {"name": "moonraker"}) + else: + self._screen._send_action(None, "machine.services.restart", {"service": "moonraker"}) + logging.info(f"version selection:{val}") + +class ConfigMoonrakerUpdateManager: + def __init__(self): + self.moonraker_config = configparser.ConfigParser() + self.moonraker_config_path = "/home/klipper/printer_data/config/moonraker.conf" + + def _set_update_manager_channel(self, section, channel="dev"): + if not self.moonraker_config.has_section(section): + self.moonraker_config.add_section(section) + self.moonraker_config.set(section, "channel", channel) + + def enable_version_selection(self, val): + update_managet_list = ["update_manager", "update_manager klipper", "update_manager KlipperScreen"] + try: + self.moonraker_config.read(self.moonraker_config_path) + + if "dev" == val or "beta" == val: + for section in update_managet_list: + self._set_update_manager_channel(section, val) + else: + for section in update_managet_list: + self.moonraker_config.remove_section(section) + + with open(self.moonraker_config_path, "w") as configfile: + self.moonraker_config.write(configfile) + except Exception as e: + msg = f"Error reading or writing config: \n{e}" + logging.exception(msg)