diff --git a/io.github.flattool.Warehouse.json b/io.github.flattool.Warehouse.json index c06b077..fbd819e 100644 --- a/io.github.flattool.Warehouse.json +++ b/io.github.flattool.Warehouse.json @@ -12,7 +12,8 @@ "--talk-name=org.freedesktop.Flatpak", "--filesystem=/var/lib/flatpak/:ro", "--filesystem=~/.local/share/flatpak/:ro", - "--filesystem=~/.var/app/" + "--filesystem=~/.var/app/", + "--filesystem=host-etc" ], "cleanup" : [ "/include", diff --git a/src/host_info.py b/src/host_info.py new file mode 100644 index 0000000..f5f40bd --- /dev/null +++ b/src/host_info.py @@ -0,0 +1,130 @@ +import gi, subprocess, os, pathlib + +gi.require_version('Gtk', '4.0') + +from gi.repository import Gio, Gtk, GLib + +home = f"{pathlib.Path.home()}" +icon_theme = Gtk.IconTheme.new() +icon_theme.add_search_path(f"{home}/.local/share/flatpak/exports/share/icons") +direction = Gtk.Image().get_direction() + +class Flatpak: + def __init__(self, columns): + self.is_runtime = "runtime" in columns[12] + self.info = { + "name": columns[0], + "description": columns[1], + "id": columns[2], + "version": columns[3], + "branch": columns[4], + "arch": columns[5], + "origin": columns[6], + "ref": columns[8], + "installed_size": columns[11], + "options": columns[12], + } + self.data_path = f"{home}/{columns[2]}" + installation = columns[7] + if len(i := installation.split(' ')) > 1: + self.info["installation"] = i[1].replace("(", "").replace(")", "") + else: + self.info["installation"] = installation + + try: + self.icon_path = ( + icon_theme.lookup_icon( + self.info["id"], None, 512, 1, direction, 0 + ) + .get_file() + .get_path() + ) + except GLib.GError as e: + print(e) + icon_path = None + + +class Remote: + def __init__(self, name, installation): + self.name = name + self.installation = installation + +class HostInfo: + home = home + + # Get all possible installation icon theme dirs + output = subprocess.run( + ['flatpak-spawn', '--host', + 'flatpak', '--installations'], + text=True, + capture_output=True, + ).stdout + lines = output.strip().split("\n") + for i in lines: + icon_theme.add_search_path(f"{i}/exports/share/icons") + + flatpaks = [] + @classmethod + def get_flatpaks(this, callback=None): + # Callback is a function to run after the host flatpaks are found + this.flatpaks.clear() + + def thread(task, *args): + output = subprocess.run( + ['flatpak-spawn', '--host', + 'flatpak', 'list', '--columns=all'], + text=True, + capture_output=True, + ).stdout + lines = output.strip().split("\n") + for i in lines: + this.flatpaks.append(Flatpak(i.split("\t"))) + + Gio.Task.new(None, None, callback).run_in_thread(thread) + + remotes = [] + installations = [] + @classmethod + def get_remotes(this, callback=None): + # Callback is a function to run after the host remotes are found + this.remotes.clear() + this.installations.clear() + + def thread(task, *args): + + # Get all config files for any extra installations + custom_install_config_path = "/run/host/etc/flatpak/installations.d" + if os.path.exists(custom_install_config_path): + for file in os.listdir(custom_install_config_path): + with open(f"{custom_install_config_path}/{file}", "r") as f: + for line in f: + if line.startswith("[Installation"): + # Get specifically the installation name itself + this.installations.append(line.replace("[Installation \"", "").replace("\"]", "").strip()) + + def remote_info(installation): + cmd = ['flatpak-spawn', '--host', + 'flatpak', 'remotes'] + if installation == "user": + cmd.append("--user") + elif installation == "system": + cmd.append("--system") + else: + cmd.append(f"--installation={installation}") + output = subprocess.run( + cmd, text=True, + capture_output=True, + ).stdout + lines = output.strip().split("\n") + for i in lines: + if i != "": + this.remotes.append(Remote(i.strip(), installation)) + if installation == "user" or installation == "system": + this.installations.append(installation) + + for i in this.installations: + remote_info(i) + remote_info("user") + remote_info("system") + + Gio.Task.new(None, None, callback).run_in_thread(thread) \ No newline at end of file diff --git a/src/main.py b/src/main.py index 85ec197..1295026 100644 --- a/src/main.py +++ b/src/main.py @@ -43,31 +43,6 @@ class WarehouseApplication(Adw.Application): self.create_action("quit", lambda *_: self.quit(), ["q"]) self.create_action("about", self.on_about_action) self.create_action("preferences", self.on_preferences_action) - self.create_action("search", self.on_search_action, ["f"]) - self.create_action("manage-data-folders", self.manage_data_shortcut) - self.create_action( - "toggle-batch-mode", - self.batch_mode_shortcut, - ["b", "Return"], - ) - self.create_action( - "toggle-batch-mode-keypad", self.batch_mode_shortcut, ["KP_Enter"] - ) # This action is not added to the shortcuts window - self.create_action( - "manage-data-folders", self.manage_data_shortcut, ["d"] - ) - self.create_action( - "refresh-list", self.refresh_list_shortcut, ["r", "F5"] - ) - self.create_action( - "show-remotes-window", self.show_remotes_shortcut, ["m"] - ) - self.create_action("set-filter", self.filters_shortcut, ["t"]) - self.create_action("install-from-file", self.install_from_file, ["o"]) - self.create_action("open-menu", self.main_menu_shortcut, ["F10"]) - self.create_action( - "open-search-install", self.open_search_install, ["i"] - ) self.is_dialog_open = False @@ -98,29 +73,6 @@ class WarehouseApplication(Adw.Application): lang=lang, ) - def open_search_install(self, widget, _): - SearchInstallWindow(self.props.active_window) - - def batch_mode_shortcut(self, widget, _): - button = self.props.active_window.batch_mode_button - button.set_active(not button.get_active()) - - def manage_data_shortcut(self, widget, _): - OrphansWindow(self.props.active_window) - - def refresh_list_shortcut(self, widget, _): - self.props.active_window.refresh_list_of_flatpaks(widget) - - def show_remotes_shortcut(self, widget, _): - RemotesWindow(self.props.active_window) - - def filters_shortcut(self, widget, _): - FilterWindow(self.props.active_window) - - def main_menu_shortcut(self, widget, _): - window = self.props.active_window - window.main_menu.set_active(True) - def file_callback(self, object, result): window = self.props.active_window try: @@ -197,11 +149,6 @@ class WarehouseApplication(Adw.Application): """Callback for the app.preferences action.""" print("app.preferences action activated") - def on_search_action(self, widget, _): - self.props.active_window.search_bar.set_search_mode( - not self.props.active_window.search_bar.get_search_mode() - ) - def create_action(self, name, callback, shortcuts=None): """Add an application action. @@ -217,7 +164,6 @@ class WarehouseApplication(Adw.Application): if shortcuts: self.set_accels_for_action(f"app.{name}", shortcuts) - def main(version): """The application's entry point.""" app = WarehouseApplication() diff --git a/src/main_window/window.blp b/src/main_window/window.blp index 2fa24bd..e59ba94 100644 --- a/src/main_window/window.blp +++ b/src/main_window/window.blp @@ -19,9 +19,12 @@ template $WarehouseWindow: Adw.ApplicationWindow { } ; content: - Adw.ToolbarView { - [top] - Adw.HeaderBar {} + Adw.NavigationPage { + title: "Test"; + Adw.ToolbarView { + [top] + Adw.HeaderBar {} + } } ; } diff --git a/src/main_window/window.py b/src/main_window/window.py index 19a69cd..f3af6bf 100644 --- a/src/main_window/window.py +++ b/src/main_window/window.py @@ -23,6 +23,7 @@ import re import time from gi.repository import Adw, Gdk, Gio, GLib, Gtk +from .host_info import HostInfo from .const import Config @Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui") @@ -62,3 +63,9 @@ class WarehouseWindow(Adw.ApplicationWindow): if Config.DEVEL: self.add_css_class("devel") + + def guh(*args): + for i in HostInfo.flatpaks: + print(i.info["name"]) + + HostInfo.get_flatpaks() \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index cbb0a39..81f232d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -48,6 +48,7 @@ warehouse_sources = [ '__init__.py', 'main.py', 'main_window/window.py', + 'host_info.py', '../data/style.css', ]