Feature: Allow GUI to detect available update and install it (#587)

* rename verify_update and give return value

* change verify_update call

* GUI: add update feature
This commit is contained in:
shadeyg56 2023-10-27 04:38:42 -05:00 committed by GitHub
parent d3760eaf37
commit 34f3d23aa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 6 deletions

View File

@ -248,7 +248,9 @@ def main(config, daemon, debug, update, install, remove, live, log, monitor, sta
elif subprocess.run(["bash", "-c", "command -v pacman >/dev/null 2>&1"]).returncode == 0 and subprocess.run(["bash", "-c", "pacman -Q auto-cpufreq >/dev/null 2>&1"]).returncode == 0:
print("Arch-based distribution with AUR support detected. Please refresh auto-cpufreq using your AUR helper.")
else:
verify_update()
is_new_update = check_for_update()
if not is_new_update:
return
ans = input("Do you want to update auto-cpufreq to the latest release? [Y/n]: ").strip().lower()
if not os.path.exists(custom_dir):
os.makedirs(custom_dir)

View File

@ -11,10 +11,11 @@ from gi.repository import Gtk, GLib
from auto_cpufreq.gui.app import ToolWindow
def main():
GLib.set_prgname("auto-cpufreq")
win = ToolWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
GLib.set_prgname("auto-cpufreq")
win.handle_update()
Gtk.main()
if __name__ == "__main__":

View File

@ -165,7 +165,10 @@ def app_version():
except Exception as e:
print(repr(e))
pass
def verify_update():
def check_for_update():
# returns True if a new release is available from the GitHub repo
# Specify the repository and package name
# IT IS IMPORTANT TO THAT IF THE REPOSITORY STRUCTURE IS CHANGED, THE FOLLOWING FUNCTION NEEDS TO BE UPDATED ACCORDINGLY
# Fetch the latest release information from GitHub API
@ -192,10 +195,11 @@ def verify_update():
# Compare the latest version with the installed version and perform update if necessary
if latest_version == installed_version:
print("auto-cpufreq is up to date")
exit(0)
return False
else:
print(f"Updates are available,\nCurrent version: {installed_version}\nLatest version: {latest_version}")
print("Note that your previous custom settings might be erased with the following update")
return True
def new_update(custom_dir):
os.chdir(custom_dir)

View File

@ -6,11 +6,15 @@ from gi.repository import Gtk, GLib, Gdk, Gio, GdkPixbuf
import os
import sys
from contextlib import redirect_stdout
from io import StringIO
from subprocess import run, PIPE
import shutil
from threading import Thread
sys.path.append("../")
from auto_cpufreq.core import is_running
from auto_cpufreq.gui.objects import RadioButtonView, SystemStatsLabel, CPUFreqStatsLabel, CurrentGovernorBox, DropDownMenu, DaemonNotRunningView
from auto_cpufreq.core import is_running, check_for_update, remove_daemon, new_update
from auto_cpufreq.gui.objects import RadioButtonView, SystemStatsLabel, CPUFreqStatsLabel, CurrentGovernorBox, DropDownMenu, DaemonNotRunningView, UpdateDialog
if os.getenv("PKG_MARKER") == "SNAP":
ICON_FILE = "/snap/auto-cpufreq/current/icon.png"
@ -20,6 +24,8 @@ else:
CSS_FILE = "/usr/local/share/auto-cpufreq/scripts/style.css"
HBOX_PADDING = 20
PKEXEC_ERROR = "Error executing command as another user: Not authorized\n\nThis incident has been reported.\n"
class ToolWindow(Gtk.Window):
def __init__(self):
@ -72,6 +78,31 @@ class ToolWindow(Gtk.Window):
box.pack_start(button, False, False, 0)
self.add(box)
def handle_update(self):
new_stdout = StringIO()
with redirect_stdout(new_stdout):
is_new_update = check_for_update()
if not is_new_update:
return
captured_output = new_stdout.getvalue().splitlines()
dialog = UpdateDialog(self, captured_output[1], captured_output[2])
response = dialog.run()
dialog.destroy()
if response != Gtk.ResponseType.YES:
return
updater = run(["pkexec", "auto-cpufreq", "--update"], input="y\n", encoding="utf-8", stderr=PIPE)
if updater.stderr == PKEXEC_ERROR:
error = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, "Error updating")
error.format_secondary_text("Authorization Failed")
error.run()
error.destroy()
return
success = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Update successful")
success.format_secondary_text("The app will now close. Please reopen to apply changes")
success.run()
success.destroy()
exit(0)
def daemon_not_running(self):
self.box = DaemonNotRunningView(self)
self.add(self.box)

View File

@ -242,6 +242,23 @@ class AboutDialog(Gtk.Dialog):
self.box.pack_start(self.love, False, False, 0)
self.show_all()
class UpdateDialog(Gtk.Dialog):
def __init__(self, parent, current_version: str, latest_version: str):
super().__init__(title="Update Available", transient_for=parent)
self.box = self.get_content_area()
self.set_default_size(400, 100)
self.add_buttons("Update", Gtk.ResponseType.YES, "Cancel", Gtk.ResponseType.NO)
self.label = Gtk.Label(label="An update is available\n")
self.current_version = Gtk.Label(label=current_version + "\n")
self.latest_version = Gtk.Label(label=latest_version + "\n")
self.box.pack_start(self.label, True, False, 0)
self.box.pack_start(self.current_version, True, False, 0)
self.box.pack_start(self.latest_version, True, False, 0)
self.show_all()
class ConfirmDialog(Gtk.Dialog):
def __init__(self, parent, message: str):
super().__init__(title="Confirmation", transient_for=parent)