mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-14 00:04:08 +09:00
Format Python files with Ruff
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
from gi.repository import Adw, Gtk,GLib, Gio
|
from gi.repository import Adw, Gtk, GLib, Gio
|
||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
from .loading_status import LoadingStatus
|
from .loading_status import LoadingStatus
|
||||||
from .change_version_worker import ChangeVersionWorker
|
from .change_version_worker import ChangeVersionWorker
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/change_version_page/change_version_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/change_version_page/change_version_page.ui")
|
||||||
class ChangeVersionPage(Adw.NavigationPage):
|
class ChangeVersionPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = 'ChangeVersionPage'
|
__gtype_name__ = "ChangeVersionPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
toast_overlay = gtc()
|
toast_overlay = gtc()
|
||||||
scrolled_window = gtc()
|
scrolled_window = gtc()
|
||||||
@@ -23,7 +24,7 @@ class ChangeVersionPage(Adw.NavigationPage):
|
|||||||
failure = None
|
failure = None
|
||||||
|
|
||||||
def get_commits(self, *args):
|
def get_commits(self, *args):
|
||||||
cmd = ['flatpak-spawn', '--host', 'sh', '-c']
|
cmd = ["flatpak-spawn", "--host", "sh", "-c"]
|
||||||
script = f"LC_ALL=C flatpak remote-info --log {self.package.info['origin']} {self.package.info['ref']} "
|
script = f"LC_ALL=C flatpak remote-info --log {self.package.info['origin']} {self.package.info['ref']} "
|
||||||
installation = self.package.info["installation"]
|
installation = self.package.info["installation"]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
@@ -35,10 +36,10 @@ class ChangeVersionPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
commits = []
|
commits = []
|
||||||
changes = []
|
changes = []
|
||||||
dates = []
|
dates = []
|
||||||
try:
|
try:
|
||||||
output = subprocess.run(cmd, check=True, capture_output=True, text=True).stdout
|
output = subprocess.run(cmd, check=True, capture_output=True, text=True).stdout
|
||||||
lines = output.strip().split('\n')
|
lines = output.strip().split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.strip().split(": ", 1)
|
line = line.strip().split(": ", 1)
|
||||||
if len(line) < 2:
|
if len(line) < 2:
|
||||||
@@ -62,7 +63,9 @@ class ChangeVersionPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
def idle(*args):
|
def idle(*args):
|
||||||
for index, commit in enumerate(commits):
|
for index, commit in enumerate(commits):
|
||||||
row = Adw.ActionRow(title=GLib.markup_escape_text(changes[index]), subtitle=f"{GLib.markup_escape_text(commit)}\n{GLib.markup_escape_text(dates[index])}")
|
row = Adw.ActionRow(
|
||||||
|
title=GLib.markup_escape_text(changes[index]), subtitle=f"{GLib.markup_escape_text(commit)}\n{GLib.markup_escape_text(dates[index])}"
|
||||||
|
)
|
||||||
if commit == self.package.cli_info.get("commit", None):
|
if commit == self.package.cli_info.get("commit", None):
|
||||||
row.set_sensitive(False)
|
row.set_sensitive(False)
|
||||||
row.add_prefix(Gtk.Image(icon_name="check-plain-symbolic", margin_start=5, margin_end=5))
|
row.add_prefix(Gtk.Image(icon_name="check-plain-symbolic", margin_start=5, margin_end=5))
|
||||||
@@ -90,7 +93,7 @@ class ChangeVersionPage(Adw.NavigationPage):
|
|||||||
def callback(self, did_error):
|
def callback(self, did_error):
|
||||||
HostInfo.main_window.refresh_handler()
|
HostInfo.main_window.refresh_handler()
|
||||||
if not did_error:
|
if not did_error:
|
||||||
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Changed {}'s Version").format(self.package.info['name'])))
|
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Changed {}'s Version").format(self.package.info["name"])))
|
||||||
|
|
||||||
def error_callback(self, user_facing_label, error_message):
|
def error_callback(self, user_facing_label, error_message):
|
||||||
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(user_facing_label, error_message).toast)
|
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(user_facing_label, error_message).toast)
|
||||||
@@ -98,7 +101,8 @@ class ChangeVersionPage(Adw.NavigationPage):
|
|||||||
def on_apply(self, *args):
|
def on_apply(self, *args):
|
||||||
if ChangeVersionWorker.change_version(
|
if ChangeVersionWorker.change_version(
|
||||||
self.mask_row.get_active(),
|
self.mask_row.get_active(),
|
||||||
self.package, self.selected_commit,
|
self.package,
|
||||||
|
self.selected_commit,
|
||||||
self.packages_page.changing_version,
|
self.packages_page.changing_version,
|
||||||
self.callback,
|
self.callback,
|
||||||
self.error_callback,
|
self.error_callback,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from gi.repository import GLib, Gio
|
|||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
import subprocess, re
|
import subprocess, re
|
||||||
|
|
||||||
|
|
||||||
class ChangeVersionWorker:
|
class ChangeVersionWorker:
|
||||||
process = None
|
process = None
|
||||||
callback = None
|
callback = None
|
||||||
@@ -23,9 +24,9 @@ class ChangeVersionWorker:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def change_version_thread(this, should_mask, package, commit):
|
def change_version_thread(this, should_mask, package, commit):
|
||||||
try:
|
try:
|
||||||
cmd = ['flatpak-spawn', '--host', 'pkexec', 'sh', '-c']
|
cmd = ["flatpak-spawn", "--host", "pkexec", "sh", "-c"]
|
||||||
|
|
||||||
installation = package.info['installation']
|
installation = package.info["installation"]
|
||||||
real_installation = ""
|
real_installation = ""
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
real_installation = f"--{installation}"
|
real_installation = f"--{installation}"
|
||||||
@@ -44,9 +45,9 @@ class ChangeVersionWorker:
|
|||||||
suffix += mask_cmd
|
suffix += mask_cmd
|
||||||
|
|
||||||
cmd.append(suffix)
|
cmd.append(suffix)
|
||||||
this.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
this.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||||
percent_pattern = r'\d{1,3}%'
|
percent_pattern = r"\d{1,3}%"
|
||||||
amount_pattern = r'(\d+)/(\d+)'
|
amount_pattern = r"(\d+)/(\d+)"
|
||||||
for line in this.process.stdout:
|
for line in this.process.stdout:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
percent_match = re.search(percent_pattern, line)
|
percent_match = re.search(percent_pattern, line)
|
||||||
@@ -54,7 +55,7 @@ class ChangeVersionWorker:
|
|||||||
ratio = int(percent_match.group()[0:-1]) / 100.0
|
ratio = int(percent_match.group()[0:-1]) / 100.0
|
||||||
amount_match = re.search(amount_pattern, line)
|
amount_match = re.search(amount_pattern, line)
|
||||||
if amount_match:
|
if amount_match:
|
||||||
amount = amount_match.group().split('/')
|
amount = amount_match.group().split("/")
|
||||||
complete = int(amount[0]) - 1
|
complete = int(amount[0]) - 1
|
||||||
total = int(amount[1])
|
total = int(amount[1])
|
||||||
this.update_status(ratio, complete, total)
|
this.update_status(ratio, complete, total)
|
||||||
@@ -65,7 +66,7 @@ class ChangeVersionWorker:
|
|||||||
if error := this.process.communicate()[1].strip():
|
if error := this.process.communicate()[1].strip():
|
||||||
this.on_error(_("Error occurred while changing version"), error)
|
this.on_error(_("Error occurred while changing version"), error)
|
||||||
|
|
||||||
except subprocess.TimeoutExpired as te:
|
except subprocess.TimeoutExpired:
|
||||||
this.process.terminate()
|
this.process.terminate()
|
||||||
this.on_error(_("Error occurred while changing version"), _("Failed to exit cleanly"))
|
this.on_error(_("Error occurred while changing version"), _("Failed to exit cleanly"))
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gi.repository import Adw, Gtk, GLib
|
from gi.repository import Adw, Gtk, GLib
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/app_row.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/app_row.ui")
|
||||||
class AppRow(Adw.ActionRow):
|
class AppRow(Adw.ActionRow):
|
||||||
__gtype_name__ = 'AppRow'
|
__gtype_name__ = "AppRow"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
image = gtc()
|
image = gtc()
|
||||||
eol_package_package_status_icon = gtc()
|
eol_package_package_status_icon = gtc()
|
||||||
@@ -35,7 +36,7 @@ class AppRow(Adw.ActionRow):
|
|||||||
GLib.idle_add(lambda *_: self.idle_stuff())
|
GLib.idle_add(lambda *_: self.idle_stuff())
|
||||||
self.add_controller(self.rclick_gesture)
|
self.add_controller(self.rclick_gesture)
|
||||||
self.add_controller(self.long_press_gesture)
|
self.add_controller(self.long_press_gesture)
|
||||||
if package.info['id'] == "io.github.flattool.Warehouse":
|
if package.info["id"] == "io.github.flattool.Warehouse":
|
||||||
self.check_button.set_active = lambda *_: None
|
self.check_button.set_active = lambda *_: None
|
||||||
self.check_button.set_sensitive(False)
|
self.check_button.set_sensitive(False)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from gi.repository import Adw, Gtk
|
|||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/attempt_install_dialog.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/attempt_install_dialog.ui")
|
||||||
class AttemptInstallDialog(Adw.AlertDialog):
|
class AttemptInstallDialog(Adw.AlertDialog):
|
||||||
__gtype_name__ = "AttemptInstallDialog"
|
__gtype_name__ = "AttemptInstallDialog"
|
||||||
@@ -46,12 +47,16 @@ class AttemptInstallDialog(Adw.AlertDialog):
|
|||||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||||
HostInfo.main_window.activate_row(HostInfo.main_window.install_row)
|
HostInfo.main_window.activate_row(HostInfo.main_window.install_row)
|
||||||
self.callback(True)
|
self.callback(True)
|
||||||
install_page.install_packages([{
|
install_page.install_packages(
|
||||||
"remote": row.remote_name,
|
[
|
||||||
"installation": row.remote_installation,
|
{
|
||||||
"package_names": self.package_names,
|
"remote": row.remote_name,
|
||||||
"extra_flags": [],
|
"installation": row.remote_installation,
|
||||||
}])
|
"package_names": self.package_names,
|
||||||
|
"extra_flags": [],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
elif not self.callback is None:
|
elif not self.callback is None:
|
||||||
self.callback(False)
|
self.callback(False)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
from gi.repository import Adw, Gtk, Gdk, GLib
|
from gi.repository import Adw, Gtk, Gdk, GLib
|
||||||
|
|
||||||
|
|
||||||
class ErrorToast:
|
class ErrorToast:
|
||||||
main_window = None
|
main_window = None
|
||||||
|
|
||||||
def __init__(self, display_msg, error_msg):
|
def __init__(self, display_msg, error_msg):
|
||||||
def on_response(dialog, response_id):
|
def on_response(dialog, response_id):
|
||||||
if response_id == "copy":
|
if response_id == "copy":
|
||||||
@@ -17,7 +19,7 @@ class ErrorToast:
|
|||||||
print(error_msg)
|
print(error_msg)
|
||||||
popup.add_response("copy", _("Copy"))
|
popup.add_response("copy", _("Copy"))
|
||||||
popup.add_response("ok", _("OK"))
|
popup.add_response("ok", _("OK"))
|
||||||
lb = Gtk.Label(selectable=True, wrap=True)#, natural_wrap_mode=Gtk.NaturalWrapMode.WORD)
|
lb = Gtk.Label(selectable=True, wrap=True) # , natural_wrap_mode=Gtk.NaturalWrapMode.WORD)
|
||||||
lb.set_markup(f"<tt>{GLib.markup_escape_text(error_msg)}</tt>")
|
lb.set_markup(f"<tt>{GLib.markup_escape_text(error_msg)}</tt>")
|
||||||
# lb.set_label(error_msg)
|
# lb.set_label(error_msg)
|
||||||
# lb.set_selectable(True)
|
# lb.set_selectable(True)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from gi.repository import Adw, Gtk
|
from gi.repository import Adw, Gtk
|
||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/installation_chooser.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/installation_chooser.ui")
|
||||||
class InstallationChooser(Adw.PreferencesGroup):
|
class InstallationChooser(Adw.PreferencesGroup):
|
||||||
__gtype_name__ = 'InstallationChooser'
|
__gtype_name__ = "InstallationChooser"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
user_row = gtc()
|
user_row = gtc()
|
||||||
@@ -20,7 +21,7 @@ class InstallationChooser(Adw.PreferencesGroup):
|
|||||||
if button.get_active():
|
if button.get_active():
|
||||||
return func()
|
return func()
|
||||||
|
|
||||||
return "" # Case for when no button is active (which shouldn't happen)
|
return "" # Case for when no button is active (which shouldn't happen)
|
||||||
|
|
||||||
def set_content_strings(self, content_name, is_plural):
|
def set_content_strings(self, content_name, is_plural):
|
||||||
if is_plural:
|
if is_plural:
|
||||||
@@ -36,7 +37,7 @@ class InstallationChooser(Adw.PreferencesGroup):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.check_buttons = {
|
self.check_buttons = {
|
||||||
self.user_check : lambda: "user",
|
self.user_check: lambda: "user",
|
||||||
self.system_check: lambda: "system",
|
self.system_check: lambda: "system",
|
||||||
self.single_check: self.single_row.get_title,
|
self.single_check: self.single_row.get_title,
|
||||||
self.choice_check: lambda: self.choice_row.get_selected_item().get_string(),
|
self.choice_check: lambda: self.choice_row.get_selected_item().get_string(),
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gi.repository import Gtk, GLib
|
from gi.repository import Gtk, GLib
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/loading_status.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/loading_status.ui")
|
||||||
class LoadingStatus(Gtk.ScrolledWindow):
|
class LoadingStatus(Gtk.ScrolledWindow):
|
||||||
__gtype_name__ = 'LoadingStatus'
|
__gtype_name__ = "LoadingStatus"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
title_label = gtc()
|
title_label = gtc()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
|
|
||||||
|
|
||||||
class SidebarButton(Gtk.Button):
|
class SidebarButton(Gtk.Button):
|
||||||
__gtype_name__ = "SidebarButton"
|
__gtype_name__ = "SidebarButton"
|
||||||
|
|
||||||
|
|||||||
106
src/host_info.py
106
src/host_info.py
@@ -7,14 +7,16 @@ icon_theme = Gtk.IconTheme.new()
|
|||||||
icon_theme.add_search_path(f"{home}/.local/share/flatpak/exports/share/icons")
|
icon_theme.add_search_path(f"{home}/.local/share/flatpak/exports/share/icons")
|
||||||
direction = Gtk.Image().get_direction()
|
direction = Gtk.Image().get_direction()
|
||||||
|
|
||||||
|
|
||||||
class Flatpak:
|
class Flatpak:
|
||||||
def open_app(self, callback=None):
|
def open_app(self, callback=None):
|
||||||
self.failed_app_run = None
|
self.failed_app_run = None
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
if self.is_runtime:
|
if self.is_runtime:
|
||||||
self.failed_app_run = "error: cannot open a runtime"
|
self.failed_app_run = "error: cannot open a runtime"
|
||||||
try:
|
try:
|
||||||
subprocess.run(['flatpak-spawn', '--host', 'flatpak', 'run', f"{self.info['ref']}"], capture_output=True, text=True, check=True)
|
subprocess.run(["flatpak-spawn", "--host", "flatpak", "run", f"{self.info['ref']}"], capture_output=True, text=True, check=True)
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
self.failed_app_run = cpe
|
self.failed_app_run = cpe
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -32,17 +34,20 @@ class Flatpak:
|
|||||||
|
|
||||||
def get_data_size(self, callback=None):
|
def get_data_size(self, callback=None):
|
||||||
size = [None]
|
size = [None]
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
sed = "sed 's/K/ KB/; s/M/ MB/; s/G/ GB/; s/T/ TB/; s/P/ PB/;'"
|
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]
|
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):
|
def on_done(*arg):
|
||||||
if callback:
|
if callback:
|
||||||
callback(f"~ {size[0]}")
|
callback(f"~ {size[0]}")
|
||||||
|
|
||||||
Gio.Task.new(None, None, on_done).run_in_thread(thread)
|
Gio.Task.new(None, None, on_done).run_in_thread(thread)
|
||||||
|
|
||||||
def trash_data(self, callback=None):
|
def trash_data(self, callback=None):
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash', self.data_path], capture_output=True, text=True, check=True)
|
subprocess.run(["gio", "trash", self.data_path], capture_output=True, text=True, check=True)
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
raise cpe
|
raise cpe
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -50,8 +55,9 @@ class Flatpak:
|
|||||||
|
|
||||||
def set_mask(self, should_mask, callback=None):
|
def set_mask(self, should_mask, callback=None):
|
||||||
self.failed_mask = None
|
self.failed_mask = None
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'mask', self.info["id"]]
|
cmd = ["flatpak-spawn", "--host", "flatpak", "mask", self.info["id"]]
|
||||||
installation = self.info["installation"]
|
installation = self.info["installation"]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
@@ -77,7 +83,7 @@ class Flatpak:
|
|||||||
self.failed_pin = "Cannot pin an application"
|
self.failed_pin = "Cannot pin an application"
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'pin', f"runtime/{self.info['ref']}"]
|
cmd = ["flatpak-spawn", "--host", "flatpak", "pin", f"runtime/{self.info['ref']}"]
|
||||||
installation = self.info["installation"]
|
installation = self.info["installation"]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
@@ -106,7 +112,7 @@ class Flatpak:
|
|||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
HostInfo.main_window.add_refresh_lockout("uninstalling packages")
|
HostInfo.main_window.add_refresh_lockout("uninstalling packages")
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'uninstall', '-y', self.info["ref"]]
|
cmd = ["flatpak-spawn", "--host", "flatpak", "uninstall", "-y", self.info["ref"]]
|
||||||
installation = self.info["installation"]
|
installation = self.info["installation"]
|
||||||
if installation == "system" or installation == "user":
|
if installation == "system" or installation == "user":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
@@ -136,10 +142,7 @@ class Flatpak:
|
|||||||
|
|
||||||
cmd += self.info["ref"]
|
cmd += self.info["ref"]
|
||||||
try:
|
try:
|
||||||
output = subprocess.run(
|
output = subprocess.run(["flatpak-spawn", "--host", "sh", "-c", cmd], text=True, capture_output=True).stdout
|
||||||
['flatpak-spawn', '--host', 'sh', '-c', cmd],
|
|
||||||
text=True, capture_output=True
|
|
||||||
).stdout
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
@@ -172,23 +175,23 @@ class Flatpak:
|
|||||||
|
|
||||||
def __init__(self, columns):
|
def __init__(self, columns):
|
||||||
self.info = {
|
self.info = {
|
||||||
"name": columns[0],
|
"name": columns[0],
|
||||||
"id": columns[1],
|
"id": columns[1],
|
||||||
"version": columns[2],
|
"version": columns[2],
|
||||||
"branch": columns[3],
|
"branch": columns[3],
|
||||||
"arch": columns[4],
|
"arch": columns[4],
|
||||||
"origin": columns[5],
|
"origin": columns[5],
|
||||||
"installation": columns[6],
|
"installation": columns[6],
|
||||||
"ref": columns[7],
|
"ref": columns[7],
|
||||||
"installed_size": columns[8],
|
"installed_size": columns[8],
|
||||||
"options": columns[9],
|
"options": columns[9],
|
||||||
}
|
}
|
||||||
self.is_runtime = "runtime" in self.info["options"]
|
self.is_runtime = "runtime" in self.info["options"]
|
||||||
self.data_path = f"{home}/.var/app/{self.info["id"]}"
|
self.data_path = f"{home}/.var/app/{self.info["id"]}"
|
||||||
self.data_size = -1
|
self.data_size = -1
|
||||||
self.cli_info = None
|
self.cli_info = None
|
||||||
installation = self.info["installation"]
|
installation = self.info["installation"]
|
||||||
if len(i := installation.split(' ')) > 1:
|
if len(i := installation.split(" ")) > 1:
|
||||||
self.info["installation"] = i[1].replace("(", "").replace(")", "")
|
self.info["installation"] = i[1].replace("(", "").replace(")", "")
|
||||||
else:
|
else:
|
||||||
self.info["installation"] = installation
|
self.info["installation"] = installation
|
||||||
@@ -211,13 +214,7 @@ class Flatpak:
|
|||||||
self.is_pinned = False
|
self.is_pinned = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.icon_path = (
|
self.icon_path = icon_theme.lookup_icon(self.info["id"], None, 512, 1, direction, 0).get_file().get_path()
|
||||||
icon_theme.lookup_icon(
|
|
||||||
self.info["id"], None, 512, 1, direction, 0
|
|
||||||
)
|
|
||||||
.get_file()
|
|
||||||
.get_path()
|
|
||||||
)
|
|
||||||
except GLib.GError as e:
|
except GLib.GError as e:
|
||||||
print(f"Minor error in looking up icon for {self.info['id']}", e)
|
print(f"Minor error in looking up icon for {self.info['id']}", e)
|
||||||
self.icon_path = None
|
self.icon_path = None
|
||||||
@@ -231,6 +228,7 @@ class Remote:
|
|||||||
if title == "" or title == "-":
|
if title == "" or title == "-":
|
||||||
self.title = name
|
self.title = name
|
||||||
|
|
||||||
|
|
||||||
class HostInfo:
|
class HostInfo:
|
||||||
home = home
|
home = home
|
||||||
clipboard = Gdk.Display.get_default().get_clipboard()
|
clipboard = Gdk.Display.get_default().get_clipboard()
|
||||||
@@ -239,8 +237,7 @@ class HostInfo:
|
|||||||
|
|
||||||
# Get all possible installation icon theme dirs
|
# Get all possible installation icon theme dirs
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
['flatpak-spawn', '--host',
|
["flatpak-spawn", "--host", "flatpak", "--installations"],
|
||||||
'flatpak', '--installations'],
|
|
||||||
text=True,
|
text=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
@@ -256,6 +253,7 @@ class HostInfo:
|
|||||||
masks = {}
|
masks = {}
|
||||||
pins = {}
|
pins = {}
|
||||||
dependent_runtime_refs = []
|
dependent_runtime_refs = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_flatpaks(this, callback=None):
|
def get_flatpaks(this, callback=None):
|
||||||
# Callback is a function to run after the host flatpaks are found
|
# Callback is a function to run after the host flatpaks are found
|
||||||
@@ -271,52 +269,62 @@ class HostInfo:
|
|||||||
def thread(task, *args):
|
def thread(task, *args):
|
||||||
# Remotes
|
# Remotes
|
||||||
def remote_info(installation):
|
def remote_info(installation):
|
||||||
cmd = ['flatpak-spawn', '--host',
|
cmd = ["flatpak-spawn", "--host", "flatpak", "remotes", "--columns=name,title,options", "--show-disabled"]
|
||||||
'flatpak', 'remotes', '--columns=name,title,options', '--show-disabled']
|
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
else:
|
else:
|
||||||
cmd.append(f"--installation={installation}")
|
cmd.append(f"--installation={installation}")
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
cmd, text=True,
|
cmd,
|
||||||
|
text=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
lines = output.strip().split("\n")
|
lines = output.strip().split("\n")
|
||||||
remote_list = []
|
remote_list = []
|
||||||
if lines[0] != '':
|
if lines[0] != "":
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.split("\t")
|
line = line.split("\t")
|
||||||
remote_list.append(Remote(name=line[0], title=line[1], disabled=(len(line) == 3) and "disabled" in line[2]))
|
remote_list.append(Remote(name=line[0], title=line[1], disabled=(len(line) == 3) and "disabled" in line[2]))
|
||||||
this.remotes[installation] = remote_list
|
this.remotes[installation] = remote_list
|
||||||
|
|
||||||
# Masks
|
# Masks
|
||||||
cmd = ['flatpak-spawn', '--host',
|
cmd = [
|
||||||
'flatpak', 'mask',]
|
"flatpak-spawn",
|
||||||
|
"--host",
|
||||||
|
"flatpak",
|
||||||
|
"mask",
|
||||||
|
]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
else:
|
else:
|
||||||
cmd.append(f"--installation={installation}")
|
cmd.append(f"--installation={installation}")
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
cmd, text=True,
|
cmd,
|
||||||
|
text=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
lines = output.strip().replace(" ", "").split("\n")
|
lines = output.strip().replace(" ", "").split("\n")
|
||||||
if lines[0] != '':
|
if lines[0] != "":
|
||||||
this.masks[installation] = lines
|
this.masks[installation] = lines
|
||||||
|
|
||||||
# Pins
|
# Pins
|
||||||
cmd = ['flatpak-spawn', '--host',
|
cmd = [
|
||||||
'flatpak', 'pin',]
|
"flatpak-spawn",
|
||||||
|
"--host",
|
||||||
|
"flatpak",
|
||||||
|
"pin",
|
||||||
|
]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
cmd.append(f"--{installation}")
|
cmd.append(f"--{installation}")
|
||||||
else:
|
else:
|
||||||
cmd.append(f"--installation={installation}")
|
cmd.append(f"--installation={installation}")
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
cmd, text=True,
|
cmd,
|
||||||
|
text=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
lines = output.strip().replace(" ", "").split("\n")
|
lines = output.strip().replace(" ", "").split("\n")
|
||||||
if lines[0] != '':
|
if lines[0] != "":
|
||||||
this.pins[installation] = lines
|
this.pins[installation] = lines
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -329,7 +337,7 @@ class HostInfo:
|
|||||||
for line in f:
|
for line in f:
|
||||||
if line.startswith("[Installation"):
|
if line.startswith("[Installation"):
|
||||||
# Get specifically the installation name itself
|
# Get specifically the installation name itself
|
||||||
this.installations.append(line.replace("[Installation \"", "").replace("\"]", "").strip())
|
this.installations.append(line.replace('[Installation "', "").replace('"]', "").strip())
|
||||||
|
|
||||||
this.installations.append("user")
|
this.installations.append("user")
|
||||||
this.installations.append("system")
|
this.installations.append("system")
|
||||||
@@ -340,9 +348,9 @@ class HostInfo:
|
|||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
['flatpak-spawn', '--host', 'flatpak', 'list',
|
["flatpak-spawn", "--host", "flatpak", "list", "--columns=name,application,version,branch,arch,origin,installation,ref,size,options"],
|
||||||
'--columns=name,application,version,branch,arch,origin,installation,ref,size,options'],
|
text=True,
|
||||||
text=True, check=True,
|
check=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
lines = output.strip().split("\n")
|
lines = output.strip().split("\n")
|
||||||
@@ -354,15 +362,15 @@ class HostInfo:
|
|||||||
|
|
||||||
# Dependent Runtimes
|
# Dependent Runtimes
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
['flatpak-spawn', '--host',
|
["flatpak-spawn", "--host", "flatpak", "list", "--columns=runtime,ref"],
|
||||||
'flatpak', 'list', '--columns=runtime,ref'],
|
text=True,
|
||||||
text=True, check=True,
|
check=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
).stdout
|
).stdout
|
||||||
lines = output.split("\n")
|
lines = output.split("\n")
|
||||||
for index, line in enumerate(lines):
|
for index, line in enumerate(lines):
|
||||||
split_line = line.split("\t")
|
split_line = line.split("\t")
|
||||||
if len(split_line) < 2 or split_line[0] == '':
|
if len(split_line) < 2 or split_line[0] == "":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
package = this.flatpaks[index]
|
package = this.flatpaks[index]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from gi.repository import Adw, Gtk
|
from gi.repository import Adw, Gtk
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/file_install_dialog.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/file_install_dialog.ui")
|
||||||
class FileInstallDialog(Adw.Dialog):
|
class FileInstallDialog(Adw.Dialog):
|
||||||
__gtype_name__ = "FileInstallDialog"
|
__gtype_name__ = "FileInstallDialog"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from .loading_status import LoadingStatus
|
|||||||
from .package_install_worker import PackageInstallWorker
|
from .package_install_worker import PackageInstallWorker
|
||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/install_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/install_page.ui")
|
||||||
class InstallPage(Adw.BreakpointBin):
|
class InstallPage(Adw.BreakpointBin):
|
||||||
__gtype_name__ = "InstallPage"
|
__gtype_name__ = "InstallPage"
|
||||||
@@ -25,8 +26,8 @@ class InstallPage(Adw.BreakpointBin):
|
|||||||
bottom_label = gtc()
|
bottom_label = gtc()
|
||||||
|
|
||||||
# Referred to in the main window
|
# Referred to in the main window
|
||||||
# It is used to determine if a new page should be made or not
|
# It is used to determine if a new page should be made or not
|
||||||
# This must be set to the created object from within the class's __init__ method
|
# This must be set to the created object from within the class's __init__ method
|
||||||
instance = None
|
instance = None
|
||||||
page_name = "install"
|
page_name = "install"
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from gi.repository import Adw, Gtk
|
|||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
from .result_row import ResultRow
|
from .result_row import ResultRow
|
||||||
|
|
||||||
|
|
||||||
class AddedGroup(Adw.PreferencesGroup):
|
class AddedGroup(Adw.PreferencesGroup):
|
||||||
__gtype_name__ = "AddedGroup"
|
__gtype_name__ = "AddedGroup"
|
||||||
|
|
||||||
@@ -33,12 +34,13 @@ class AddedGroup(Adw.PreferencesGroup):
|
|||||||
icon_name="list-remove-all-symbolic",
|
icon_name="list-remove-all-symbolic",
|
||||||
label=_("Remove All"),
|
label=_("Remove All"),
|
||||||
),
|
),
|
||||||
valign = Gtk.Align.CENTER,
|
valign=Gtk.Align.CENTER,
|
||||||
)
|
)
|
||||||
remove_all.add_css_class("flat")
|
remove_all.add_css_class("flat")
|
||||||
remove_all.connect("clicked", self.remove_all)
|
remove_all.connect("clicked", self.remove_all)
|
||||||
self.set_header_suffix(remove_all)
|
self.set_header_suffix(remove_all)
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/pending_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/pending_page.ui")
|
||||||
class PendingPage(Adw.NavigationPage):
|
class PendingPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = "PendingPage"
|
__gtype_name__ = "PendingPage"
|
||||||
@@ -100,7 +102,7 @@ class PendingPage(Adw.NavigationPage):
|
|||||||
"extra_flags": [],
|
"extra_flags": [],
|
||||||
}
|
}
|
||||||
for row in group.rows:
|
for row in group.rows:
|
||||||
item['package_names'].append(row.package.app_id)
|
item["package_names"].append(row.package.app_id)
|
||||||
|
|
||||||
package_requests.append(item)
|
package_requests.append(item)
|
||||||
|
|
||||||
@@ -119,7 +121,7 @@ class PendingPage(Adw.NavigationPage):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
# Extra Object Creation
|
# Extra Object Creation
|
||||||
self.groups = {} # remote<>installation: adw.preference_group
|
self.groups = {} # remote<>installation: adw.preference_group
|
||||||
self.added_packages = []
|
self.added_packages = []
|
||||||
|
|
||||||
# Connections
|
# Connections
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from gi.repository import Adw, Gtk, GLib
|
from gi.repository import Adw, Gtk, GLib
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/result_row.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/result_row.ui")
|
||||||
class ResultRow(Adw.ActionRow):
|
class ResultRow(Adw.ActionRow):
|
||||||
__gtype_name__ = "ResultRow"
|
__gtype_name__ = "ResultRow"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .loading_status import LoadingStatus
|
|||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
class AddedPackage:
|
class AddedPackage:
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return (
|
return (
|
||||||
@@ -17,11 +18,7 @@ class AddedPackage:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def is_similar(self, other):
|
def is_similar(self, other):
|
||||||
return (
|
return self.app_id == other.app_id and self.branch == other.branch and self.version == other.version
|
||||||
self.app_id == other.app_id
|
|
||||||
and self.branch == other.branch
|
|
||||||
and self.version == other.version
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, name, app_id, branch, version, remote, installation):
|
def __init__(self, name, app_id, branch, version, remote, installation):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -31,6 +28,7 @@ class AddedPackage:
|
|||||||
self.remote = remote
|
self.remote = remote
|
||||||
self.installation = installation
|
self.installation = installation
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/results_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/results_page.ui")
|
||||||
class ResultsPage(Adw.NavigationPage):
|
class ResultsPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = "ResultsPage"
|
__gtype_name__ = "ResultsPage"
|
||||||
@@ -41,7 +39,7 @@ class ResultsPage(Adw.NavigationPage):
|
|||||||
stack = gtc()
|
stack = gtc()
|
||||||
new_search = gtc()
|
new_search = gtc()
|
||||||
too_many = gtc()
|
too_many = gtc()
|
||||||
results_view= gtc()
|
results_view = gtc()
|
||||||
no_results = gtc()
|
no_results = gtc()
|
||||||
|
|
||||||
def show_remote(self, row, remote, installation, nav_view=None):
|
def show_remote(self, row, remote, installation, nav_view=None):
|
||||||
@@ -76,9 +74,11 @@ class ResultsPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', installation, self.search_entry.get_text()],
|
["flatpak-spawn", "--host", "flatpak", "search", "--columns=all", installation, self.search_entry.get_text()],
|
||||||
check=True, text=True, capture_output=True
|
check=True,
|
||||||
).stdout.split('\n')
|
text=True,
|
||||||
|
capture_output=True,
|
||||||
|
).stdout.split("\n")
|
||||||
if len(output) > 100:
|
if len(output) > 100:
|
||||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.too_many))
|
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.too_many))
|
||||||
return
|
return
|
||||||
@@ -86,11 +86,11 @@ class ResultsPage(Adw.NavigationPage):
|
|||||||
for line in output:
|
for line in output:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
|
|
||||||
info = line.split('\t')
|
info = line.split("\t")
|
||||||
if len(info) != 6:
|
if len(info) != 6:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
remotes = info[5].split(',')
|
remotes = info[5].split(",")
|
||||||
if not self.remote.name in remotes:
|
if not self.remote.name in remotes:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .results_page import ResultsPage
|
|||||||
from .sidebar_button import SidebarButton
|
from .sidebar_button import SidebarButton
|
||||||
from .file_install_dialog import FileInstallDialog
|
from .file_install_dialog import FileInstallDialog
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/select_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/select_page.ui")
|
||||||
class SelectPage(Adw.NavigationPage):
|
class SelectPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = "SelectPage"
|
__gtype_name__ = "SelectPage"
|
||||||
@@ -41,12 +42,14 @@ class SelectPage(Adw.NavigationPage):
|
|||||||
requests = []
|
requests = []
|
||||||
for file in file_names:
|
for file in file_names:
|
||||||
# sadly flatpak doesn't support multiple local installs in one command :(
|
# sadly flatpak doesn't support multiple local installs in one command :(
|
||||||
requests.append({
|
requests.append(
|
||||||
"remote": "local_file",
|
{
|
||||||
"installation": installation,
|
"remote": "local_file",
|
||||||
"package_names": [file.get_path()],
|
"installation": installation,
|
||||||
"extra_flags": [],
|
"package_names": [file.get_path()],
|
||||||
})
|
"extra_flags": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
install_page.install_packages(requests)
|
install_page.install_packages(requests)
|
||||||
|
|
||||||
|
|||||||
20
src/main.py
20
src/main.py
@@ -30,6 +30,7 @@ from .window import WarehouseWindow
|
|||||||
from .const import Config
|
from .const import Config
|
||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
|
|
||||||
|
|
||||||
class WarehouseApplication(Adw.Application):
|
class WarehouseApplication(Adw.Application):
|
||||||
"""The main application singleton class."""
|
"""The main application singleton class."""
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ class WarehouseApplication(Adw.Application):
|
|||||||
self.create_action("show-install-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("i"), ["<primary>i"])
|
self.create_action("show-install-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("i"), ["<primary>i"])
|
||||||
|
|
||||||
self.create_action("toggle-select-mode", self.on_toggle_select_mode_shortcut, ["<primary>b", "<primary>Return"])
|
self.create_action("toggle-select-mode", self.on_toggle_select_mode_shortcut, ["<primary>b", "<primary>Return"])
|
||||||
self.create_action("toggle-selection-kp-enter", self.on_toggle_select_mode_shortcut, ["<primary>KP_Enter"]) # Doesn't show in the shortcuts window
|
self.create_action("toggle-selection-kp-enter", self.on_toggle_select_mode_shortcut, ["<primary>KP_Enter"]) # Doesn't show in the shortcuts window
|
||||||
self.create_action("search-mode", self.on_search_mode_shortcut, ["<primary>f"])
|
self.create_action("search-mode", self.on_search_mode_shortcut, ["<primary>f"])
|
||||||
self.create_action("filter", self.on_filter_shortcut, ["<primary>t"])
|
self.create_action("filter", self.on_filter_shortcut, ["<primary>t"])
|
||||||
self.create_action("new", self.on_new_shortcut, ["<primary>n"])
|
self.create_action("new", self.on_new_shortcut, ["<primary>n"])
|
||||||
@@ -64,20 +65,8 @@ class WarehouseApplication(Adw.Application):
|
|||||||
|
|
||||||
self.is_dialog_open = False
|
self.is_dialog_open = False
|
||||||
|
|
||||||
gtk_version = (
|
gtk_version = str(Gtk.MAJOR_VERSION) + "." + str(Gtk.MINOR_VERSION) + "." + str(Gtk.MICRO_VERSION)
|
||||||
str(Gtk.MAJOR_VERSION)
|
adw_version = str(Adw.MAJOR_VERSION) + "." + str(Adw.MINOR_VERSION) + "." + str(Adw.MICRO_VERSION)
|
||||||
+ "."
|
|
||||||
+ str(Gtk.MINOR_VERSION)
|
|
||||||
+ "."
|
|
||||||
+ str(Gtk.MICRO_VERSION)
|
|
||||||
)
|
|
||||||
adw_version = (
|
|
||||||
str(Adw.MAJOR_VERSION)
|
|
||||||
+ "."
|
|
||||||
+ str(Adw.MINOR_VERSION)
|
|
||||||
+ "."
|
|
||||||
+ str(Adw.MICRO_VERSION)
|
|
||||||
)
|
|
||||||
os_string = GLib.get_os_info("NAME") + " " + GLib.get_os_info("VERSION")
|
os_string = GLib.get_os_info("NAME") + " " + GLib.get_os_info("VERSION")
|
||||||
lang = GLib.environ_getenv(GLib.get_environ(), "LANG")
|
lang = GLib.environ_getenv(GLib.get_environ(), "LANG")
|
||||||
|
|
||||||
@@ -252,6 +241,7 @@ class WarehouseApplication(Adw.Application):
|
|||||||
if shortcuts:
|
if shortcuts:
|
||||||
self.set_accels_for_action(f"app.{name}", shortcuts)
|
self.set_accels_for_action(f"app.{name}", shortcuts)
|
||||||
|
|
||||||
|
|
||||||
def main(version):
|
def main(version):
|
||||||
"""The application's entry point."""
|
"""The application's entry point."""
|
||||||
app = WarehouseApplication()
|
app = WarehouseApplication()
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from .install_page import InstallPage
|
|||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
from .const import Config
|
from .const import Config
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui")
|
||||||
class WarehouseWindow(Adw.ApplicationWindow):
|
class WarehouseWindow(Adw.ApplicationWindow):
|
||||||
__gtype_name__ = "WarehouseWindow"
|
__gtype_name__ = "WarehouseWindow"
|
||||||
|
|||||||
@@ -2,19 +2,20 @@ from gi.repository import Gio, GLib
|
|||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
import subprocess, re
|
import subprocess, re
|
||||||
|
|
||||||
|
|
||||||
class PackageInstallWorker:
|
class PackageInstallWorker:
|
||||||
""" Expect Package Installation Request Data to be Formatted as Such
|
"""Expect Package Installation Request Data to be Formatted as Such
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"remote": "<remote name>" or "local_file",
|
"remote": "<remote name>" or "local_file",
|
||||||
"installation": "<installation name>",
|
"installation": "<installation name>",
|
||||||
"package_names": ["<pkg id 1>", "<pkg id 2>", ...],
|
"package_names": ["<pkg id 1>", "<pkg id 2>", ...],
|
||||||
"extra_flags": ["<flag 1>", "<flag 2>", ...],
|
"extra_flags": ["<flag 1>", "<flag 2>", ...],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
groups = None
|
groups = None
|
||||||
@@ -46,22 +47,22 @@ class PackageInstallWorker:
|
|||||||
return
|
return
|
||||||
|
|
||||||
real_installation = ""
|
real_installation = ""
|
||||||
installation = group['installation']
|
installation = group["installation"]
|
||||||
if installation == "user" or installation == "system":
|
if installation == "user" or installation == "system":
|
||||||
real_installation = f"--{installation}"
|
real_installation = f"--{installation}"
|
||||||
else:
|
else:
|
||||||
real_installation = f"--installation={installation}"
|
real_installation = f"--installation={installation}"
|
||||||
|
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'install', '-y']
|
cmd = ["flatpak-spawn", "--host", "flatpak", "install", "-y"]
|
||||||
|
|
||||||
# Handle local file installs. They don't have a remote specified
|
# Handle local file installs. They don't have a remote specified
|
||||||
if group['remote'] != "local_file":
|
if group["remote"] != "local_file":
|
||||||
cmd.append(group['remote'])
|
cmd.append(group["remote"])
|
||||||
|
|
||||||
cmd += [real_installation] + group['package_names'] + group['extra_flags']
|
cmd += [real_installation] + group["package_names"] + group["extra_flags"]
|
||||||
this.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
this.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||||
percent_pattern = r'\d{1,3}%'
|
percent_pattern = r"\d{1,3}%"
|
||||||
amount_pattern = r'(\d+)/(\d+)'
|
amount_pattern = r"(\d+)/(\d+)"
|
||||||
for line in this.process.stdout:
|
for line in this.process.stdout:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
percent_match = re.search(percent_pattern, line)
|
percent_match = re.search(percent_pattern, line)
|
||||||
@@ -69,7 +70,7 @@ class PackageInstallWorker:
|
|||||||
ratio = int(percent_match.group()[0:-1]) / 100.0
|
ratio = int(percent_match.group()[0:-1]) / 100.0
|
||||||
amount_match = re.search(amount_pattern, line)
|
amount_match = re.search(amount_pattern, line)
|
||||||
if amount_match:
|
if amount_match:
|
||||||
amount = amount_match.group().split('/')
|
amount = amount_match.group().split("/")
|
||||||
complete = int(amount[0]) - 1
|
complete = int(amount[0]) - 1
|
||||||
total = int(amount[1])
|
total = int(amount[1])
|
||||||
this.update_status(index, ratio, complete, total)
|
this.update_status(index, ratio, complete, total)
|
||||||
@@ -83,7 +84,7 @@ class PackageInstallWorker:
|
|||||||
if len(errors) > 0:
|
if len(errors) > 0:
|
||||||
this.on_error(_("Errors occurred during installation"), "\n".join(errors))
|
this.on_error(_("Errors occurred during installation"), "\n".join(errors))
|
||||||
|
|
||||||
except subprocess.TimeoutExpired as te:
|
except subprocess.TimeoutExpired:
|
||||||
this.process.terminate()
|
this.process.terminate()
|
||||||
this.on_error(_("Error occurred during installation"), _("Failed to exit cleanly"))
|
this.on_error(_("Error occurred during installation"), _("Failed to exit cleanly"))
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
from gi.repository import Adw, Gtk, Gio
|
from gi.repository import Adw, Gtk, Gio
|
||||||
from .host_info import HostInfo
|
from .host_info import HostInfo
|
||||||
|
|
||||||
|
|
||||||
class FilterRow(Adw.ActionRow):
|
class FilterRow(Adw.ActionRow):
|
||||||
__gtype_name__ = 'FilterRow'
|
__gtype_name__ = "FilterRow"
|
||||||
|
|
||||||
def __init__(self, item=None, installation=None, **kwargs):
|
def __init__(self, item=None, installation=None, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.item = item
|
self.item = item
|
||||||
@@ -11,9 +13,10 @@ class FilterRow(Adw.ActionRow):
|
|||||||
self.add_suffix(self.check_button)
|
self.add_suffix(self.check_button)
|
||||||
self.set_activatable_widget(self.check_button)
|
self.set_activatable_widget(self.check_button)
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/filters_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/filters_page.ui")
|
||||||
class FiltersPage(Adw.NavigationPage):
|
class FiltersPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = 'FiltersPage'
|
__gtype_name__ = "FiltersPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
app_check = gtc()
|
app_check = gtc()
|
||||||
runtime_check = gtc()
|
runtime_check = gtc()
|
||||||
@@ -173,7 +176,7 @@ class FiltersPage(Adw.NavigationPage):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
# Extra Objects Creation
|
# Extra Objects Creation
|
||||||
self.packages_page = None # To be set in packages page
|
self.packages_page = None # To be set in packages page
|
||||||
self.main_window = HostInfo.main_window
|
self.main_window = HostInfo.main_window
|
||||||
self.settings = Gio.Settings.new("io.github.flattool.Warehouse.filter")
|
self.settings = Gio.Settings.new("io.github.flattool.Warehouse.filter")
|
||||||
self.is_settings_settable = False
|
self.is_settings_settable = False
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ from .package_install_worker import PackageInstallWorker
|
|||||||
from .change_version_worker import ChangeVersionWorker
|
from .change_version_worker import ChangeVersionWorker
|
||||||
import subprocess, os
|
import subprocess, os
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/packages_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/packages_page.ui")
|
||||||
class PackagesPage(Adw.BreakpointBin):
|
class PackagesPage(Adw.BreakpointBin):
|
||||||
__gtype_name__ = 'PackagesPage'
|
__gtype_name__ = "PackagesPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
packages_bpt = gtc()
|
packages_bpt = gtc()
|
||||||
packages_toast_overlay = gtc()
|
packages_toast_overlay = gtc()
|
||||||
@@ -49,8 +50,8 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
filters_page = gtc()
|
filters_page = gtc()
|
||||||
|
|
||||||
# Referred to in the main window
|
# Referred to in the main window
|
||||||
# It is used to determine if a new page should be made or not
|
# It is used to determine if a new page should be made or not
|
||||||
# This must be set to the created object from within the class's __init__ method
|
# This must be set to the created object from within the class's __init__ method
|
||||||
instance = None
|
instance = None
|
||||||
page_name = "packages"
|
page_name = "packages"
|
||||||
last_activated_row = None
|
last_activated_row = None
|
||||||
@@ -110,7 +111,9 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
visible = False
|
visible = False
|
||||||
if remotes_list != "all" and not f"{row.package.info['origin']}<>{row.package.info['installation']}" in remotes_list:
|
if remotes_list != "all" and not f"{row.package.info['origin']}<>{row.package.info['installation']}" in remotes_list:
|
||||||
visible = False
|
visible = False
|
||||||
if runtimes_list != "all" and (row.package.is_runtime or row.package.dependent_runtime and not row.package.dependent_runtime.info["ref"] in runtimes_list):
|
if runtimes_list != "all" and (
|
||||||
|
row.package.is_runtime or row.package.dependent_runtime and not row.package.dependent_runtime.info["ref"] in runtimes_list
|
||||||
|
):
|
||||||
visible = False
|
visible = False
|
||||||
|
|
||||||
row.set_visible(visible)
|
row.set_visible(visible)
|
||||||
@@ -195,7 +198,7 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
self.apply_filters()
|
self.apply_filters()
|
||||||
self.select_first_visible_row()
|
self.select_first_visible_row()
|
||||||
|
|
||||||
self.scrolled_window.set_vadjustment(Gtk.Adjustment.new(0,0,0,0,0,0)) # Scroll list to top
|
self.scrolled_window.set_vadjustment(Gtk.Adjustment.new(0, 0, 0, 0, 0, 0)) # Scroll list to top
|
||||||
|
|
||||||
def row_activate_handler(self, list_box, row):
|
def row_activate_handler(self, list_box, row):
|
||||||
if self.select_button.get_active():
|
if self.select_button.get_active():
|
||||||
@@ -248,7 +251,7 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
to_copy = []
|
to_copy = []
|
||||||
for row in self.selected_rows:
|
for row in self.selected_rows:
|
||||||
to_copy.append(row.package.info[info])
|
to_copy.append(row.package.info[info])
|
||||||
to_copy += ['\n']
|
to_copy += ["\n"]
|
||||||
try:
|
try:
|
||||||
HostInfo.clipboard.set("".join(to_copy[:-1]))
|
HostInfo.clipboard.set("".join(to_copy[:-1]))
|
||||||
self.packages_toast_overlay.add_toast(Adw.Toast(title=_("Copied {}").format(feedback)))
|
self.packages_toast_overlay.add_toast(Adw.Toast(title=_("Copied {}").format(feedback)))
|
||||||
@@ -262,18 +265,19 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
def on_response(should_trash):
|
def on_response(should_trash):
|
||||||
GLib.idle_add(lambda *_: self.set_status(self.uninstalling))
|
GLib.idle_add(lambda *_: self.set_status(self.uninstalling))
|
||||||
error = []
|
error = []
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
HostInfo.main_window.add_refresh_lockout("batch uninstalling packages")
|
HostInfo.main_window.add_refresh_lockout("batch uninstalling packages")
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'uninstall', '-y']
|
cmd = ["flatpak-spawn", "--host", "flatpak", "uninstall", "-y"]
|
||||||
to_uninstall = {} # { <remote><><installation>: [<ref1>, <ref2>, <ref3>, ...], ... }
|
to_uninstall = {} # { <remote><><installation>: [<ref1>, <ref2>, <ref3>, ...], ... }
|
||||||
to_trash = []
|
to_trash = []
|
||||||
|
|
||||||
for row in self.selected_rows:
|
for row in self.selected_rows:
|
||||||
key = row.package.info['installation']
|
key = row.package.info["installation"]
|
||||||
if ls := to_uninstall.get(key, False):
|
if ls := to_uninstall.get(key, False):
|
||||||
ls.append(row.package.info['ref'])
|
ls.append(row.package.info["ref"])
|
||||||
else:
|
else:
|
||||||
to_uninstall[key] = [row.package.info['ref']]
|
to_uninstall[key] = [row.package.info["ref"]]
|
||||||
|
|
||||||
if should_trash and os.path.exists(row.package.data_path):
|
if should_trash and os.path.exists(row.package.data_path):
|
||||||
to_trash.append(row.package.data_path)
|
to_trash.append(row.package.data_path)
|
||||||
@@ -294,7 +298,7 @@ class PackagesPage(Adw.BreakpointBin):
|
|||||||
|
|
||||||
if should_trash and len(to_trash) > 0:
|
if should_trash and len(to_trash) > 0:
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash'] + to_trash, check=True, text=True, capture_output=True)
|
subprocess.run(["gio", "trash"] + to_trash, check=True, text=True, capture_output=True)
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
error.append(cpe)
|
error.append(cpe)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from gi.repository import Adw, Gtk, GLib
|
from gi.repository import Adw, Gtk, GLib
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/uninstall_dialog.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/packages_page/uninstall_dialog.ui")
|
||||||
class UninstallDialog(Adw.AlertDialog):
|
class UninstallDialog(Adw.AlertDialog):
|
||||||
__gtype_name__ = "UninstallDialog"
|
__gtype_name__ = "UninstallDialog"
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ from .loading_status import LoadingStatus
|
|||||||
from .package_install_worker import PackageInstallWorker
|
from .package_install_worker import PackageInstallWorker
|
||||||
import subprocess, os
|
import subprocess, os
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/properties_page/properties_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/properties_page/properties_page.ui")
|
||||||
class PropertiesPage(Adw.NavigationPage):
|
class PropertiesPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = 'PropertiesPage'
|
__gtype_name__ = "PropertiesPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
stack = gtc()
|
stack = gtc()
|
||||||
error_tbv = gtc()
|
error_tbv = gtc()
|
||||||
@@ -89,12 +90,12 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
self.open_app_button.set_visible(package.is_runtime)
|
self.open_app_button.set_visible(package.is_runtime)
|
||||||
self.open_app_button.set_visible(not package.is_runtime)
|
self.open_app_button.set_visible(not package.is_runtime)
|
||||||
self.data_row.set_visible(not package.is_runtime)
|
self.data_row.set_visible(not package.is_runtime)
|
||||||
self.uninstall_button.set_sensitive(self.package.info['id'] != "io.github.flattool.Warehouse")
|
self.uninstall_button.set_sensitive(self.package.info["id"] != "io.github.flattool.Warehouse")
|
||||||
if package.is_runtime:
|
if package.is_runtime:
|
||||||
self.runtime_row.set_visible(False)
|
self.runtime_row.set_visible(False)
|
||||||
else:
|
else:
|
||||||
has_path = os.path.exists(package.data_path)
|
has_path = os.path.exists(package.data_path)
|
||||||
self.trash_data_button.set_sensitive(has_path and self.package.info['id'] != "io.github.flattool.Warehouse")
|
self.trash_data_button.set_sensitive(has_path and self.package.info["id"] != "io.github.flattool.Warehouse")
|
||||||
self.open_data_button.set_sensitive(has_path)
|
self.open_data_button.set_sensitive(has_path)
|
||||||
|
|
||||||
if not self.package.dependent_runtime is None:
|
if not self.package.dependent_runtime is None:
|
||||||
@@ -163,7 +164,7 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
def trash_data_handler(self, *args):
|
def trash_data_handler(self, *args):
|
||||||
def on_choice(dialog, response):
|
def on_choice(dialog, response):
|
||||||
if response != 'continue':
|
if response != "continue":
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.package.trash_data()
|
self.package.trash_data()
|
||||||
@@ -184,16 +185,17 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
dialog = Adw.AlertDialog(
|
dialog = Adw.AlertDialog(
|
||||||
heading=_("Send {}'s User Data to the Trash?").format(self.package.info["name"]),
|
heading=_("Send {}'s User Data to the Trash?").format(self.package.info["name"]),
|
||||||
body=_("Your settings and data for this app will be sent to the trash")
|
body=_("Your settings and data for this app will be sent to the trash"),
|
||||||
)
|
)
|
||||||
dialog.add_response('cancel', _("Cancel"))
|
dialog.add_response("cancel", _("Cancel"))
|
||||||
dialog.add_response('continue', _("Trash Data"))
|
dialog.add_response("continue", _("Trash Data"))
|
||||||
dialog.connect("response", on_choice)
|
dialog.connect("response", on_choice)
|
||||||
dialog.set_response_appearance('continue', Adw.ResponseAppearance.DESTRUCTIVE)
|
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
|
||||||
dialog.present(self.main_window)
|
dialog.present(self.main_window)
|
||||||
|
|
||||||
def set_mask_handler(self, *args):
|
def set_mask_handler(self, *args):
|
||||||
state = not self.mask_switch.get_active()
|
state = not self.mask_switch.get_active()
|
||||||
|
|
||||||
def callback(*args):
|
def callback(*args):
|
||||||
if fail := self.package.failed_mask:
|
if fail := self.package.failed_mask:
|
||||||
response = _("Could not Disable Updates") if state else _("Could not Enable Updates")
|
response = _("Could not Disable Updates") if state else _("Could not Enable Updates")
|
||||||
@@ -212,6 +214,7 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
def set_pin_handler(self, *args):
|
def set_pin_handler(self, *args):
|
||||||
state = not self.pin_switch.get_active()
|
state = not self.pin_switch.get_active()
|
||||||
|
|
||||||
def callback(*args):
|
def callback(*args):
|
||||||
if fail := self.package.failed_pin:
|
if fail := self.package.failed_pin:
|
||||||
response = _("Could not Disable Autoremoval") if state else _("Could not Enable Autoremoval")
|
response = _("Could not Disable Autoremoval") if state else _("Could not Enable Autoremoval")
|
||||||
@@ -278,7 +281,7 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
def reinstall_callback(self):
|
def reinstall_callback(self):
|
||||||
HostInfo.main_window.refresh_handler()
|
HostInfo.main_window.refresh_handler()
|
||||||
if not self.reinstall_did_error:
|
if not self.reinstall_did_error:
|
||||||
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Reinstalled {}").format(self.package.info['name'])))
|
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Reinstalled {}").format(self.package.info["name"])))
|
||||||
|
|
||||||
def reinstall_error_callback(self, user_facing_label, error_message):
|
def reinstall_error_callback(self, user_facing_label, error_message):
|
||||||
self.reinstall_did_error = True
|
self.reinstall_did_error = True
|
||||||
@@ -291,12 +294,14 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
self.reinstall_did_error = False
|
self.reinstall_did_error = False
|
||||||
PackageInstallWorker.install(
|
PackageInstallWorker.install(
|
||||||
[{
|
[
|
||||||
"installation": self.package.info['installation'],
|
{
|
||||||
"remote": self.package.info['origin'],
|
"installation": self.package.info["installation"],
|
||||||
"package_names": [self.package.info['ref']],
|
"remote": self.package.info["origin"],
|
||||||
"extra_flags": ["--reinstall"],
|
"package_names": [self.package.info["ref"]],
|
||||||
}],
|
"extra_flags": ["--reinstall"],
|
||||||
|
}
|
||||||
|
],
|
||||||
self.packages_page.reinstalling,
|
self.packages_page.reinstalling,
|
||||||
self.reinstall_callback,
|
self.reinstall_callback,
|
||||||
self.reinstall_error_callback,
|
self.reinstall_error_callback,
|
||||||
@@ -304,8 +309,8 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
self.packages_page.set_status(self.packages_page.reinstalling)
|
self.packages_page.set_status(self.packages_page.reinstalling)
|
||||||
|
|
||||||
dialog = Adw.AlertDialog(
|
dialog = Adw.AlertDialog(
|
||||||
heading=_("Reinstall {}?").format(self.package.info['name']),
|
heading=_("Reinstall {}?").format(self.package.info["name"]),
|
||||||
body=_("This package will be uninstalled, and then reinstalled from the same remote and installation.")
|
body=_("This package will be uninstalled, and then reinstalled from the same remote and installation."),
|
||||||
)
|
)
|
||||||
dialog.add_response("cancel", _("Cancel"))
|
dialog.add_response("cancel", _("Cancel"))
|
||||||
dialog.add_response("continue", _("Reinstall"))
|
dialog.add_response("continue", _("Reinstall"))
|
||||||
@@ -346,25 +351,22 @@ class PropertiesPage(Adw.NavigationPage):
|
|||||||
self.info_rows = {
|
self.info_rows = {
|
||||||
"version": self.version_row,
|
"version": self.version_row,
|
||||||
"installed": self.installed_size_row,
|
"installed": self.installed_size_row,
|
||||||
|
|
||||||
"id": self.id_row,
|
"id": self.id_row,
|
||||||
"ref": self.ref_row,
|
"ref": self.ref_row,
|
||||||
"arch": self.arch_row,
|
"arch": self.arch_row,
|
||||||
"branch": self.branch_row,
|
"branch": self.branch_row,
|
||||||
"license": self.license_row,
|
"license": self.license_row,
|
||||||
|
|
||||||
"sdk": self.sdk_row,
|
"sdk": self.sdk_row,
|
||||||
"origin": self.origin_row,
|
"origin": self.origin_row,
|
||||||
"collection": self.collection_row,
|
"collection": self.collection_row,
|
||||||
"installation": self.installation_row,
|
"installation": self.installation_row,
|
||||||
|
|
||||||
"commit": self.commit_row,
|
"commit": self.commit_row,
|
||||||
"parent": self.parent_row,
|
"parent": self.parent_row,
|
||||||
"subject": self.subject_row,
|
"subject": self.subject_row,
|
||||||
"date": self.date_row,
|
"date": self.date_row,
|
||||||
}
|
}
|
||||||
self.loading_tbv.set_content(LoadingStatus(_("Loading Properties"), _("This should only take a moment")))
|
self.loading_tbv.set_content(LoadingStatus(_("Loading Properties"), _("This should only take a moment")))
|
||||||
self.packages_page = None # To be set in packages page
|
self.packages_page = None # To be set in packages page
|
||||||
self.__class__.main_window = self.main_window
|
self.__class__.main_window = self.main_window
|
||||||
self.view_snapshots = Gtk.Label(halign=Gtk.Align.START, label=_("View Snapshots"))
|
self.view_snapshots = Gtk.Label(halign=Gtk.Align.START, label=_("View Snapshots"))
|
||||||
self.copy_launch_command = Gtk.Label(halign=Gtk.Align.START, label=_("Copy Launch Command"))
|
self.copy_launch_command = Gtk.Label(halign=Gtk.Align.START, label=_("Copy Launch Command"))
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .loading_status import LoadingStatus
|
|||||||
from .installation_chooser import InstallationChooser
|
from .installation_chooser import InstallationChooser
|
||||||
import subprocess, re
|
import subprocess, re
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/add_remote_dialog.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/add_remote_dialog.ui")
|
||||||
class AddRemoteDialog(Adw.Dialog):
|
class AddRemoteDialog(Adw.Dialog):
|
||||||
__gtype_name__ = "AddRemoteDialog"
|
__gtype_name__ = "AddRemoteDialog"
|
||||||
@@ -24,12 +25,15 @@ class AddRemoteDialog(Adw.Dialog):
|
|||||||
self.parent_page.status_stack.set_visible_child(self.parent_page.adding_view)
|
self.parent_page.status_stack.set_visible_child(self.parent_page.adding_view)
|
||||||
self.apply_button.set_sensitive(False)
|
self.apply_button.set_sensitive(False)
|
||||||
error = [None]
|
error = [None]
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
HostInfo.main_window.add_refresh_lockout("adding remote")
|
HostInfo.main_window.add_refresh_lockout("adding remote")
|
||||||
cmd = [
|
cmd = [
|
||||||
'flatpak-spawn', '--host',
|
"flatpak-spawn",
|
||||||
'flatpak', 'remote-add',
|
"--host",
|
||||||
f'--title={self.title_row.get_text()}',
|
"flatpak",
|
||||||
|
"remote-add",
|
||||||
|
f"--title={self.title_row.get_text()}",
|
||||||
self.name_row.get_text(),
|
self.name_row.get_text(),
|
||||||
self.url_row.get_text(),
|
self.url_row.get_text(),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ from .host_info import HostInfo
|
|||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/remote_row.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/remote_row.ui")
|
||||||
class RemoteRow(Adw.ActionRow):
|
class RemoteRow(Adw.ActionRow):
|
||||||
__gtype_name__ = 'RemoteRow'
|
__gtype_name__ = "RemoteRow"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
suffix_label = gtc()
|
suffix_label = gtc()
|
||||||
@@ -25,8 +26,9 @@ class RemoteRow(Adw.ActionRow):
|
|||||||
return
|
return
|
||||||
|
|
||||||
has_error = []
|
has_error = []
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'remote-modify', '--enable', self.remote.name]
|
cmd = ["flatpak-spawn", "--host", "flatpak", "remote-modify", "--enable", self.remote.name]
|
||||||
if self.installation == "user" or self.installation == "system":
|
if self.installation == "user" or self.installation == "system":
|
||||||
cmd.append(f"--{self.installation}")
|
cmd.append(f"--{self.installation}")
|
||||||
else:
|
else:
|
||||||
@@ -95,7 +97,7 @@ class RemoteRow(Adw.ActionRow):
|
|||||||
self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not disable remote"), _("Remote is already disabled")).toast)
|
self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not disable remote"), _("Remote is already disabled")).toast)
|
||||||
return
|
return
|
||||||
|
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'remote-modify', '--disable', self.remote.name]
|
cmd = ["flatpak-spawn", "--host", "flatpak", "remote-modify", "--disable", self.remote.name]
|
||||||
if self.installation == "user" or self.installation == "system":
|
if self.installation == "user" or self.installation == "system":
|
||||||
cmd.append(f"--{self.installation}")
|
cmd.append(f"--{self.installation}")
|
||||||
else:
|
else:
|
||||||
@@ -118,7 +120,9 @@ class RemoteRow(Adw.ActionRow):
|
|||||||
|
|
||||||
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
||||||
|
|
||||||
dialog = Adw.AlertDialog(heading=_("Disable {}?").format(self.remote.title), body=_("Any installed apps from {} will stop receiving updates").format(self.remote.name))
|
dialog = Adw.AlertDialog(
|
||||||
|
heading=_("Disable {}?").format(self.remote.title), body=_("Any installed apps from {} will stop receiving updates").format(self.remote.name)
|
||||||
|
)
|
||||||
dialog.add_response("cancel", _("Cancel"))
|
dialog.add_response("cancel", _("Cancel"))
|
||||||
dialog.add_response("continue", _("Disable"))
|
dialog.add_response("continue", _("Disable"))
|
||||||
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
|
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from .add_remote_dialog import AddRemoteDialog
|
|||||||
from .loading_status import LoadingStatus
|
from .loading_status import LoadingStatus
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
class NewRemoteRow(Adw.ActionRow):
|
class NewRemoteRow(Adw.ActionRow):
|
||||||
__gtype_name__ = "NewRemoteRow"
|
__gtype_name__ = "NewRemoteRow"
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ class NewRemoteRow(Adw.ActionRow):
|
|||||||
GLib.idle_add(self.idle_stuff)
|
GLib.idle_add(self.idle_stuff)
|
||||||
self.set_activatable(True)
|
self.set_activatable(True)
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/remotes_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/remotes_page.ui")
|
||||||
class RemotesPage(Adw.NavigationPage):
|
class RemotesPage(Adw.NavigationPage):
|
||||||
# Preselected Remotes
|
# Preselected Remotes
|
||||||
@@ -28,7 +30,7 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
"title": "AppCenter",
|
"title": "AppCenter",
|
||||||
"name": "appcenter",
|
"name": "appcenter",
|
||||||
"link": "https://flatpak.elementary.io/repo.flatpakrepo",
|
"link": "https://flatpak.elementary.io/repo.flatpakrepo",
|
||||||
"description": _("The open source, pay-what-you-want app store from elementary")
|
"description": _("The open source, pay-what-you-want app store from elementary"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Flathub",
|
"title": "Flathub",
|
||||||
@@ -59,10 +61,10 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
"name": "webkit-sdk",
|
"name": "webkit-sdk",
|
||||||
"link": "https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo",
|
"link": "https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo",
|
||||||
"description": _("Central repository of the WebKit Developer and Runtime SDK"),
|
"description": _("Central repository of the WebKit Developer and Runtime SDK"),
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
__gtype_name__ = 'RemotesPage'
|
__gtype_name__ = "RemotesPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
search_button = gtc()
|
search_button = gtc()
|
||||||
@@ -87,8 +89,8 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
content_page = gtc()
|
content_page = gtc()
|
||||||
|
|
||||||
# Referred to in the main window
|
# Referred to in the main window
|
||||||
# It is used to determine if a new page should be made or not
|
# It is used to determine if a new page should be made or not
|
||||||
# This must be set to the created object from within the class's __init__ method
|
# This must be set to the created object from within the class's __init__ method
|
||||||
instance = None
|
instance = None
|
||||||
page_name = "remotes"
|
page_name = "remotes"
|
||||||
|
|
||||||
@@ -152,9 +154,10 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
def remove_remote(self, row):
|
def remove_remote(self, row):
|
||||||
error = [None]
|
error = [None]
|
||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
install = row.installation
|
install = row.installation
|
||||||
cmd = ['flatpak-spawn', '--host', 'flatpak', 'remote-delete', row.remote.name, '--force']
|
cmd = ["flatpak-spawn", "--host", "flatpak", "remote-delete", row.remote.name, "--force"]
|
||||||
if install == "user" or install == "system":
|
if install == "user" or install == "system":
|
||||||
cmd.append(f"--{install}")
|
cmd.append(f"--{install}")
|
||||||
else:
|
else:
|
||||||
@@ -184,7 +187,9 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
|
|
||||||
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
Gio.Task.new(None, None, callback).run_in_thread(thread)
|
||||||
|
|
||||||
dialog = Adw.AlertDialog(heading=_("Remove {}?").format(row.remote.title), body=_("Any installed apps from {} will stop receiving updates").format(row.remote.name))
|
dialog = Adw.AlertDialog(
|
||||||
|
heading=_("Remove {}?").format(row.remote.title), body=_("Any installed apps from {} will stop receiving updates").format(row.remote.name)
|
||||||
|
)
|
||||||
dialog.add_response("cancel", _("Cancel"))
|
dialog.add_response("cancel", _("Cancel"))
|
||||||
dialog.add_response("continue", _("Remove"))
|
dialog.add_response("continue", _("Remove"))
|
||||||
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
|
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
|
||||||
@@ -250,7 +255,7 @@ class RemotesPage(Adw.NavigationPage):
|
|||||||
total_visible = 0
|
total_visible = 0
|
||||||
for row in self.current_remote_rows:
|
for row in self.current_remote_rows:
|
||||||
if row.remote.disabled:
|
if row.remote.disabled:
|
||||||
if show_disabled: # show disabled
|
if show_disabled: # show disabled
|
||||||
row.set_visible(True)
|
row.set_visible(True)
|
||||||
total_visible += 1
|
total_visible += 1
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .app_row import AppRow
|
|||||||
from .tar_worker import TarWorker
|
from .tar_worker import TarWorker
|
||||||
import os, time
|
import os, time
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/new_snapshot_dialog.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/new_snapshot_dialog.ui")
|
||||||
class NewSnapshotDialog(Adw.Dialog):
|
class NewSnapshotDialog(Adw.Dialog):
|
||||||
__gtype_name__ = "NewSnapshotDialog"
|
__gtype_name__ = "NewSnapshotDialog"
|
||||||
@@ -76,7 +77,7 @@ class NewSnapshotDialog(Adw.Dialog):
|
|||||||
def valid_checker(self):
|
def valid_checker(self):
|
||||||
text = self.name_entry.get_text().strip()
|
text = self.name_entry.get_text().strip()
|
||||||
something_selected = len(self.selected_rows) > 0
|
something_selected = len(self.selected_rows) > 0
|
||||||
text_good = len(text) > 0 and not("/" in text or "\0" in text)
|
text_good = len(text) > 0 and not ("/" in text or "\0" in text)
|
||||||
self.create_button.set_sensitive(something_selected and text_good)
|
self.create_button.set_sensitive(something_selected and text_good)
|
||||||
if text_good:
|
if text_good:
|
||||||
self.name_entry.remove_css_class("error")
|
self.name_entry.remove_css_class("error")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from .error_toast import ErrorToast
|
|||||||
from .tar_worker import TarWorker
|
from .tar_worker import TarWorker
|
||||||
import os, subprocess, json
|
import os, subprocess, json
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshot_box.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshot_box.ui")
|
||||||
class SnapshotBox(Gtk.Box):
|
class SnapshotBox(Gtk.Box):
|
||||||
__gtype_name__ = "SnapshotBox"
|
__gtype_name__ = "SnapshotBox"
|
||||||
@@ -22,10 +23,10 @@ class SnapshotBox(Gtk.Box):
|
|||||||
def create_json(self):
|
def create_json(self):
|
||||||
try:
|
try:
|
||||||
data = {
|
data = {
|
||||||
'snapshot_version': 1,
|
"snapshot_version": 1,
|
||||||
'name': '',
|
"name": "",
|
||||||
}
|
}
|
||||||
with open(self.json_path, 'w') as file:
|
with open(self.json_path, "w") as file:
|
||||||
json.dump(data, file, indent=4)
|
json.dump(data, file, indent=4)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ class SnapshotBox(Gtk.Box):
|
|||||||
|
|
||||||
def update_json(self, key, value):
|
def update_json(self, key, value):
|
||||||
try:
|
try:
|
||||||
with open(self.json_path, 'r+') as file:
|
with open(self.json_path, "r+") as file:
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
data[key] = value
|
data[key] = value
|
||||||
file.seek(0)
|
file.seek(0)
|
||||||
@@ -49,9 +50,9 @@ class SnapshotBox(Gtk.Box):
|
|||||||
self.create_json()
|
self.create_json()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.json_path, 'r') as file:
|
with open(self.json_path, "r") as file:
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
name = data['name']
|
name = data["name"]
|
||||||
if name != "":
|
if name != "":
|
||||||
self.title.set_label(GLib.markup_escape_text(name))
|
self.title.set_label(GLib.markup_escape_text(name))
|
||||||
else:
|
else:
|
||||||
@@ -64,7 +65,7 @@ class SnapshotBox(Gtk.Box):
|
|||||||
if not self.valid_checker():
|
if not self.valid_checker():
|
||||||
return
|
return
|
||||||
|
|
||||||
self.update_json('name', self.rename_entry.get_text().strip())
|
self.update_json("name", self.rename_entry.get_text().strip())
|
||||||
self.load_from_json()
|
self.load_from_json()
|
||||||
self.rename_menu.popdown()
|
self.rename_menu.popdown()
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ class SnapshotBox(Gtk.Box):
|
|||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash', path], capture_output=True, text=True, check=True)
|
subprocess.run(["gio", "trash", path], capture_output=True, text=True, check=True)
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
error[0] = cpe.stderr
|
error[0] = cpe.stderr
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -130,9 +131,9 @@ class SnapshotBox(Gtk.Box):
|
|||||||
if self.worker in self.snapshot_page.workers:
|
if self.worker in self.snapshot_page.workers:
|
||||||
self.snapshot_page.workers.remove(self.worker)
|
self.snapshot_page.workers.remove(self.worker)
|
||||||
|
|
||||||
return False # Stop the timeout
|
return False # Stop the timeout
|
||||||
else:
|
else:
|
||||||
return True # Continue the timeout
|
return True # Continue the timeout
|
||||||
|
|
||||||
def on_apply(self, button):
|
def on_apply(self, button):
|
||||||
def on_response(dialog, response):
|
def on_response(dialog, response):
|
||||||
@@ -162,14 +163,14 @@ class SnapshotBox(Gtk.Box):
|
|||||||
|
|
||||||
self.snapshot_page = parent_page.parent_page
|
self.snapshot_page = parent_page.parent_page
|
||||||
self.toast_overlay = toast_overlay
|
self.toast_overlay = toast_overlay
|
||||||
self.app_id = snapshots_path.split('/')[-2].strip()
|
self.app_id = snapshots_path.split("/")[-2].strip()
|
||||||
self.worker = TarWorker(
|
self.worker = TarWorker(
|
||||||
existing_path=f"{snapshots_path}{folder}",
|
existing_path=f"{snapshots_path}{folder}",
|
||||||
new_path=f"{HostInfo.home}/.var/app/{self.app_id}/",
|
new_path=f"{HostInfo.home}/.var/app/{self.app_id}/",
|
||||||
toast_overlay=self.toast_overlay,
|
toast_overlay=self.toast_overlay,
|
||||||
)
|
)
|
||||||
|
|
||||||
split_folder = folder.split('_')
|
split_folder = folder.split("_")
|
||||||
if len(split_folder) < 2:
|
if len(split_folder) < 2:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from .tar_worker import TarWorker
|
|||||||
from .attempt_install_dialog import AttemptInstallDialog
|
from .attempt_install_dialog import AttemptInstallDialog
|
||||||
import os, subprocess
|
import os, subprocess
|
||||||
|
|
||||||
|
|
||||||
class LeftoverSnapshotRow(Adw.ActionRow):
|
class LeftoverSnapshotRow(Adw.ActionRow):
|
||||||
__gtype_name__ = "LeftoverSnapshotRow"
|
__gtype_name__ = "LeftoverSnapshotRow"
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ class LeftoverSnapshotRow(Adw.ActionRow):
|
|||||||
self.add_controller(self.rclick_gesture)
|
self.add_controller(self.rclick_gesture)
|
||||||
self.add_controller(self.long_press_gesture)
|
self.add_controller(self.long_press_gesture)
|
||||||
self.check_button.add_css_class("selection-mode")
|
self.check_button.add_css_class("selection-mode")
|
||||||
self.name = self.folder.split('.')[-1]
|
self.name = self.folder.split(".")[-1]
|
||||||
self.set_activatable(True)
|
self.set_activatable(True)
|
||||||
GLib.idle_add(lambda *_: self.idle_stuff())
|
GLib.idle_add(lambda *_: self.idle_stuff())
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ class LeftoverSnapshotRow(Adw.ActionRow):
|
|||||||
self.rclick_gesture.connect("released", self.gesture_handler)
|
self.rclick_gesture.connect("released", self.gesture_handler)
|
||||||
self.long_press_gesture.connect("pressed", self.gesture_handler)
|
self.long_press_gesture.connect("pressed", self.gesture_handler)
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshot_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshot_page.ui")
|
||||||
class SnapshotPage(Adw.BreakpointBin):
|
class SnapshotPage(Adw.BreakpointBin):
|
||||||
__gtype_name__ = "SnapshotPage"
|
__gtype_name__ = "SnapshotPage"
|
||||||
@@ -82,8 +84,8 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
trash_snapshots = gtc()
|
trash_snapshots = gtc()
|
||||||
|
|
||||||
# Referred to in the main window
|
# Referred to in the main window
|
||||||
# It is used to determine if a new page should be made or not
|
# It is used to determine if a new page should be made or not
|
||||||
# This must be set to the created object from within the class's __init__ method
|
# This must be set to the created object from within the class's __init__ method
|
||||||
instance = None
|
instance = None
|
||||||
page_name = "snapshots"
|
page_name = "snapshots"
|
||||||
is_trash_dialog_open = False
|
is_trash_dialog_open = False
|
||||||
@@ -102,7 +104,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for folder in os.listdir(HostInfo.snapshots_path):
|
for folder in os.listdir(HostInfo.snapshots_path):
|
||||||
if folder.count('.') < 2 or ' ' in folder:
|
if folder.count(".") < 2 or " " in folder:
|
||||||
bad_folders.append(folder)
|
bad_folders.append(folder)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -124,7 +126,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
|
|
||||||
for folder in bad_folders:
|
for folder in bad_folders:
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash', f'{HostInfo.snapshots_path}{folder}'])
|
subprocess.run(["gio", "trash", f"{HostInfo.snapshots_path}{folder}"])
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -191,11 +193,11 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
if row.package is package:
|
if row.package is package:
|
||||||
self.active_listbox.select_row(row)
|
self.active_listbox.select_row(row)
|
||||||
self.active_select_handler(None, row, True)
|
self.active_select_handler(None, row, True)
|
||||||
self.toast_overlay.add_toast(Adw.Toast(title=_("Showing snapshots for {}").format(package.info['name'])))
|
self.toast_overlay.add_toast(Adw.Toast(title=_("Showing snapshots for {}").format(package.info["name"])))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
dialog = NewSnapshotDialog(self, self.snapshotting_status, self.refresh, [package])
|
dialog = NewSnapshotDialog(self, self.snapshotting_status, self.refresh, [package])
|
||||||
toast = Adw.Toast(title=_("No snapshots for {}").format(package.info['name']), button_label=_("New"))
|
toast = Adw.Toast(title=_("No snapshots for {}").format(package.info["name"]), button_label=_("New"))
|
||||||
toast.connect("button-clicked", lambda *_: dialog.present(HostInfo.main_window))
|
toast.connect("button-clicked", lambda *_: dialog.present(HostInfo.main_window))
|
||||||
self.toast_overlay.add_toast(toast)
|
self.toast_overlay.add_toast(toast)
|
||||||
|
|
||||||
@@ -225,7 +227,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
|
|
||||||
data_exists = False
|
data_exists = False
|
||||||
for package in HostInfo.flatpaks:
|
for package in HostInfo.flatpaks:
|
||||||
if package.info['id'] == "io.github.flattool.Warehouse":
|
if package.info["id"] == "io.github.flattool.Warehouse":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if os.path.exists(package.data_path):
|
if os.path.exists(package.data_path):
|
||||||
@@ -299,7 +301,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
|
|
||||||
def sort_func(self, row1, row2):
|
def sort_func(self, row1, row2):
|
||||||
if type(row1) is AppRow:
|
if type(row1) is AppRow:
|
||||||
return row1.package.info['name'].lower() > row2.package.info['name'].lower()
|
return row1.package.info["name"].lower() > row2.package.info["name"].lower()
|
||||||
else:
|
else:
|
||||||
return row1.name.lower() > row2.name.lower()
|
return row1.name.lower() > row2.name.lower()
|
||||||
|
|
||||||
@@ -441,7 +443,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
|
|
||||||
app_ids = []
|
app_ids = []
|
||||||
for row in self.selected_active_rows:
|
for row in self.selected_active_rows:
|
||||||
app_ids.append(row.package.info['id'])
|
app_ids.append(row.package.info["id"])
|
||||||
|
|
||||||
for row in self.selected_leftover_rows:
|
for row in self.selected_leftover_rows:
|
||||||
app_ids.append(row.folder)
|
app_ids.append(row.folder)
|
||||||
@@ -450,7 +452,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
for app_id in id_to_tar:
|
for app_id in id_to_tar:
|
||||||
biggest = 0
|
biggest = 0
|
||||||
for tar in id_to_tar[app_id]:
|
for tar in id_to_tar[app_id]:
|
||||||
epoch = int(tar.split('_')[0])
|
epoch = int(tar.split("_")[0])
|
||||||
if epoch > biggest:
|
if epoch > biggest:
|
||||||
biggest = epoch
|
biggest = epoch
|
||||||
|
|
||||||
@@ -489,10 +491,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
AttemptInstallDialog(package_names, lambda is_valid: self.select_button.set_active(not is_valid))
|
AttemptInstallDialog(package_names, lambda is_valid: self.select_button.set_active(not is_valid))
|
||||||
|
|
||||||
def selection_trash_handler(self):
|
def selection_trash_handler(self):
|
||||||
if (
|
if len(self.selected_active_rows) + len(self.selected_leftover_rows) < 1 or self.is_trash_dialog_open:
|
||||||
len(self.selected_active_rows) + len(self.selected_leftover_rows) < 1
|
|
||||||
or self.is_trash_dialog_open
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_response(dialog, response):
|
def on_response(dialog, response):
|
||||||
@@ -508,7 +507,7 @@ class SnapshotPage(Adw.BreakpointBin):
|
|||||||
to_trash.append(f"{HostInfo.snapshots_path}{row.folder}")
|
to_trash.append(f"{HostInfo.snapshots_path}{row.folder}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash'] + to_trash, check=True, text=True, capture_output=True)
|
subprocess.run(["gio", "trash"] + to_trash, check=True, text=True, capture_output=True)
|
||||||
self.start_loading()
|
self.start_loading()
|
||||||
self.end_loading()
|
self.end_loading()
|
||||||
self.toast_overlay.add_toast(Adw.Toast(title=_("Trashed snapshots")))
|
self.toast_overlay.add_toast(Adw.Toast(title=_("Trashed snapshots")))
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from .loading_status import LoadingStatus
|
|||||||
from .new_snapshot_dialog import NewSnapshotDialog
|
from .new_snapshot_dialog import NewSnapshotDialog
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshots_list_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshots_list_page.ui")
|
||||||
class SnapshotsListPage(Adw.NavigationPage):
|
class SnapshotsListPage(Adw.NavigationPage):
|
||||||
__gtype_name__ = "SnapshotsListPage"
|
__gtype_name__ = "SnapshotsListPage"
|
||||||
|
|||||||
@@ -3,30 +3,30 @@ from .host_info import HostInfo
|
|||||||
from .error_toast import ErrorToast
|
from .error_toast import ErrorToast
|
||||||
import os, subprocess, json
|
import os, subprocess, json
|
||||||
|
|
||||||
|
|
||||||
class TarWorker:
|
class TarWorker:
|
||||||
def compress_thread(self, *args):
|
def compress_thread(self, *args):
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(self.new_path):
|
if not os.path.exists(self.new_path):
|
||||||
os.makedirs(self.new_path)
|
os.makedirs(self.new_path)
|
||||||
|
|
||||||
self.total = int(subprocess.run(['du', '-s', self.existing_path], check=True, text=True, capture_output=True).stdout.split('\t')[0])
|
self.total = int(subprocess.run(["du", "-s", self.existing_path], check=True, text=True, capture_output=True).stdout.split("\t")[0])
|
||||||
self.total /= 2.2 # estimate for space savings
|
self.total /= 2.2 # estimate for space savings
|
||||||
self.process = subprocess.Popen(['tar', 'cafv', f'{self.new_path}/{self.file_name}.tar.zst', '-C', self.existing_path, '.'],
|
self.process = subprocess.Popen(
|
||||||
stdout=subprocess.PIPE,
|
["tar", "cafv", f"{self.new_path}/{self.file_name}.tar.zst", "-C", self.existing_path, "."], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
stderr=subprocess.PIPE
|
|
||||||
)
|
)
|
||||||
stdout, stderr = self.process.communicate()
|
stdout, stderr = self.process.communicate()
|
||||||
if self.process.returncode != 0:
|
if self.process.returncode != 0:
|
||||||
raise subprocess.CalledProcessError(self.process.returncode, self.process.args, output=stdout, stderr=stderr)
|
raise subprocess.CalledProcessError(self.process.returncode, self.process.args, output=stdout, stderr=stderr)
|
||||||
|
|
||||||
with open(f"{self.new_path}/{self.file_name}.json", 'w') as file:
|
with open(f"{self.new_path}/{self.file_name}.json", "w") as file:
|
||||||
data = {
|
data = {
|
||||||
'snapshot_version': 1,
|
"snapshot_version": 1,
|
||||||
'name': self.name,
|
"name": self.name,
|
||||||
}
|
}
|
||||||
json.dump(data, file, indent=4)
|
json.dump(data, file, indent=4)
|
||||||
|
|
||||||
self.stop = True # tell the check timeout to stop, because we know the file is done being made
|
self.stop = True # tell the check timeout to stop, because we know the file is done being made
|
||||||
HostInfo.main_window.remove_refresh_lockout("managing snapshot")
|
HostInfo.main_window.remove_refresh_lockout("managing snapshot")
|
||||||
|
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
@@ -38,21 +38,20 @@ class TarWorker:
|
|||||||
def extract_thread(self, *args):
|
def extract_thread(self, *args):
|
||||||
try:
|
try:
|
||||||
if os.path.exists(self.new_path):
|
if os.path.exists(self.new_path):
|
||||||
subprocess.run(['gio', 'trash', self.new_path], capture_output=True, check=True) # trash the current user data, because new data will go in its place
|
subprocess.run(
|
||||||
|
["gio", "trash", self.new_path], capture_output=True, check=True
|
||||||
|
) # trash the current user data, because new data will go in its place
|
||||||
|
|
||||||
os.makedirs(self.new_path) # create the new user data path
|
os.makedirs(self.new_path) # create the new user data path
|
||||||
|
|
||||||
self.total = int(subprocess.run(['du', '-s', self.existing_path], check=True, text=True, capture_output=True).stdout.split('\t')[0])
|
self.total = int(subprocess.run(["du", "-s", self.existing_path], check=True, text=True, capture_output=True).stdout.split("\t")[0])
|
||||||
self.total *= 2.2 # estimate from space savings
|
self.total *= 2.2 # estimate from space savings
|
||||||
self.process = subprocess.Popen(['tar', '--zstd', '-xvf', self.existing_path, '-C', self.new_path],
|
self.process = subprocess.Popen(["tar", "--zstd", "-xvf", self.existing_path, "-C", self.new_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE
|
|
||||||
)
|
|
||||||
stdout, stderr = self.process.communicate()
|
stdout, stderr = self.process.communicate()
|
||||||
if self.process.returncode != 0:
|
if self.process.returncode != 0:
|
||||||
raise subprocess.CalledProcessError(self.process.returncode, self.process.args, output=stdout, stderr=stderr)
|
raise subprocess.CalledProcessError(self.process.returncode, self.process.args, output=stdout, stderr=stderr)
|
||||||
|
|
||||||
self.stop = True # tell the check timeout to stop, because we know the file is done being made
|
self.stop = True # tell the check timeout to stop, because we know the file is done being made
|
||||||
HostInfo.main_window.remove_refresh_lockout("managing snapshot")
|
HostInfo.main_window.remove_refresh_lockout("managing snapshot")
|
||||||
|
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError as cpe:
|
||||||
@@ -70,7 +69,7 @@ class TarWorker:
|
|||||||
self.process.wait()
|
self.process.wait()
|
||||||
if len(self.files_to_trash_on_cancel) > 0:
|
if len(self.files_to_trash_on_cancel) > 0:
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash'] + self.files_to_trash_on_cancel, capture_output=True, check=True)
|
subprocess.run(["gio", "trash"] + self.files_to_trash_on_cancel, capture_output=True, check=True)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@@ -82,17 +81,17 @@ class TarWorker:
|
|||||||
|
|
||||||
def check_size(self, check_path):
|
def check_size(self, check_path):
|
||||||
try:
|
try:
|
||||||
output = subprocess.run(['du', '-s', check_path], check=True, text=True, capture_output=True).stdout.split('\t')[0]
|
output = subprocess.run(["du", "-s", check_path], check=True, text=True, capture_output=True).stdout.split("\t")[0]
|
||||||
working_total = float(output)
|
working_total = float(output)
|
||||||
self.fraction = working_total / self.total
|
self.fraction = working_total / self.total
|
||||||
return not self.stop
|
return not self.stop
|
||||||
|
|
||||||
except subprocess.CalledProcessError as cpe:
|
except subprocess.CalledProcessError:
|
||||||
return not self.stop # continue the timeout or stop the timeout
|
return not self.stop # continue the timeout or stop the timeout
|
||||||
|
|
||||||
def compress(self):
|
def compress(self):
|
||||||
self.stop = False
|
self.stop = False
|
||||||
self.files_to_trash_on_cancel = [f'{self.new_path}/{self.file_name}.tar.zst', f'{self.new_path}/{self.file_name}.json']
|
self.files_to_trash_on_cancel = [f"{self.new_path}/{self.file_name}.tar.zst", f"{self.new_path}/{self.file_name}.json"]
|
||||||
HostInfo.main_window.add_refresh_lockout("managing snapshot")
|
HostInfo.main_window.add_refresh_lockout("managing snapshot")
|
||||||
Gio.Task.new(None, None, None).run_in_thread(self.compress_thread)
|
Gio.Task.new(None, None, None).run_in_thread(self.compress_thread)
|
||||||
GLib.timeout_add(200, self.check_size, f"{self.new_path}/{self.file_name}.tar.zst")
|
GLib.timeout_add(200, self.check_size, f"{self.new_path}/{self.file_name}.tar.zst")
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ from .error_toast import ErrorToast
|
|||||||
from .attempt_install_dialog import AttemptInstallDialog
|
from .attempt_install_dialog import AttemptInstallDialog
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_box.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_box.ui")
|
||||||
class DataBox(Gtk.ListBox):
|
class DataBox(Gtk.ListBox):
|
||||||
__gtype_name__ = 'DataBox'
|
__gtype_name__ = "DataBox"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
row = gtc()
|
row = gtc()
|
||||||
@@ -24,7 +25,7 @@ class DataBox(Gtk.ListBox):
|
|||||||
|
|
||||||
def human_readable_size(self):
|
def human_readable_size(self):
|
||||||
working_size = self.size
|
working_size = self.size
|
||||||
units = ['KB', 'MB', 'GB', 'TB']
|
units = ["KB", "MB", "GB", "TB"]
|
||||||
# size *= 1024
|
# size *= 1024
|
||||||
for unit in units:
|
for unit in units:
|
||||||
if working_size < 1024:
|
if working_size < 1024:
|
||||||
@@ -33,7 +34,7 @@ class DataBox(Gtk.ListBox):
|
|||||||
return f"~ {round(working_size)} PB"
|
return f"~ {round(working_size)} PB"
|
||||||
|
|
||||||
def get_size(self, *args):
|
def get_size(self, *args):
|
||||||
self.size = int(subprocess.run(['du', '-s', self.data_path], capture_output=True, text=True).stdout.split("\t")[0])
|
self.size = int(subprocess.run(["du", "-s", self.data_path], capture_output=True, text=True).stdout.split("\t")[0])
|
||||||
|
|
||||||
def show_size(self):
|
def show_size(self):
|
||||||
def callback(*args):
|
def callback(*args):
|
||||||
@@ -68,6 +69,7 @@ class DataBox(Gtk.ListBox):
|
|||||||
|
|
||||||
def install_handler(self, *args):
|
def install_handler(self, *args):
|
||||||
self.parent_page.should_rclick = False
|
self.parent_page.should_rclick = False
|
||||||
|
|
||||||
def why_cant_this_just_be_a_lambda(*args):
|
def why_cant_this_just_be_a_lambda(*args):
|
||||||
self.parent_page.should_rclick = True
|
self.parent_page.should_rclick = True
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ class DataBox(Gtk.ListBox):
|
|||||||
|
|
||||||
def thread(*args):
|
def thread(*args):
|
||||||
try:
|
try:
|
||||||
subprocess.run(['gio', 'trash', self.data_path], check=True, text=True, capture_output=True)
|
subprocess.run(["gio", "trash", self.data_path], check=True, text=True, capture_output=True)
|
||||||
properties_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].properties_page
|
properties_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].properties_page
|
||||||
properties_package = properties_page.package
|
properties_package = properties_page.package
|
||||||
if not properties_package is None:
|
if not properties_package is None:
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ from .host_info import HostInfo
|
|||||||
from .data_box import DataBox
|
from .data_box import DataBox
|
||||||
from .loading_status import LoadingStatus
|
from .loading_status import LoadingStatus
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_subpage.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_subpage.ui")
|
||||||
class DataSubpage(Gtk.Stack):
|
class DataSubpage(Gtk.Stack):
|
||||||
__gtype_name__ = 'DataSubpage'
|
__gtype_name__ = "DataSubpage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
scrolled_window = gtc()
|
scrolled_window = gtc()
|
||||||
@@ -25,7 +26,7 @@ class DataSubpage(Gtk.Stack):
|
|||||||
|
|
||||||
def human_readable_size(self):
|
def human_readable_size(self):
|
||||||
working_size = self.total_size
|
working_size = self.total_size
|
||||||
units = ['KB', 'MB', 'GB', 'TB']
|
units = ["KB", "MB", "GB", "TB"]
|
||||||
# size *= 1024
|
# size *= 1024
|
||||||
for unit in units:
|
for unit in units:
|
||||||
if working_size < 1024:
|
if working_size < 1024:
|
||||||
@@ -35,6 +36,7 @@ class DataSubpage(Gtk.Stack):
|
|||||||
|
|
||||||
def sort_func(self, box1, box2):
|
def sort_func(self, box1, box2):
|
||||||
import random
|
import random
|
||||||
|
|
||||||
# print(random.randint(1, 100), self.sort_mode, self.sort_ascend)
|
# print(random.randint(1, 100), self.sort_mode, self.sort_ascend)
|
||||||
i1 = None
|
i1 = None
|
||||||
i2 = None
|
i2 = None
|
||||||
@@ -138,14 +140,34 @@ class DataSubpage(Gtk.Stack):
|
|||||||
self.should_rclick = True
|
self.should_rclick = True
|
||||||
if flatpaks:
|
if flatpaks:
|
||||||
for i, pak in enumerate(flatpaks):
|
for i, pak in enumerate(flatpaks):
|
||||||
box = DataBox(self, self.parent_page.toast_overlay, False, pak.info["name"], pak.info["id"], pak.data_path, pak.icon_path, self.box_size_callback, self.trash_handler)
|
box = DataBox(
|
||||||
|
self,
|
||||||
|
self.parent_page.toast_overlay,
|
||||||
|
False,
|
||||||
|
pak.info["name"],
|
||||||
|
pak.info["id"],
|
||||||
|
pak.data_path,
|
||||||
|
pak.icon_path,
|
||||||
|
self.box_size_callback,
|
||||||
|
self.trash_handler,
|
||||||
|
)
|
||||||
box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box))
|
box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box))
|
||||||
self.boxes.append(box)
|
self.boxes.append(box)
|
||||||
self.flow_box.append(box)
|
self.flow_box.append(box)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for i, folder in enumerate(data):
|
for i, folder in enumerate(data):
|
||||||
box = DataBox(self, self.parent_page.toast_overlay, True, folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}", None, self.box_size_callback, self.trash_handler)
|
box = DataBox(
|
||||||
|
self,
|
||||||
|
self.parent_page.toast_overlay,
|
||||||
|
True,
|
||||||
|
folder.split(".")[-1],
|
||||||
|
folder,
|
||||||
|
f"{HostInfo.home}/.var/app/{folder}",
|
||||||
|
None,
|
||||||
|
self.box_size_callback,
|
||||||
|
self.trash_handler,
|
||||||
|
)
|
||||||
box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box))
|
box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box))
|
||||||
self.flow_box.append(box)
|
self.flow_box.append(box)
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ from .loading_status import LoadingStatus
|
|||||||
from .attempt_install_dialog import AttemptInstallDialog
|
from .attempt_install_dialog import AttemptInstallDialog
|
||||||
import os, subprocess
|
import os, subprocess
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/user_data_page.ui")
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/user_data_page.ui")
|
||||||
class UserDataPage(Adw.BreakpointBin):
|
class UserDataPage(Adw.BreakpointBin):
|
||||||
__gtype_name__ = 'UserDataPage'
|
__gtype_name__ = "UserDataPage"
|
||||||
gtc = Gtk.Template.Child
|
gtc = Gtk.Template.Child
|
||||||
|
|
||||||
bpt = gtc()
|
bpt = gtc()
|
||||||
@@ -44,8 +45,8 @@ class UserDataPage(Adw.BreakpointBin):
|
|||||||
more_install = gtc()
|
more_install = gtc()
|
||||||
|
|
||||||
# Referred to in the main window
|
# Referred to in the main window
|
||||||
# It is used to determine if a new page should be made or not
|
# It is used to determine if a new page should be made or not
|
||||||
# This must be set to the created object from within the class's __init__ method
|
# This must be set to the created object from within the class's __init__ method
|
||||||
instance = None
|
instance = None
|
||||||
page_name = "user-data"
|
page_name = "user-data"
|
||||||
data_path = f"{HostInfo.home}/.var/app"
|
data_path = f"{HostInfo.home}/.var/app"
|
||||||
@@ -158,7 +159,7 @@ class UserDataPage(Adw.BreakpointBin):
|
|||||||
child = self.stack.get_visible_child()
|
child = self.stack.get_visible_child()
|
||||||
|
|
||||||
def thread(path):
|
def thread(path):
|
||||||
cmd = ['gio', 'trash'] + path
|
cmd = ["gio", "trash"] + path
|
||||||
try:
|
try:
|
||||||
subprocess.run(cmd, check=True, capture_output=True, text=True)
|
subprocess.run(cmd, check=True, capture_output=True, text=True)
|
||||||
properties_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].properties_page
|
properties_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].properties_page
|
||||||
|
|||||||
Reference in New Issue
Block a user