fixup repo file add/remove from url incorrect tempfile name

This commit is contained in:
GloriousEggroll 2025-03-26 21:15:44 -06:00
parent 4f2b2fbdd1
commit b0b6b0c9df
2 changed files with 96 additions and 109 deletions

View file

@ -43,14 +43,12 @@ import logging
from enum import IntEnum from enum import IntEnum
import argparse import argparse
import requests import requests
import urllib from urllib.parse import quote_plus, urlparse
from urllib.parse import quote_plus
import tempfile import tempfile
import os import os
import sys import sys
import json import json
import time import time
from enum import Enum
# Set up logging # Set up logging
@ -628,7 +626,6 @@ def install_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tupl
repo_name = "flathub" repo_name = "flathub"
installation = get_installation(system) installation = get_installation(system)
searcher = get_reposearcher(system)
transaction = Flatpak.Transaction.new_for_installation(installation) transaction = Flatpak.Transaction.new_for_installation(installation)
@ -776,7 +773,7 @@ def repoadd(repofile, system=False):
try: try:
local_path = download_repo(repofile) local_path = download_repo(repofile)
repofile = local_path repofile = local_path
print(f"\nRepository added successfully: {args.add_repo}") print(f"\nRepository added successfully: {repofile}")
except: except:
return False, f"Repository file '{repofile}' could not be downloaded." return False, f"Repository file '{repofile}' could not be downloaded."
@ -822,7 +819,7 @@ def repoadd(repofile, system=False):
def repofile_is_url(string): def repofile_is_url(string):
"""Check if a string is a valid URL""" """Check if a string is a valid URL"""
try: try:
result = urllib.parse.urlparse(string) result = urlparse(string)
return all([result.scheme, result.netloc]) return all([result.scheme, result.netloc])
except: except:
return False return False
@ -831,9 +828,9 @@ def download_repo(url):
"""Download a repository file from URL to /tmp/""" """Download a repository file from URL to /tmp/"""
try: try:
# Create a deterministic filename based on the URL # Create a deterministic filename based on the URL
url_path = urllib.parse.urlparse(url).path url_path = urlparse(url).path
filename = os.path.basename(url_path) or 'repo' filename = os.path.basename(url_path) or 'repo'
tmp_path = Path(tempfile.gettempdir()) / f"{filename}.flatpakrepo" tmp_path = Path(tempfile.gettempdir()) / f"{filename}"
# Download the file # Download the file
with requests.get(url, stream=True) as response: with requests.get(url, stream=True) as response:

192
main.py
View file

