bump readme

This commit is contained in:
GloriousEggroll 2025-04-12 19:40:32 -06:00
parent ccd6939141
commit 02ba1cca56
3 changed files with 150 additions and 24 deletions

View file

@ -43,9 +43,9 @@ DONE:
- Add Package information page/section.
- Cleanup permissions GUI
- Add permissions override viewing inside per-app permissions view.
- Add 'update all' functionality.
TODO:
- Update management GUI (individual apps can already be updated)
- add about section
- General GUI layout/theming improvements
@ -83,6 +83,7 @@ options:
--install APP_ID Install a Flatpak package
--remove APP_ID Remove a Flatpak package
--update APP_ID Update a Flatpak package
--update-all Apply all available updates
--system Install as system instead of user
--refresh Install as system instead of user
--refresh-local Install as system instead of user
@ -165,6 +166,8 @@ Common CLI combinations:
./fp_turbo.py --remove <app id> --system
./fp_turbo.py --update <app id>
./fp_turbo.py --update <app id> --system
./fp_turbo.py --update-all
./fp_turbo.py --update-all --system
./fp_turbo.py --id <app id> --list-file-perms
./fp_turbo.py --id <app id> --add-file-perms <host, host-os, host-etc, home, or "/path/to/directory" for custom paths>
./fp_turbo.py --id <app id> --remove-file-perms <host, host-os, host-etc, home, or "/path/to/directory" for custom paths>
@ -203,7 +206,6 @@ Common CLI combinations:
./fp_turbo.py --override --global-list-other-perm-values <environment, session_bus, system_bus> --system
./fp_turbo.py --override --global-add-other-perm-values <environment, session_bus, system_bus> --perm-value <ENVVAR=value or xxx.yyy.zzz=talk or xxx.yyy.zzz=own> --system
./fp_turbo.py --override --global-remove-other-perm-values <environment, session_bus, system_bus> --perm-value <ENVVAR=value or xxx.yyy.zzz=talk or xxx.yyy.zzz=own> --system
./fp_turbo.py --get-all-portal-permissions
./fp_turbo.py --get-portal-permissions <portal>
./fp_turbo.py --get-app-portal-permissions --id <app id>

View file

