mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-14 00:04:08 +09:00
115 lines
3.8 KiB
Python
115 lines
3.8 KiB
Python
from gi.repository import GLib, Gio
|
|
from .host_info import HostInfo
|
|
import subprocess, re
|
|
|
|
class ChangeVersionWorker:
|
|
process = None
|
|
callback = None
|
|
error_callback = None
|
|
loading_status = None
|
|
did_error = False
|
|
|
|
@classmethod
|
|
def update_status(this, package_ratio, complete, total):
|
|
final_ratio = (package_ratio + complete) / (total or 1)
|
|
|
|
print(f"fr: {final_ratio:.2f}")
|
|
print("r:", package_ratio, ", c:", complete, ", t:", total)
|
|
print("=======================================")
|
|
|
|
if not this.loading_status is None:
|
|
GLib.idle_add(lambda *_: this.loading_status.progress_bar.set_fraction(final_ratio))
|
|
|
|
@classmethod
|
|
def change_version_thread(this, should_mask, package, commit):
|
|
try:
|
|
cmd = ['flatpak-spawn', '--host', 'pkexec', 'sh', '-c']
|
|
|
|
installation = package.info['installation']
|
|
real_installation = ""
|
|
if installation == "user" or installation == "system":
|
|
real_installation = f"--{installation}"
|
|
else:
|
|
real_installation = f"--installation={installation}"
|
|
|
|
suffix = ""
|
|
unmask_cmd = f"flatpak mask --remove {real_installation} {package.info['id']} && "
|
|
change_version_cmd = f"flatpak update {package.info['ref']} --commit={commit} {real_installation} -y"
|
|
mask_cmd = f" && flatpak mask {real_installation} {package.info['id']}"
|
|
if package.is_masked:
|
|
suffix += unmask_cmd
|
|
|
|
suffix += change_version_cmd
|
|
if should_mask:
|
|
suffix += mask_cmd
|
|
|
|
cmd.append(suffix)
|
|
this.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
|
percent_pattern = r'\d{1,3}%'
|
|
amount_pattern = r'(\d+)/(\d+)'
|
|
for line in this.process.stdout:
|
|
line = line.strip()
|
|
percent_match = re.search(percent_pattern, line)
|
|
if percent_match:
|
|
ratio = int(percent_match.group()[0:-1]) / 100.0
|
|
amount_match = re.search(amount_pattern, line)
|
|
if amount_match:
|
|
amount = amount_match.group().split('/')
|
|
complete = int(amount[0]) - 1
|
|
total = int(amount[1])
|
|
this.update_status(ratio, complete, total)
|
|
else:
|
|
this.update_status(ratio, 0, 1)
|
|
|
|
this.process.wait(timeout=10)
|
|
if error := this.process.communicate()[1].strip():
|
|
this.on_error(_("Error occurred while changing version"), error)
|
|
|
|
except subprocess.TimeoutExpired as te:
|
|
this.process.terminate()
|
|
this.on_error(_("Error occurred while changing version"), _("Failed to exit cleanly"))
|
|
|
|
except Exception as e:
|
|
this.process.terminate()
|
|
this.on_error(_("Error occurred while changing version"), str(e))
|
|
|
|
@classmethod
|
|
def cancel(this):
|
|
if this.process is None:
|
|
return
|
|
|
|
try:
|
|
this.process.terminate()
|
|
this.process.wait(timeout=10)
|
|
except Exception as e:
|
|
this.on_error(_("Could not cancel version change"), str(e))
|
|
|
|
@classmethod
|
|
def on_done(this, *args):
|
|
this.process = None
|
|
HostInfo.main_window.remove_refresh_lockout("changing version")
|
|
if not this.loading_status is None:
|
|
this.loading_status.progress_bar.set_fraction(0.0)
|
|
|
|
if not this.callback is None:
|
|
this.callback(this.did_error)
|
|
|
|
@classmethod
|
|
def on_error(this, user_facing_label, error_message):
|
|
this.did_error = True
|
|
if not this.error_callback is None:
|
|
this.error_callback(user_facing_label, error_message)
|
|
|
|
@classmethod
|
|
def change_version(this, should_mask, package, commit, loading_status=None, callback=None, error_callback=None):
|
|
if not this.process is None:
|
|
this.on_error(_("Could not change version"), _("Another package is changing version."))
|
|
return False
|
|
|
|
this.loading_status = loading_status
|
|
this.callback = callback
|
|
this.error_callback = error_callback
|
|
HostInfo.main_window.add_refresh_lockout("changing version")
|
|
Gio.Task.new(None, None, this.on_done).run_in_thread(lambda *_: this.change_version_thread(should_mask, package, commit))
|
|
return True
|