mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-15 00:34:42 +09:00
Sync current work
This commit is contained in:
106
src/host_info.py
106
src/host_info.py
@@ -1,6 +1,7 @@
|
||||
import subprocess, os, pathlib
|
||||
|
||||
from gi.repository import Gio, Gtk, GLib
|
||||
from gi.repository import Gio, Gtk, GLib, Adw
|
||||
# from .app_row import AppRow
|
||||
|
||||
home = f"{pathlib.Path.home()}"
|
||||
icon_theme = Gtk.IconTheme.new()
|
||||
@@ -28,9 +29,10 @@ class Flatpak:
|
||||
Gio.Task.new(None, None, on_done).run_in_thread(thread)
|
||||
|
||||
def trash_data(self, callback=None):
|
||||
def thread(*args):
|
||||
try:
|
||||
subprocess.run(['gio', 'trash', f"{self.data_path}"])
|
||||
Gio.Task.new(None, None, lambda *_: callback()).run_in_thread(thread)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def get_cli_info(self):
|
||||
cli_info = {}
|
||||
@@ -86,6 +88,8 @@ class Flatpak:
|
||||
else:
|
||||
self.info["installation"] = installation
|
||||
|
||||
self.is_masked = self.info["id"] in HostInfo.masks[self.info["installation"]]
|
||||
|
||||
try:
|
||||
self.icon_path = (
|
||||
icon_theme.lookup_icon(
|
||||
@@ -119,52 +123,27 @@ class HostInfo:
|
||||
icon_theme.add_search_path(f"{i}/exports/share/icons")
|
||||
|
||||
flatpaks = []
|
||||
remotes = []
|
||||
installations = []
|
||||
masks = {}
|
||||
pins = {}
|
||||
@classmethod
|
||||
def get_flatpaks(this, callback=None):
|
||||
# Callback is a function to run after the host flatpaks are found
|
||||
this.flatpaks.clear()
|
||||
|
||||
def thread(task, *args):
|
||||
output = subprocess.run(
|
||||
['flatpak-spawn', '--host',
|
||||
'flatpak', 'list', '--columns=all'],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
).stdout
|
||||
lines = output.strip().split("\n")
|
||||
for i in lines:
|
||||
this.flatpaks.append(Flatpak(i.split("\t")))
|
||||
this.flatpaks = sorted(this.flatpaks, key=lambda flatpak: flatpak.info["name"].lower())
|
||||
|
||||
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
||||
|
||||
remotes = []
|
||||
installations = []
|
||||
@classmethod
|
||||
def get_remotes(this, callback=None):
|
||||
# Callback is a function to run after the host remotes are found
|
||||
this.remotes.clear()
|
||||
this.installations.clear()
|
||||
this.masks.clear()
|
||||
this.pins.clear()
|
||||
|
||||
def thread(task, *args):
|
||||
|
||||
# Get all config files for any extra installations
|
||||
custom_install_config_path = "/run/host/etc/flatpak/installations.d"
|
||||
if os.path.exists(custom_install_config_path):
|
||||
for file in os.listdir(custom_install_config_path):
|
||||
with open(f"{custom_install_config_path}/{file}", "r") as f:
|
||||
for line in f:
|
||||
if line.startswith("[Installation"):
|
||||
# Get specifically the installation name itself
|
||||
this.installations.append(line.replace("[Installation \"", "").replace("\"]", "").strip())
|
||||
|
||||
# Remotes
|
||||
def remote_info(installation):
|
||||
cmd = ['flatpak-spawn', '--host',
|
||||
'flatpak', 'remotes']
|
||||
if installation == "user":
|
||||
cmd.append("--user")
|
||||
elif installation == "system":
|
||||
cmd.append("--system")
|
||||
if installation == "user" or installation == "system":
|
||||
cmd.append(f"--{installation}")
|
||||
else:
|
||||
cmd.append(f"--installation={installation}")
|
||||
output = subprocess.run(
|
||||
@@ -178,9 +157,62 @@ class HostInfo:
|
||||
if installation == "user" or installation == "system":
|
||||
this.installations.append(installation)
|
||||
|
||||
# Masks
|
||||
cmd = ['flatpak-spawn', '--host',
|
||||
'flatpak', 'mask',]
|
||||
if installation == "user" or installation == "system":
|
||||
cmd.append(f"--{installation}")
|
||||
else:
|
||||
cmd.append(f"--installation={installation}")
|
||||
output = subprocess.run(
|
||||
cmd, text=True,
|
||||
capture_output=True,
|
||||
).stdout
|
||||
lines = output.strip().replace(" ", "").split("\n")
|
||||
if lines[0] != '':
|
||||
this.masks[installation] = lines
|
||||
|
||||
# Pins
|
||||
cmd = ['flatpak-spawn', '--host',
|
||||
'flatpak', 'pin',]
|
||||
if installation == "user" or installation == "system":
|
||||
cmd.append(f"--{installation}")
|
||||
else:
|
||||
cmd.append(f"--installation={installation}")
|
||||
output = subprocess.run(
|
||||
cmd, text=True,
|
||||
capture_output=True,
|
||||
).stdout
|
||||
lines = output.strip().replace(" ", "").split("\n")
|
||||
if lines[0] != '':
|
||||
this.pins[installation] = lines
|
||||
|
||||
# Installations
|
||||
# Get all config files for any extra installations
|
||||
custom_install_config_path = "/run/host/etc/flatpak/installations.d"
|
||||
if os.path.exists(custom_install_config_path):
|
||||
for file in os.listdir(custom_install_config_path):
|
||||
with open(f"{custom_install_config_path}/{file}", "r") as f:
|
||||
for line in f:
|
||||
if line.startswith("[Installation"):
|
||||
# Get specifically the installation name itself
|
||||
this.installations.append(line.replace("[Installation \"", "").replace("\"]", "").strip())
|
||||
|
||||
for i in this.installations:
|
||||
remote_info(i)
|
||||
remote_info("user")
|
||||
remote_info("system")
|
||||
|
||||
# Packages
|
||||
output = subprocess.run(
|
||||
['flatpak-spawn', '--host',
|
||||
'flatpak', 'list', '--columns=all'],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
).stdout
|
||||
lines = output.strip().split("\n")
|
||||
for i in lines:
|
||||
this.flatpaks.append(Flatpak(i.split("\t")))
|
||||
this.flatpaks = sorted(this.flatpaks, key=lambda flatpak: flatpak.info["name"].lower())
|
||||
|
||||
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
||||
@@ -25,6 +25,7 @@ import time
|
||||
from gi.repository import Adw, Gdk, Gio, GLib, Gtk
|
||||
from .packages_page import PackagesPage
|
||||
from .const import Config
|
||||
from .error_toast import ErrorToast
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui")
|
||||
class WarehouseWindow(Adw.ApplicationWindow):
|
||||
@@ -75,6 +76,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
|
||||
}
|
||||
|
||||
# Apply
|
||||
ErrorToast.main_window = self
|
||||
self.settings.bind("window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("window-height", self, "default-height", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("is-maximized", self, "maximized", Gio.SettingsBindFlags.DEFAULT)
|
||||
@@ -92,4 +94,4 @@ class WarehouseWindow(Adw.ApplicationWindow):
|
||||
self.sidebar_button.connect("clicked", lambda *_: self.main_split.set_show_sidebar(False))
|
||||
|
||||
self.navigation_row_listbox.get_row_at_index(0).activate()
|
||||
self.main_split.set_show_sidebar(True)
|
||||
self.main_split.set_show_sidebar(True)
|
||||
|
||||
@@ -24,7 +24,12 @@ class PackagesPage(Adw.BreakpointBin):
|
||||
def generate_list(self, *args):
|
||||
self.packages_list_box.remove_all()
|
||||
for package in HostInfo.flatpaks:
|
||||
self.packages_list_box.append(AppRow(package))
|
||||
row = AppRow(package)
|
||||
app_id = package.info["id"]
|
||||
installation = package.info["installation"]
|
||||
if package.is_masked:
|
||||
row.add_css_class("warning")
|
||||
self.packages_list_box.append(row)
|
||||
first_row = self.packages_list_box.get_row_at_index(0)
|
||||
self.packages_list_box.select_row(first_row)
|
||||
self.properties_page.set_properties(first_row.package)
|
||||
@@ -50,6 +55,7 @@ class PackagesPage(Adw.BreakpointBin):
|
||||
|
||||
# Apply
|
||||
HostInfo.get_flatpaks(callback=self.generate_list)
|
||||
|
||||
self.packages_list_box.set_filter_func(self.filter_func)
|
||||
self.packages_split.set_content(self.properties_page)
|
||||
self.__class__.instance = self
|
||||
|
||||
@@ -17,17 +17,22 @@ template $PropertiesPage : Adw.NavigationPage {
|
||||
ListBox more_list {
|
||||
ListBoxRow details {
|
||||
Label {
|
||||
label: "Show Details in Store";
|
||||
label: _("Show Details in Store");
|
||||
}
|
||||
}
|
||||
ListBoxRow view_snapshots {
|
||||
ListBoxRow reinstall {
|
||||
Label {
|
||||
label: "View Snapshots";
|
||||
label: _("Reinstall");
|
||||
}
|
||||
}
|
||||
ListBoxRow copy_launch {
|
||||
Label {
|
||||
label: "Copy Launch Command";
|
||||
label: _("Copy Launch Command");
|
||||
}
|
||||
}
|
||||
ListBoxRow view_snapshots {
|
||||
Label {
|
||||
label: _("View Snapshots");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ class PropertiesPage(Adw.NavigationPage):
|
||||
trash_data_button = gtc()
|
||||
data_spinner = gtc()
|
||||
version_row = gtc()
|
||||
mask_label = gtc()
|
||||
mask_row = gtc()
|
||||
downgrade_row = gtc()
|
||||
installed_size_row = gtc()
|
||||
@@ -90,7 +91,7 @@ class PropertiesPage(Adw.NavigationPage):
|
||||
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)
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not get properties"), str(e)).toast)
|
||||
return
|
||||
|
||||
for key, row in self.info_rows.items():
|
||||
@@ -106,21 +107,25 @@ class PropertiesPage(Adw.NavigationPage):
|
||||
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)
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not get properties"), str(e)).toast)
|
||||
continue
|
||||
|
||||
self.mask_label.set_visible(package.is_masked)
|
||||
|
||||
def ask_confirmation(self, title, description):
|
||||
pass
|
||||
|
||||
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)
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not open data"), str(error)).toast)
|
||||
|
||||
def trash_data_handler(self, *args):
|
||||
def when_done(*args):
|
||||
try:
|
||||
self.package.trash_data()
|
||||
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)
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not trash data"), str(e)).toast)
|
||||
|
||||
def __init__(self, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from gi.repository import Adw, Gtk, Gdk, GLib, Pango
|
||||
from gi.repository import Adw, Gtk, Gdk, GLib
|
||||
clipboard = Gdk.Display.get_default().get_clipboard()
|
||||
|
||||
class ErrorToast:
|
||||
def __init__(self, display_msg, error_msg, parent_window):
|
||||
main_window = None
|
||||
def __init__(self, display_msg, error_msg):
|
||||
|
||||
def on_response(dialog, response_id):
|
||||
if response_id == "copy":
|
||||
@@ -24,6 +25,5 @@ class ErrorToast:
|
||||
popup.set_extra_child(lb)
|
||||
|
||||
# Connections
|
||||
self.toast.connect("button-clicked", lambda *_: popup.present(parent_window))
|
||||
self.toast.connect("button-clicked", lambda *_: popup.present(self.main_window))
|
||||
popup.connect("response", on_response)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user