@ -720,10 +720,11 @@ class AppstreamSearcher:
self.installed_results.extend(search_result)
elif "updates" in category:
updates = searcher.check_updates(system)
for repo_name, app_id, repo_type in updates:
for app_id, repo_name, repo_type in updates:
if repo_name:
search_result = searcher.search_flatpak(app_id, repo_name)
self.updates_results.extend(search_result)
# Update progress bar
self.refresh_progress = (current_category / total_categories) * 100
# make sure to reset these to empty before refreshing.
@ -897,9 +898,11 @@ def install_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tupl
installation = get_installation(system)
transaction = Flatpak.Transaction.new_for_installation(installation)
# Add the install operation
transaction.add_install(repo_name, app.flatpak_bundle, None)
available_apps = installation.list_remote_refs_sync(repo_name)
for available_app in available_apps:
if app.id in available_app.get_name():
# Add the install operation
transaction.add_install(repo_name, available_app.format_ref(), None)
# Run the transaction
try:
transaction.run()
@ -942,7 +945,7 @@ def install_flatpakref(ref_file, system=False):
return True, f"Successfully installed {ref_file}"
def remove_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple[bool, str]:
def remove_flatpak(app: AppStreamPackage, system=False) -> tuple[bool, str]:
"""
Remove a Flatpak package using transactions.
@ -953,15 +956,15 @@ def remove_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple
Returns:
Tuple[bool, str]: (success, message)
"""
if not repo_name:
repo_name = "flathub"
# Get the appropriate installation based on user parameter
installation = get_installation(system)
installed = installation.list_installed_refs(None)
# Create a new transaction for removal
transaction = Flatpak.Transaction.new_for_installation(installation)
transaction.add_uninstall(app.flatpak_bundle)
for installed_ref in installed:
if app.id in installed_ref.get_name():
transaction.add_uninstall(installed_ref.format_ref())
# Run the transaction
try:
transaction.run()
@ -969,7 +972,7 @@ def remove_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple
return False, f"Failed to remove {app.id}: {e}"
return True, f"Successfully removed {app.id}"
def update_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple[bool, str]:
def update_flatpak(app: AppStreamPackage, system=False) -> tuple[bool, str]:
"""
Remove a Flatpak package using transactions.
@ -980,15 +983,16 @@ def update_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple
Returns:
Tuple[bool, str]: (success, message)
"""
if not repo_name:
repo_name = "flathub"
# Get the appropriate installation based on user parameter
installation = get_installation(system)
updates = installation.list_installed_refs_for_update(None)
# Create a new transaction for removal
transaction = Flatpak.Transaction.new_for_installation(installation)
transaction.add_update(app.flatpak_bundle)
for update in updates:
if app.id == update.get_name():
transaction.add_update(update.format_ref())
# Run the transaction
try:
transaction.run()
@ -996,6 +1000,31 @@ def update_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple
return False, f"Failed to update {app.id}: {e}"
return True, f"Successfully updated {app.id}"
def update_all_flatpaks(apps: list[AppStreamPackage], system=False) -> tuple[bool, str]:
"""
Update multiple Flatpak packages using transactions.
Args:
apps (Union[List[AppStreamPackage], AppStreamPackage]): One or more packages to update
system (Optional[bool]): Whether to operate on user or system installation
Returns:
Tuple[bool, List[str]]: (success, list of status messages)
"""
installation = get_installation(system)
updates = installation.list_installed_refs_for_update(None)
# Create a new transaction for removal
transaction = Flatpak.Transaction.new_for_installation(installation)
for update in updates:
transaction.add_update(update.format_ref())
try:
transaction.run()
return True, "Successfully updated all packages"
except GLib.Error as e:
return False, f"Failed to update all packages: {str(e)}"
def get_installation(system=False):
if system is False:
installation = Flatpak.Installation.new_user()
@ -2253,6 +2282,8 @@ def main():
help='Remove a Flatpak package')
parser.add_argument('--update', type=str, metavar='APP_ID',
help='Update a Flatpak package')
parser.add_argument('--update-all', action='store_true',
help='Update all Flatpak packages')
parser.add_argument('--system', action='store_true', help='Install as system instead of user')
parser.add_argument('--refresh', action='store_true', help='Install as system instead of user')
parser.add_argument('--refresh-local', action='store_true', help='Install as system instead of user')
@ -2340,6 +2371,10 @@ def main():
handle_update(args, searcher)
return
if args.update_all:
handle_update_all(args, searcher)
return
# Handle information operations
if args.list_installed:
handle_list_installed(args, searcher)
@ -2504,7 +2539,7 @@ def handle_remove(args, searcher):
result_message = ""
for package in packagelist:
try:
success, message = remove_flatpak(package, args.repo, args.system)
success, message = remove_flatpak(package, args.system)
result_message = f"{message}"
break
except GLib.Error as e:
@ -2513,11 +2548,11 @@ def handle_remove(args, searcher):
print(result_message)
def handle_update(args, searcher):
packagelist = searcher.search_flatpak(args.update, args.repo)
packagelist = searcher.search_flatpak(args.update)
result_message = ""
for package in packagelist:
try:
success, message = update_flatpak(package, args.repo, args.system)
success, message = update_flatpak(package, args.system)
result_message = f"{message}"
break
except GLib.Error as e:
@ -2525,6 +2560,19 @@ def handle_update(args, searcher):
pass
print(result_message)
def handle_update_all(args, searcher):
packagelist = searcher.search_flatpak(args.update)
result_message = ""
for package in packagelist:
try:
success, message = update_all_flatpaks(package, args.system)
result_message = f"{message}"
break
except GLib.Error as e:
result_message = f"Unable to apply updates: {str(e)}"
pass
print(result_message)
def handle_list_installed(args, searcher):
installed_apps = searcher.get_installed_apps(args.system)
print(f"\nInstalled Flatpak Applications ({len(installed_apps)}):")

86
main.py
View file

