From 5d6b408259e32c5deb429503a299b15cd3040676 Mon Sep 17 00:00:00 2001 From: Heliguy Date: Fri, 27 Sep 2024 21:19:28 -0400 Subject: [PATCH] Set no title for the snapshotting status, as that will now be handled later --- src/snapshot_page/snapshot_box.py | 20 +++++++++++- src/snapshot_page/snapshot_page.py | 2 +- src/snapshot_page/tar_worker.py | 49 ++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/snapshot_page/snapshot_box.py b/src/snapshot_page/snapshot_box.py index 6586387..84136d7 100644 --- a/src/snapshot_page/snapshot_box.py +++ b/src/snapshot_page/snapshot_box.py @@ -1,6 +1,7 @@ from gi.repository import Adw, Gtk, GLib, Gio from .host_info import HostInfo from .error_toast import ErrorToast +from .tar_worker import TarWorker import os, subprocess, json, re @Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshot_box.ui") @@ -109,11 +110,27 @@ class SnapshotBox(Gtk.Box): dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE) dialog.connect("response", on_response) dialog.present(HostInfo.main_window) - + + def get_fraction(self): + loading_status = self.parent_page.parent_page.loading_status + loading_status.title_label.set_label(_("Applying Snapshot")) + loading_status.progress_bar.set_fraction(total / len(self.workers)) + + def on_apply(self, button): + self.parent_page.parent_page.status_stack.set_visible_child(self.snapshot_page.snapshotting_view) + self.worker.extract() + + def __init__(self, parent_page, folder, snapshots_path, toast_overlay, **kwargs): super().__init__(**kwargs) self.toast_overlay = toast_overlay + self.app_id = snapshots_path.split('/')[-2].strip() + self.worker = TarWorker( + existing_path=f"{snapshots_path}{folder}", + new_path=f"{HostInfo.home}/.var/app/{self.app_id}/", + file_name=self.app_id, + ) split_folder = folder.split('_') if len(split_folder) < 2: @@ -128,6 +145,7 @@ class SnapshotBox(Gtk.Box): self.version.set_label(_("Version: {}").format(split_folder[1].replace(".tar.zst", ""))) self.json_path = f"{snapshots_path}{folder.replace('tar.zst', 'json')}" self.load_from_json() + self.apply_button.connect("clicked", self.on_apply) self.apply_rename.connect("clicked", self.on_rename) self.rename_entry.connect("activate", self.on_rename) self.rename_entry.connect("changed", self.valid_checker) diff --git a/src/snapshot_page/snapshot_page.py b/src/snapshot_page/snapshot_page.py index 9511a3b..c752490 100644 --- a/src/snapshot_page/snapshot_page.py +++ b/src/snapshot_page/snapshot_page.py @@ -191,7 +191,7 @@ class SnapshotPage(Adw.BreakpointBin): self.leftover_snapshots = [] # self.leftover_rows = [] self.list_page = SnapshotsListPage(self) - self.snapshotting_status = LoadingStatus(_("Creating Snapshots"), _("This might take a while"), True, self.on_cancel) + self.snapshotting_status = LoadingStatus("Initial Title", _("This might take a while"), True, self.on_cancel) # Connections self.active_listbox.connect("row-activated", self.active_select_handler) diff --git a/src/snapshot_page/tar_worker.py b/src/snapshot_page/tar_worker.py index bbac690..9f62f20 100644 --- a/src/snapshot_page/tar_worker.py +++ b/src/snapshot_page/tar_worker.py @@ -40,30 +40,51 @@ class TarWorker: self.stop = True # tell the check timeout to stop, because we know the file is done being made except subprocess.CalledProcessError as cpe: - print("Called Error") - self.do_cancel(cpe.stderr.decode()) # stderr is in bytes, so decode it + print("Called Error in Compress Thread") + self.do_cancel(cpe.stderr.decode(), [f'{self.new_path}/{self.file_name}.tar.zst', f'{self.new_path}/{self.file_name}.json']) # stderr is in bytes, so decode it except Exception as e: - print("Exception") - self.do_cancel(str(e)) + print("Exception in Compress Thread") + self.do_cancel(str(e), [f'{self.new_path}/{self.file_name}.tar.zst', f'{self.new_path}/{self.file_name}.json']) + + def extract_thread(self, *args): + try: + if not os.path.exists(self.new_path): + os.makedirs(self.new_path) # create the new user data path if none exists + else: + subprocess.run('gio', 'trash', self.new_path) # trash the current user data, because new data will go in its place + + self.total = int(subprocess.run(['du', '-s', self.existing_path], check=True, text=True, capture_output=True).stdout.split('\t')[0]) + self.total *= 2.2 # estimate from space savings + self.process = subprocess.Popen(['tar', '--zstd', '-xvf', self.existing_path, '-C', self.new_path]) + stdout, stderr = self.process.communicate() + if self.process.returncode != 0: + raise subprocess.CalledProcessError(self.process.returncode, self.process.args, output=stdout, stderr=stderr) + + except subprocess.CalledProcessError as cpe: + print("Called Error in Extract Thread") + self.do_cancel(cpe.stderr.decode(), [self.new_path]) + + except Exception as e: + print("Exception in Extract Thread") + self.do_cancel(str(e), [self.new_path]) - def do_cancel(self, error_str=None): + def do_cancel(self, error_str, files_to_trash=None): self.process.terminate() self.process.wait() - if error_str == "manual_cancel": + if not files_to_trash is None: try: - subprocess.run(['gio', 'trash', f'{self.new_path}/{self.file_name}.tar.zst'],capture_output=True) - subprocess.run(['gio', 'trash', f'{self.new_path}/{self.file_name}.json'],capture_output=True) + subprocess.run(['gio', 'trash'] + files_to_trash, capture_output=True) except Exception: pass self.stop = True - print("Error in compression:", error_str) + print("Error in cancelling:", error_str) - def check_size(self): + def check_size(self, check_path): try: - output = subprocess.run(['du', '-s', f"{self.new_path}/{self.file_name}.tar.zst"], check=True, text=True, capture_output=True).stdout.split('\t')[0] + output = subprocess.run(['du', '-s', check_path], check=True, text=True, capture_output=True).stdout.split('\t')[0] working_total = int(output) self.fraction = working_total / self.total return not self.stop @@ -74,5 +95,9 @@ class TarWorker: def compress(self): self.stop = False Gio.Task.new(None, None, None).run_in_thread(self.compress_thread) - GLib.timeout_add(200, self.check_size) + GLib.timeout_add(200, self.check_size, f"{self.new_path}/{self.file_name}.tar.zst") + def extract(self): + self.stop = False + Gio.Task.new(None, None, None).run_in_thread(self.existing_path) + GLib.timeout_add(200, self.check_size, self.new_path)