from os import system, getlogin import os from sys import exit from zipfile import ZipFile import win32com.client from glob import glob import re from itertools import cycle from shutil import get_terminal_size from threading import Thread from time import sleep def error_exit(exception_info: str): print(exception_info) input("\nPress enter/return to exit") exit(1) class NoMatchingFile(Exception): def __init__(self, search_file: str, found: list) -> None: super().__init__(f"File: {search_file} was not found: {found}") class Loader: def __init__(self, desc="Loading...", end="Done!", timeout=0.1): """ A loader-like context manager Args: desc (str, optional): The loader's description. Defaults to "Loading...". end (str, optional): Final print. Defaults to "Done!". timeout (float, optional): Sleep time between prints. Defaults to 0.1. """ self.desc = desc self.end = end self.timeout = timeout self._thread = Thread(target=self._animate, daemon=True) self.steps = ["|", "/", "-", "\\",] self.done = False def start(self): self._thread.start() return self def _animate(self): for c in cycle(self.steps): if self.done: break print(f"\r{self.desc} {c}", flush=True, end="") sleep(self.timeout) def __enter__(self): self.start() def stop(self): self.done = True cols = get_terminal_size((80, 20)).columns print("\r" + " " * cols, end="", flush=True) print(f"\r{self.end}", flush=True) def __exit__(self, exc_type, exc_value, tb): # handle exceptions with those variables ^ self.stop() ZIP_LOCATION = r"\\leafnow.com\public\Accounting Shared\ILE Apps" APP_FOLDER = r"InfoLeaseExtract" try: user = getlogin() install_folder = f"C:\\Users\\{user}\\AppData\\Local" backup_install_folder = f"C:\\Users\\{user}\\Documents\\" print(f"Initalizing InfoLease Extract Installer\n#######################################") # Find the newest version: latest_version = glob(f"{ZIP_LOCATION}\\LATEST*") if len(latest_version) == 0: # Create Custom exception raise NoMatchingFile(f"{ZIP_LOCATION}\\LATEST*", latest_version) latest_version: str = latest_version[0] version = re.search("\d+\.\d+", latest_version).group() print(f"Installing verion {version}...") with ZipFile(latest_version, 'r') as zipObj: try: with Loader("Setting up program files..."): zipObj.extractall(install_folder) except Exception as e: error_exit(f"Failed to extract file ({latest_version}) to '{install_folder}' :\n{e}") print("Creating Desktop shortcut...") try: desktop = f"C:\\Users\\{user}\\OneDrive - LEAF Commercial Capital\\Desktop" shell = win32com.client.Dispatch("WScript.Shell") shortcut = shell.CreateShortCut(os.path.join(desktop, "IL Extract v3.10.lnk"),) shortcut.Targetpath = f"{install_folder}\\IL Extract\\IL Extract.exe" shortcut.IconLocation = f"{install_folder}\\IL Extract\\assets\\extract.ico" shortcut.WorkingDirectory = f"{install_folder}\\IL Extract" shortcut.save() except: try: desktop = f"C:\\Users\\{user}\\Desktop" shell = win32com.client.Dispatch("WScript.Shell") shortcut = shell.CreateShortCut(os.path.join(desktop, "IL Extract v3.10.lnk"),) shortcut.Targetpath = f"{install_folder}\\IL Extract\\IL Extract.exe" shortcut.IconLocation = f"{install_folder}\\IL Extract\\assets\\extract.ico" shortcut.WorkingDirectory = f"{install_folder}\\IL Extract" shortcut.save() except Exception as e: error_exit(f"Failed to create shortcut. The application is still installed at:\n{install_folder}\\IL Extract.\nYou can manually create a shortcut if you would like.\n{e}") print(f"\nInstallation Completed Successfully!") input("\nPress Enter/Return to exit.") except Exception as e: error_exit(f"High level exception:\n{e}")