Populate properties panel with correct data

This commit is contained in:
heliguy
2024-07-06 15:49:16 -04:00
parent 74f0594478
commit 0d160cea01
4 changed files with 149 additions and 26 deletions

View File

@@ -8,7 +8,6 @@ icon_theme.add_search_path(f"{home}/.local/share/flatpak/exports/share/icons")
direction = Gtk.Image().get_direction()
class Flatpak:
cli_info = None
def open_data(self):
if not os.path.exists(self.data_path):
@@ -18,24 +17,52 @@ class Flatpak:
except GLib.GError as e:
return e
def get_data_size(self, callback=None):
size = [None]
def thread(*args):
sed = "sed 's/K/ KB/; s/M/ MB/; s/G/ GB/; s/T/ TB/; s/P/ PB/;'"
size[0] = subprocess.run(['sh', '-c', f"du -sh {self.data_path} | {sed}"], capture_output=True, text=True).stdout.split("\t")[0]
def on_done(*arg):
if callback:
callback(f"~ {size[0]}")
Gio.Task.new(None, None, on_done).run_in_thread(thread)
def trash_data(self, callback=None):
def thread(*args):
subprocess.run(['gio', 'trash', f"{self.data_path}"])
Gio.Task.new(None, None, lambda *_: callback()).run_in_thread(thread)
def get_cli_info(self):
if not self.cli_info:
cmd = "LC_ALL=C flatpak info "
installation = self.info["installation"]
cli_info = {}
cmd = "LC_ALL=C flatpak info "
installation = self.info["installation"]
if installation == "user":
cmd += "--user "
elif installation == "system":
cmd += "--system "
else:
cmd += f"--installation={installation} "
if installation == "user":
cmd += "--user "
elif installation == "system":
cmd += "--system "
else:
cmd += f"--installation={installation} "
cmd += self.info["ref"]
cmd += self.info["ref"]
output = subprocess.run(['flatpak-spawn', '--host', 'sh', '-c', cmd], text=True, capture_output=True)
print(output)
try:
output = subprocess.run(['flatpak-spawn', '--host', 'sh', '-c', cmd], text=True, capture_output=True).stdout
except Exception as e:
raise e
return self.cli_info
lines = output.strip().split("\n")
for i, word in enumerate(lines):
word = word.strip().split(": ", 1)
if len(word) < 2:
continue
word[0] = word[0].lower()
if "installed" in word[0]:
word[1] = word[1].replace("?", " ")
cli_info[word[0]] = word[1]
return cli_info
def __init__(self, columns):
self.is_runtime = "runtime" in columns[12]
@@ -52,6 +79,7 @@ class Flatpak:
"options": columns[12],
}
self.data_path = f"{home}/.var/app/{columns[2]}"
self.data_size = -1
installation = columns[7]
if len(i := installation.split(' ')) > 1:
self.info["installation"] = i[1].replace("(", "").replace(")", "")

View File