@ -255,64 +255,25 @@ class MainWindow(Gtk.Window):
dialog.destroy() dialog.destroy()
def refresh_local(self): def refresh_local(self):
# Create dialog and progress bar try:
dialog = Gtk.Dialog( searcher = libflatpak_query.get_reposearcher(self.system_mode)
title="Refreshing local data, please wait...", installed_results, updates_results = searcher.refresh_local(self.system_mode)
parent=self, self.installed_results = installed_results
modal=True, self.updates_results = updates_results
destroy_with_parent=True except Exception as e:
) message_type = Gtk.MessageType.ERROR
dialog.set_size_request(400, 100) dialog = Gtk.MessageDialog(
transient_for=None, # Changed from self
progress_bar = Gtk.ProgressBar() modal=True,
progress_bar.set_text("Initializing...") destroy_with_parent=True,
progress_bar.set_show_text(True) message_type=message_type,
dialog.vbox.pack_start(progress_bar, True, True, 0) buttons=Gtk.ButtonsType.OK,
dialog.vbox.set_spacing(12) text=f"Error refreshing local data: {str(e)}"
)
# Show the dialog dialog.run()
dialog.show_all()
searcher = libflatpak_query.get_reposearcher(self.system_mode)
# Define thread target function
def refresh_target():
try:
installed_results, updates_results = searcher.refresh_local(self.system_mode)
self.installed_results = installed_results
self.updates_results = updates_results
except Exception as e:
message_type = Gtk.MessageType.ERROR
dialog = Gtk.MessageDialog(
transient_for=None, # Changed from self
modal=True,
destroy_with_parent=True,
message_type=message_type,
buttons=Gtk.ButtonsType.OK,
text=f"Error updating progress: {str(e)}"
)
dialog.run()
dialog.destroy()
# Start the refresh thread
refresh_thread = threading.Thread(target=refresh_target)
refresh_thread.start()
def update_progress():
while refresh_thread.is_alive():
progress_bar.set_text("Refreshing...")
progress = searcher.refresh_progress
progress_bar.set_fraction(progress / 100)
return True
else:
progress_bar.set_fraction(100 / 100)
dialog.destroy()
# Start the progress update timer
GLib.timeout_add_seconds(0.5, update_progress)
dialog.run()
if not refresh_thread.is_alive() and dialog.is_active():
dialog.destroy() dialog.destroy()
def create_panels(self): def create_panels(self):
# Check if panels already exist # Check if panels already exist
if hasattr(self, 'left_panel') and self.left_panel.get_parent(): if hasattr(self, 'left_panel') and self.left_panel.get_parent():
@ -924,6 +885,31 @@ class MainWindow(Gtk.Window):
self.right_container.show_all() # Show all widgets after adding them self.right_container.show_all() # Show all widgets after adding them
def show_waiting_dialog(self, message="Please wait while task is running..."):
"""Show a modal dialog with a spinner"""
self.waiting_dialog = Gtk.Dialog(
title="Running Task...",
transient_for=self,
modal=True,
destroy_with_parent=True,
)
# Create spinner
self.spinner = Gtk.Spinner()
self.spinner.start()
# Add content
box = self.waiting_dialog.get_content_area()
box.set_spacing(12)
box.set_border_width(12)
# Add label and spinner
box.pack_start(Gtk.Label(label=message), False, False, 0)
box.pack_start(self.spinner, False, False, 0)
# Show dialog
self.waiting_dialog.show_all()
def on_install_clicked(self, button, app): def on_install_clicked(self, button, app):
"""Handle the Install button click with installation options""" """Handle the Install button click with installation options"""
details = app.get_details() details = app.get_details()
@ -946,7 +932,6 @@ class MainWindow(Gtk.Window):
# Create repository dropdown # Create repository dropdown
repo_combo = Gtk.ComboBoxText() repo_combo = Gtk.ComboBoxText()
repo_combo.set_hexpand(True)
content_area.pack_start(Gtk.Label(label=f"Install: {details['id']}?"), False, False, 0) content_area.pack_start(Gtk.Label(label=f"Install: {details['id']}?"), False, False, 0)
@ -998,30 +983,43 @@ class MainWindow(Gtk.Window):
selected_repo = repo_combo.get_active_text() selected_repo = repo_combo.get_active_text()
# Perform installation # Perform installation
# Get selected values def perform_installation():
if self.system_mode is False: # Show waiting dialog
print(f"Installing {details['name']} for User") GLib.idle_add(self.show_waiting_dialog)
else:
print(f"Installing {details['name']} for System") success, message = libflatpak_query.install_flatpak(app, selected_repo, self.system_mode)
success, message = libflatpak_query.install_flatpak(app, selected_repo, self.system_mode)
message_type=Gtk.MessageType.INFO # Update UI on main thread
if not success: GLib.idle_add(lambda: self.on_task_complete(dialog, success, message))
message_type=Gtk.MessageType.ERROR
if message: # Start spinner and begin installation
finished_dialog = Gtk.MessageDialog( thread = threading.Thread(target=perform_installation)
transient_for=self, thread.daemon = True # Allow program to exit even if thread is still running
modal=True, thread.start()
destroy_with_parent=True,
message_type=message_type,
buttons=Gtk.ButtonsType.OK,
text=message
)
self.refresh_local()
self.refresh_current_page()
finished_dialog.run()
finished_dialog.destroy()
dialog.destroy() dialog.destroy()
def on_task_complete(self, dialog, success, message):
"""Handle tasl completion"""
# Update UI
message_type=Gtk.MessageType.INFO
if not success:
message_type=Gtk.MessageType.ERROR
if message:
finished_dialog = Gtk.MessageDialog(
transient_for=self,
modal=True,
destroy_with_parent=True,
message_type=message_type,
buttons=Gtk.ButtonsType.OK,
text=message
)
self.refresh_local()
self.refresh_current_page()
finished_dialog.run()
finished_dialog.destroy()
self.waiting_dialog.destroy()
def on_remove_clicked(self, button, app): def on_remove_clicked(self, button, app):
"""Handle the Remove button click with removal options""" """Handle the Remove button click with removal options"""
details = app.get_details() details = app.get_details()
@ -1051,28 +1049,20 @@ class MainWindow(Gtk.Window):
response = dialog.run() response = dialog.run()
if response == Gtk.ResponseType.OK: if response == Gtk.ResponseType.OK:
# Perform Removal # Perform Removal
# Get selected values def perform_removal():
if self.system_mode is False: # Show waiting dialog
print(f"Removing {details['name']} for User.") GLib.idle_add(self.show_waiting_dialog, "Removing package...")
else:
print(f"Removing {details['name']} for System.") success, message = libflatpak_query.remove_flatpak(app, self.system_mode)
success, message = libflatpak_query.remove_flatpak(app, self.system_mode)
message_type=Gtk.MessageType.INFO # Update UI on main thread
if not success: GLib.idle_add(lambda: self.on_task_complete(dialog, success, message))
message_type=Gtk.MessageType.ERROR
if message: # Start spinner and begin installation
finished_dialog = Gtk.MessageDialog( thread = threading.Thread(target=perform_removal)
transient_for=self, thread.daemon = True # Allow program to exit even if thread is still running
modal=True, thread.start()
destroy_with_parent=True,
message_type=message_type,
buttons=Gtk.ButtonsType.OK,
text=message
)
self.refresh_local()
self.refresh_current_page()
finished_dialog.run()
finished_dialog.destroy()
dialog.destroy() dialog.destroy()
def on_update_clicked(self, button, app): def on_update_clicked(self, button, app):