from gi.repository import Adw, Gtk, GLib, Gio from .host_info import HostInfo from .error_toast import ErrorToast import subprocess @Gtk.Template(resource_path="/io/github/flattool/Warehouse/remotes_page/remote_row.ui") class RemoteRow(Adw.ActionRow): __gtype_name__ = 'RemoteRow' gtc = Gtk.Template.Child suffix_label = gtc() filter_button = gtc() menu_pop = gtc() menu_listbox = gtc() copy_title = gtc() copy_name = gtc() enable_remote = gtc() disable_remote = gtc() remove = gtc() def enable_remote_handler(self, *args): if not self.remote.disabled: self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not enable remote"), _("Remote is already enabled")).toast) return has_error = [] def thread(*args): cmd = ['flatpak-spawn', '--host', 'flatpak', 'remote-modify', '--enable', self.remote.name] if self.installation == "user" or self.installation == "system": cmd.append(f"--{self.installation}") else: cmd.append(f"--installation={self.installation}") try: subprocess.run(cmd, check=True, capture_output=True, text=True) except subprocess.CalledProcessError as cpe: has_error.append(str(cpe.stderr)) except Exception as e: has_error.append(str(e)) def callback(*args): if len(has_error) > 0: GLib.idle_add(lambda *args, cpe=cpe: self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not enable remote"), has_error[0]).toast)) return self.remove_css_class("warning") self.set_icon_name("") self.set_tooltip_text("") self.remote.disabled = False self.parent_page.toast_overlay.add_toast(Adw.Toast(title=_("Enabled remote"))) self.menu_listbox.get_row_at_index(2).set_visible(False) self.menu_listbox.get_row_at_index(3).set_visible(True) self.parent_page.total_disabled -= 1 install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row] install_page.start_loading() install_page.end_loading() filters_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].filters_page filters_page.generate_filters() if self.parent_page.total_disabled == 0: self.parent_page.show_disabled_button.set_active(False) self.parent_page.show_disabled_button.set_visible(False) Gio.Task.new(None, None, callback).run_in_thread(thread) def disable_remote_handler(self, *args): error = [None] def callback(*args): if error[0]: return self.add_css_class("warning") self.set_icon_name("error-symbolic") self.set_tooltip_text(_("Remote is Disabled")) self.remote.disabled = True self.parent_page.toast_overlay.add_toast(Adw.Toast(title=_("Disabled remote"))) self.menu_listbox.get_row_at_index(2).set_visible(True) self.menu_listbox.get_row_at_index(3).set_visible(False) self.set_visible(self.parent_page.show_disabled_button.get_active()) self.parent_page.show_disabled_button.set_visible(True) self.parent_page.total_disabled += 1 self.parent_page.none_visible_handler() install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row] install_page.start_loading() install_page.end_loading() filters_page = HostInfo.main_window.pages[HostInfo.main_window.packages_row].filters_page filters_page.settings.reset("remotes-list") filters_page.all_remotes_switch.set_active(False) filters_page.generate_filters() filters_page.packages_page.apply_filters() def thread(*args): if self.remote.disabled: self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not disable remote"), _("Remote is already disabled")).toast) return cmd = ['flatpak-spawn', '--host', 'flatpak', 'remote-modify', '--disable', self.remote.name] if self.installation == "user" or self.installation == "system": cmd.append(f"--{self.installation}") else: cmd.append(f"--installation={self.installation}") try: subprocess.run(cmd, check=True, capture_output=True, text=True) except subprocess.CalledProcessError as cpe: GLib.idle_add(lambda *args, cpe=cpe: self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not disable remote"), str(cpe.stderr)).toast)) error[0] = cpe return except Exception as e: GLib.idle_add(lambda *args, e=e: self.parent_page.toast_overlay.add_toast(ErrorToast(_("Could not disable remote"), str(e)).toast)) error[0] = e return def on_response(_, response): if response != "continue": return 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.add_response("cancel", _("Cancel")) dialog.add_response("continue", _("Disable")) dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE) dialog.connect("response", on_response) dialog.present(self.parent_page.main_window) def on_menu_action(self, listbox, row): row = row.get_child() match row: case self.copy_title: HostInfo.clipboard.set(self.remote.title) self.parent_page.toast_overlay.add_toast(Adw.Toast(title=_("Copied title"))) case self.copy_name: HostInfo.clipboard.set(self.remote.name) self.parent_page.toast_overlay.add_toast(Adw.Toast(title=_("Copied name"))) case self.enable_remote: self.enable_remote_handler() case self.disable_remote: self.disable_remote_handler() case self.remove: self.parent_page.remove_remote(self) self.menu_pop.popdown() def idle_stuff(self): self.set_title(self.remote.title) self.set_subtitle(_("Installation: {}").format(self.installation)) self.suffix_label.set_label(self.remote.name) if self.remote.disabled: self.set_icon_name("error-symbolic") self.add_css_class("warning") self.set_tooltip_text(_("Remote is Disabled")) def __init__(self, parent_page, installation, remote, **kwargs): super().__init__(**kwargs) # Extra Object Creation self.parent_page = parent_page self.remote = remote self.installation = installation # Apply GLib.idle_add(lambda *_: self.idle_stuff()) ## Show / Hide the Enable / Disable actions depending on remote status self.menu_listbox.get_row_at_index(2).set_visible(remote.disabled) self.menu_listbox.get_row_at_index(3).set_visible(not remote.disabled) # Connections self.menu_listbox.connect("row-activated", self.on_menu_action) self.filter_button.connect("clicked", lambda *_: parent_page.filter_remote(self))