@ -295,6 +295,10 @@ class MainWindow(Gtk.Window):
.app-type-label {
font-size: 0.8em;
}
.updates_available_bar {
background-color: #18A3FF;
padding: 4px;
}
.screenshot-bullet {
color: #18A3FF;
font-size: 30px;
@ -917,6 +921,7 @@ class MainWindow(Gtk.Window):
self.current_group = group
self.update_category_header(category)
self.update_subcategories_bar(category)
self.update_updates_available_bar(category)
self.show_category_apps(category)
@ -969,6 +974,15 @@ class MainWindow(Gtk.Window):
self.subcategories_bar.set_visible(False)
self.subcategories_bar.set_halign(Gtk.Align.FILL) # Ensure full width
self.right_panel.pack_start(self.subcategories_bar, False, False, 0)
# Create subcategories bar (initially hidden)
self.updates_available_bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.updates_available_bar.set_hexpand(True)
self.updates_available_bar.set_spacing(6)
self.updates_available_bar.set_border_width(6)
self.updates_available_bar.set_visible(False)
self.updates_available_bar.set_halign(Gtk.Align.FILL) # Ensure full width
self.right_panel.pack_start(self.updates_available_bar, False, False, 0)
self.right_panel.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, False, 0)
# Create scrollable area
@ -1150,6 +1164,68 @@ class MainWindow(Gtk.Window):
self.subcategories_bar.queue_resize()
self.subcategories_bar.show_all()
def update_updates_available_bar(self, category):
for child in self.updates_available_bar.get_children():
child.destroy()
if category == "updates":
if self.updates_results != [] :
self.updates_available_bar.get_style_context().add_class("updates_available_bar")
self.updates_available_bar.set_visible(True)
buttons_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
buttons_box.set_spacing(6)
buttons_box.set_margin_top(4)
buttons_box.set_halign(Gtk.Align.END)
update_all_button = Gtk.Button()
update_all_icon = Gio.Icon.new_for_string('system-software-update-symbolic')
update_all_button.set_image(Gtk.Image.new_from_gicon(update_all_icon, Gtk.IconSize.BUTTON))
update_all_button.connect("clicked", self.on_update_all_button_clicked)
buttons_box.pack_end(update_all_button, False, False, 0)
# Create left label
left_label = Gtk.Label(label="Update All: ")
left_label.set_halign(Gtk.Align.END) # Align left
self.updates_available_bar.pack_end(buttons_box, False, False, 0)
self.updates_available_bar.pack_end(left_label, False, False, 0)
self.updates_available_bar.show_all()
else:
self.updates_available_bar.set_visible(False)
def on_update_all_button_clicked(self, button=None):
# Create a message dialog
dialog = Gtk.MessageDialog(
transient_for=self, # Parent window
modal=True, # Make it modal
message_type=Gtk.MessageType.QUESTION,
buttons=Gtk.ButtonsType.OK_CANCEL,
text="Download and install all available Flatpak updates?",
title="Confirm"
)
# Show the dialog and get the response
response = dialog.run()
# Handle the response
if response == Gtk.ResponseType.OK:
# Perform Removal
def perform_update():
# Show waiting dialog
GLib.idle_add(self.show_waiting_dialog, "Updating packages...")
success, message = fp_turbo.update_all_flatpaks(self.updates_results, self.system_mode)
# Update UI on main thread
GLib.idle_add(lambda: self.on_task_complete(dialog, success, message))
# Start spinner and begin installation
thread = threading.Thread(target=perform_update)
thread.daemon = True # Allow program to exit even if thread is still running
thread.start()
dialog.destroy()
def get_parent_category(self, subcategory):
for parent, subcats in self.subcategory_groups.items():
if subcategory in subcats:
@ -1507,14 +1583,14 @@ class MainWindow(Gtk.Window):
# Add repository labels
repo_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
repo_box.set_spacing(4)
repo_box.set_halign(Gtk.Align.END)
repo_box.set_valign(Gtk.Align.END)
repo_box.set_halign(Gtk.Align.START)
repo_box.set_valign(Gtk.Align.START)
# Add repository labels
for repo in sorted(app_data['repos']):
repo_label = Gtk.Label(label=f"{repo}")
#repo_label.get_style_context().add_class("app-repo-label")
repo_label.set_halign(Gtk.Align.END)
repo_label.set_halign(Gtk.Align.START)
repo_box.pack_end(repo_label, False, False, 0)
repo_list_label = Gtk.Label(label="Sources: ")
repo_box.pack_end(repo_list_label, False, False, 0)
@ -1818,7 +1894,7 @@ class MainWindow(Gtk.Window):
# Show waiting dialog
GLib.idle_add(self.show_waiting_dialog, "Removing package...")
success, message = fp_turbo.remove_flatpak(app, None, self.system_mode)
success, message = fp_turbo.remove_flatpak(app, self.system_mode)
# Update UI on main thread
GLib.idle_add(lambda: self.on_task_complete(dialog, success, message))
@ -3543,7 +3619,7 @@ class MainWindow(Gtk.Window):
# Show waiting dialog
GLib.idle_add(self.show_waiting_dialog, "Updating package...")
success, message = fp_turbo.update_flatpak(app, None, self.system_mode)
success, message = fp_turbo.update_flatpak(app, self.system_mode)
# Update UI on main thread
GLib.idle_add(lambda: self.on_task_complete(dialog, success, message))