diff --git a/client.py b/client.py index 695ebc6..f8d406c 100644 --- a/client.py +++ b/client.py @@ -1,8 +1,8 @@ -import tkinter import customtkinter import PIL import data_backend import client_details +import pgwrapper customtkinter.set_appearance_mode("dark") customtkinter.set_default_color_theme("blue") @@ -130,11 +130,12 @@ def update_button_positions(event=None): if __name__ == "__main__": - progressbar = customtkinter.CTkProgressBar(master=app) + pgw = pgwrapper.ProgressBarWrapper() + pgw.new(app) # define data backend # #db = data_backend.LocalFS(None, None, "./install/", remote_root_dir="example_software_root") db = data_backend.FTP(None, None, "./install/", server="ftp://192.168.1.132:2121", - remote_root_dir="/", progress_bar=progressbar, tkinter_root=app) + remote_root_dir="/", progress_bar_wrapper=pgw, tkinter_root=app) load_main() diff --git a/client_details.py b/client_details.py index 0939282..28c57ba 100644 --- a/client_details.py +++ b/client_details.py @@ -37,14 +37,17 @@ def create_details_page(app, software, backswitch_function): img = PIL.ImageTk.PhotoImage(img) - # navbar # + # navbar & progress bar # navbar = customtkinter.CTkFrame(app, fg_color="transparent") navbar.grid(column=0, row=0, padx=10, pady=5, sticky="ew") back_button = customtkinter.CTkButton(navbar, text="Back", command=backswitch_function) back_button.pack(anchor="nw", side="left") + progress_bar = software.progress_bar_wrapper.new(navbar) + progress_bar.pack(anchor="nw", side="left") elements.append(navbar) elements.append(back_button) + elements.append(progress_bar) # thumbnail image # thumbnail_image = customtkinter.CTkButton(app, text="", image=img, width=500, height=700, diff --git a/data_backend.py b/data_backend.py index 7fd89db..8e4e986 100644 --- a/data_backend.py +++ b/data_backend.py @@ -11,14 +11,14 @@ class DataBackend: os.makedirs(cache_dir, exist_ok=True) def __init__(self, user, password, install_dir, server=None, remote_root_dir=None, - progress_bar=None, tkinter_root=None): + progress_bar_wrapper=None, tkinter_root=None): self.user = user self.password = password self.remote_root_dir = remote_root_dir self.server = server self.install_dir = install_dir - self.progress_bar=progress_bar + self.progress_bar_wrapper = progress_bar_wrapper self.root = tkinter_root def get(self, path, return_content=False): @@ -147,7 +147,7 @@ class FTP(DataBackend): # load the file on remote # total_size = ftp.size(fullpath) - self.progress_bar["maximum"] = total_size + self.progress_bar_wrapper.get_pb()["maximum"] = total_size print(local_file, "not in cache, retriving..") with open(local_file, "w") as f: @@ -158,12 +158,13 @@ class FTP(DataBackend): unit='B', unit_scale=True ) as cmd_progress_bar: - + # Define a callback function to update the progress bar # def callback(data): local_file_open.write(data) self.root.update_idletasks() # Update the GUI - self.progress_bar.set(self.progress_bar.get() + len(data)) + self.progress_bar_wrapper.get_pb().set( + self.progress_bar_wrapper.get_pb().get() + len(data)) cmd_progress_bar.update(len(data)) # run with callback # @@ -226,4 +227,5 @@ class FTP(DataBackend): #print(meta_file_content) local_meta_file_list.append(f) - return [ software.Software(meta_file, self) for meta_file in local_meta_file_list ] \ No newline at end of file + return [ software.Software(meta_file, self, self.progress_bar_wrapper) + for meta_file in local_meta_file_list ] \ No newline at end of file diff --git a/pgwrapper.py b/pgwrapper.py new file mode 100644 index 0000000..e38c32e --- /dev/null +++ b/pgwrapper.py @@ -0,0 +1,21 @@ +import customtkinter + +class ProgressBarWrapper: + '''Provide a progress bar wrapper, so PGs can be created and destroyed + on the GUI level without affecting the references stored for updates + in the DataBackend and Software Objects''' + + def __init__(self): + self.progress_bar = None + + def new(self, tk_parent): + self.progress_bar = customtkinter.CTkProgressBar(tk_parent) + self.progress_bar["maximum"] = 10000 + self.progress_bar.set(0) + return self.progress_bar + + def get_pb(self): + if self.progress_bar: + return self.progress_bar + else: + raise AssertionError("No progress bar in this wrapper created") \ No newline at end of file diff --git a/software.py b/software.py index 7fa13f5..22ded7a 100644 --- a/software.py +++ b/software.py @@ -4,10 +4,11 @@ import localaction import zipfile import shutil import pathlib +import tqdm class Software: - def __init__(self, meta_file, backend): + def __init__(self, meta_file, backend, progress_bar_wrapper): self.meta_file = meta_file self.directory = os.path.dirname(meta_file) @@ -15,6 +16,7 @@ class Software: # print(self.directory) self.cache_dir = os.path.join("cache", self.directory) self._load_from_yaml() + self.progress_bar_wrapper = progress_bar_wrapper def _load_from_yaml(self): @@ -52,7 +54,18 @@ class Software: os.makedirs(software_path, exist_ok=True) with zipfile.ZipFile(cache_src, 'r') as zip_ref: - zip_ref.extractall(software_path) + + total_count = zip_ref.infolist() + count = 0 + for member in tqdm.tqdm(total_count, desc='Extracting '): + try: + zip_ref.extract(member, software_path) + count += 1 + self.progress_bar_wrapper.get_pb().set(count/len(total_count)) + self.progress_bar_wrapper.get_pb().update_idletasks() + except zipfile.error as e: + pass # TODO ??? + #zip_ref.extractall(software_path) def install(self): '''Install this software from the backend'''