@@ -6,7 +6,8 @@ template $PropertiesPage : Adw.NavigationPage {
Adw.ToastOverlay toast_overlay {
Adw.ToolbarView {
[top]
Adw.HeaderBar {
Adw.HeaderBar header_bar {
show-title: false;
[end]
MenuButton more_menu {
icon-name: "view-more-symbolic";
@@ -34,7 +35,7 @@ template $PropertiesPage : Adw.NavigationPage {
;
}
}
ScrolledWindow {
ScrolledWindow scrolled_window {
Adw.Clamp {
Box {
margin-start: 12;
@@ -46,6 +47,7 @@ template $PropertiesPage : Adw.NavigationPage {
Image app_icon {
pixel-size: 100;
margin-top: 6;
margin-bottom: 18;
icon-name: "application-x-executable-symbolic";
styles["icon-dropshadow"]
@@ -68,7 +70,6 @@ template $PropertiesPage : Adw.NavigationPage {
wrap: true;
wrap-mode: word_char;
justify: center;
margin-bottom: 18;
margin-start: 6;
margin-end: 6;
}
@@ -76,6 +77,7 @@ template $PropertiesPage : Adw.NavigationPage {
Box {
spacing: 6;
homogeneous: true;
margin-top: 18;
margin-bottom: 12;
halign: center;
Button open_app_button {
@@ -95,8 +97,8 @@ template $PropertiesPage : Adw.NavigationPage {
Adw.PreferencesGroup actions {
margin-bottom: 12;
Adw.SwitchRow pin_row {
title: _("Remove When Unused");
subtitle: _("Pin this runtime so it's never auto removed");
title: _("Disable Automactic Removal");
subtitle: _("Pin this runtime to keep it installed");
}
Adw.ActionRow data_row {
title: _("User Data");
@@ -117,16 +119,27 @@ template $PropertiesPage : Adw.NavigationPage {
icon-name: "user-trash-symbolic";
tooltip-text: _("Trash User Data");
}
[suffix]
Spinner data_spinner {
spinning: true;
}
}
Adw.ExpanderRow version_row {
title: _("Version");
styles ["property"]
[suffix]
Label mask_label {
label: _("Updates disabled");
styles["warning"]
}
Adw.SwitchRow mask_row {
title: _("Disable Updates");
subtitle: _("Mask this package so it's never updated");
}
Adw.ActionRow downgrade_row {
title: _("Change Version");
subtitle: _("Upgrade or downgrade this package");
activatable: true;
Image {
icon-name: "right-large-symbolic";

View File

@@ -1,11 +1,14 @@
from gi.repository import Adw, Gtk#, GLib, Gio, Pango
from .error_toast import ErrorToast
import subprocess, os
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/properties_page/properties_page.ui")
class PropertiesPage(Adw.NavigationPage):
__gtype_name__ = 'PropertiesPage'
gtc = Gtk.Template.Child
toast_overlay = gtc()
header_bar = gtc()
scrolled_window = gtc()
app_icon = gtc()
name = gtc()
description = gtc()
@@ -16,6 +19,7 @@ class PropertiesPage(Adw.NavigationPage):
data_row = gtc()
open_data_button = gtc()
trash_data_button = gtc()
data_spinner = gtc()
version_row = gtc()
mask_row = gtc()
downgrade_row = gtc()
@@ -40,13 +44,14 @@ class PropertiesPage(Adw.NavigationPage):
package = None
def set_properties(self, package):
if package == self.package:
def set_properties(self, package, refresh=False):
if package == self.package and not refresh:
# Do not update the ui if the same app row is clicked
print("skip")
return
self.package = package
self.set_title(package.info["id"])
self.set_title(_("{} Properties").format(package.info["name"]))
self.name.set_label(package.info["name"])
pkg_description = package.info["description"]
self.description.set_visible(pkg_description != "")
@@ -57,17 +62,94 @@ class PropertiesPage(Adw.NavigationPage):
else:
self.app_icon.set_from_icon_name("application-x-executable-symbolic")
package.get_cli_info()
self.pin_row.set_visible(package.is_runtime)
self.open_app_button.set_visible(package.is_runtime)
self.open_app_button.set_visible(not package.is_runtime)
if not package.is_runtime:
has_path = os.path.exists(package.data_path)
self.trash_data_button.set_sensitive(has_path)
self.open_data_button.set_sensitive(has_path)
if has_path:
self.trash_data_button.set_visible(False)
self.open_data_button.set_visible(False)
self.data_spinner.set_visible(True)
self.data_row.set_subtitle(_("Loading User Data"))
def callback(size):
self.trash_data_button.set_visible(True)
self.open_data_button.set_visible(True)
self.data_spinner.set_visible(False)
self.data_row.set_subtitle(size)
self.package.get_data_size(lambda size: callback(size))
else:
self.data_row.set_subtitle(_("No User Data"))
cli_info = None
try:
cli_info = package.get_cli_info()
except Exception as e:
self.toast_overlay.add_toast(ErrorToast(_("Could not get properties"), str(e), self.main_window).toast)
return
for key, row in self.info_rows.items():
row.set_visible(False)
try:
subtitle = cli_info[key]
row.set_subtitle(subtitle)
row.set_visible(True)
except KeyError:
if key == "version":
row.set_visible(True)
row.set_subtitle(_("No version information found"))
continue
except Exception as e:
self.toast_overlay.add_toast(ErrorToast(_("Could not get properties"), str(e), self.main_window).toast)
continue
def open_data_handler(self, *args):
if error := self.package.open_data():
self.toast_overlay.add_toast(ErrorToast(_("Could not open data"), str(error), self.main_window).toast)
def trash_data_handler(self, *args):
def when_done(*args):
self.set_properties(self.package, refresh=True)
self.toast_overlay.add_toast(Adw.Toast.new("Trashed User Data"))
try:
self.package.trash_data(when_done)
except Exception as e:
self.toast_overlay.add_toast(ErrorToast(_("Could not trash data"), str(e), self.main_window).toast)
def __init__(self, main_window, **kwargs):
super().__init__(**kwargs)
# Extra Object Creation
self.main_window = main_window
self.info_rows = {
"version": self.version_row,
"installed": self.installed_size_row,
"id": self.id_row,
"ref": self.ref_row,
"arch": self.arch_row,
"branch": self.branch_row,
"license": self.license_row,
"runtime": self.runtime_row,
"sdk": self.sdk_row,
"origin": self.origin_row,
"collection": self.collection_row,
"installation": self.installation_row,
"commit": self.commit_row,
"parent": self.parent_row,
"subject": self.subject_row,
"date": self.date_row,
}
# Connections
self.open_data_button.connect("clicked", self.open_data_handler)
self.open_data_button.connect("clicked", self.open_data_handler)
self.scrolled_window.get_vadjustment().connect("value-changed", lambda adjustment: self.header_bar.set_show_title(not adjustment.get_value() == 0))
self.trash_data_button.connect("clicked", self.trash_data_handler)

View File

@@ -2,7 +2,7 @@ from gi.repository import Adw, Gtk, Gdk, GLib, Pango
clipboard = Gdk.Display.get_default().get_clipboard()
class ErrorToast:
def __init__(self, display_msg, error_msg, parent_window, format=True):
def __init__(self, display_msg, error_msg, parent_window):
def on_response(dialog, response_id):
if response_id == "copy":
@@ -10,7 +10,7 @@ class ErrorToast:
# Extra Object Creation
self.toast = Adw.Toast(title=display_msg, button_label=_("Details"))
popup = Adw.AlertDialog.new(display_msg, error_msg)
popup = Adw.AlertDialog.new(display_msg)
# Apply
print(display_msg)