def uninstall_dependencies(packet: PortablePacket, metadata: Metadata): disp = str(packet.dependencies).replace("[", "").replace("]", "").replace("\'", "") write(f'{packet.display_name} has the following dependencies: {disp}', 'bright_yellow', metadata) continue_install = confirm( 'Would you like to uninstall the above dependencies ?') if continue_install: write(f'Uninstalling Dependencies For => {packet.display_name}', 'cyan', metadata) for package_name in packet.dependencies: os.system(f'electric uninstall {package_name}')
def handle_sublime_extension(package_name: str, mode: str, metadata: Metadata): """ Installs a sublime text package handling metadata for the method #### Arguments package_name (str): The name of the sublime text package to be installed version (str): The version of the sublime text package to be installed mode (str): The method (installation/uninstallation) metadata (`Metadata`): Metadata for the method """ if mode != 'install': return if utils.find_existing_installation('sublime-text-3', 'Sublime Text 3'): location = PathManager.get_appdata_directory().replace('\electric', '') + \ '\Sublime Text 3' if os.path.isdir(location) and os.path.isfile(fr'{location}\Packages\User\Package Control.sublime-settings'): with open(fr'{location}\Packages\User\Package Control.sublime-settings', 'r') as f: lines = f.readlines() idx = 0 for line in lines: if '"Package Control",' in line.strip(): idx = lines.index(line) if ']' in lines[idx + 1].strip(): lines[idx] = " \"Package Control\"" with open(fr'{location}\Packages\User\Package Control.sublime-settings', 'w') as f: f.writelines(lines) with open(fr'{location}\Packages\User\Package Control.sublime-settings', 'r') as f: json = js.load(f) current_packages = json['installed_packages'] if package_name in current_packages: write(f'{package_name} Is Already Installed!', 'white', metadata) sys.exit() current_packages.append(package_name) updated_packages = current_packages del json['installed_packages'] json['installed_packages'] = updated_packages with open(fr'{location}\Packages\User\Package Control.sublime-settings', 'w+') as f: f.write(js.dumps(json, indent=4)) write( f'Successfully Added {package_name} to Sublime Text 3', 'white', metadata) else: if not os.path.isdir(location): os.mkdir(location) if not os.path.isdir(fr'{location}\Installed Packages'): os.mkdir(fr'{location}\Installed Packages') # Package Control Not Installed with Halo('Installing Package Control', text_color='cyan'): urlretrieve('https://packagecontrol.io/Package%20Control.sublime-package', fr'{location}\Installed Packages\Package Control.sublime-package') if not os.path.isdir(fr'{location}\Packages'): os.mkdir(fr'{location}\Packages') if not os.path.isdir(fr'{location}\Packages\User'): os.mkdir(fr'{location}\Packages\User') with open(fr'{location}\Packages\User\Package Control.sublime-settings', 'w+') as f: f.write( js.dumps({ "bootstrapped": True, "installed_packages": [ "Package Control" ]}, indent=4 ) ) handle_sublime_extension(package_name, mode, metadata) else: click.echo(click.style( 'Sublime Text 3 Is Not Installed. Exit Code [0112]', fg='bright_yellow')) utils.disp_error_msg(utils.get_error_message( '0112', 'install', package_name, None, metadata, package_name), metadata) utils.handle_exit('error', '', metadata)
def handle_vscode_extension(package_name: str, requested_version: str, mode: str, metadata: Metadata): """ Installs a visual studio code package handling metadata for the method #### Arguments package_name (str): The name of the visual studio code package to be installed version (str): The version of the visual studio code package to be installed mode (str): The method (installation/uninstallation) metadata (`Metadata`): Metadata for the method """ base_c = 'code' output = Popen(mslex.split('code --version'), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) version, _ = output.communicate() version = version.decode() if output.returncode != 0: output = Popen(mslex.split('code-insiders --version'), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) version, _ = output.communicate() version = version.decode() base_c = 'code-insiders' if output.returncode != 0: click.echo(click.style( 'Visual Studio Code Or vscode Is Not Installed. Exit Code [0111]', fg='bright_yellow')) utils.disp_error_msg(utils.get_error_message( '0111', 'install', package_name, None, metadata, package_name), metadata) utils.handle_exit('error', '', metadata) version = version.strip().split('\n')[0] if mode == 'install': add_str = f"@{requested_version}" if requested_version else "" command = f'{base_c} --install-extension {package_name}{add_str} --force' proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) success = False for line in proc.stdout: line = line.decode() if 'Installing extensions' in line: if metadata.no_color: write( f'Code v{version} :: Installing {package_name}', 'white', metadata) else: write( f'Code v{version} :: Installing {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.RESET}', 'bright_green', metadata) if 'is already installed' in line: success = True if metadata.no_color: write( f'Code v{version} :: {package_name} Is Already Installed!', 'white', metadata) else: write( f'{Fore.LIGHTGREEN_EX}Code v{version} :: {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.LIGHTYELLOW_EX} Is Already Installed!', 'white', metadata) if 'was successfully installed' in line: if metadata.no_color: write( f'Code v{version} :: Successfully Installed {package_name}', 'white', metadata) success = True else: write( f'{Fore.LIGHTGREEN_EX}Code v{version} :: Successfully Installed {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.RESET}', 'bright_green', metadata) if not success: write( f'{Fore.LIGHTGREEN_EX}Code v{version} :: Successfully Installed {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.RESET}', 'bright_green', metadata) if mode == 'uninstall': add_str = f"@{requested_version}" if requested_version else "" command = f'{base_c} --uninstall-extension {package_name}{add_str} --force' proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) for line in proc.stdout: line = line.decode() if 'Uninstalling' in line: if metadata.no_color: write(f'Code v{version} :: Uninstalling {package_name}', 'white', metadata) else: write( f'Code v{version} :: Uninstalling {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.RESET}', 'bright_green', metadata) if 'is not installed' in line: if metadata.no_color: write(f'Code v{version} :: {package_name} is not installed!', 'white', metadata) else: write(f'{Fore.LIGHTGREEN_EX}Code v{version} :: {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.LIGHTYELLOW_EX} is not installed!', 'white', metadata) if 'was successfully uninstalled' in line: if metadata.no_color: write(f'Code v{version} :: Successfully Uninstalled {package_name}', 'white', metadata) else: write(f'{Fore.LIGHTGREEN_EX}Code v{version} :: Successfully Uninstalled {Fore.LIGHTMAGENTA_EX}{package_name}{Fore.RESET}', 'bright_green', metadata)
def handle_python_package(package_name: str, version: str, mode: str, metadata: Metadata): """ Installs a python package handling metadata for the method #### Arguments package_name (str): The name of the python package to be installed version (str): The version of the python package to be installed mode (str): The method (installation/uninstallation) metadata (`Metadata`): Metadata for the method """ command = '' valid = Popen(mslex.split('pip --version'), stdin=PIPE, stdout=PIPE, stderr=PIPE) _, err = valid.communicate() if err: click.echo(click.style( 'Python Is Not Installed. Exit Code [0011]', fg='red')) utils.disp_error_msg(utils.get_error_message( '0011', 'install', package_name, None, metadata, package_name), metadata) utils.handle_exit('ERROR', None, metadata) if mode == 'install': command = 'python -m pip install --upgrade --no-input' command += f' {package_name}' if version != 'latest': command += f'=={version}' proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE) py_version = sys.version.split() for line in proc.stdout: line = line.decode('utf-8') if f'Collecting {package_name}' in line: write( f'Python v{py_version[0]} :: Collecting {package_name}', 'bright_green', metadata) if 'Downloading' in line and package_name in line: write( f'Python v{py_version[0]} :: Downloading {package_name}', 'bright_green', metadata) if 'Installing collected packages' in line and package_name in line: write( f'Python v{py_version[0]} :: Installing {package_name}', 'bright_green', metadata) if f'Requirement ' in line and package_name in line: write( f'Python v{py_version[0]} :: {package_name} Is Already Installed And On The Latest Version ==> {line.split()[-1]}', 'bright_yellow', metadata) break if 'Successfully installed' in line and package_name in line: ver = line.split('-')[1] write( f'Python v{py_version[0]} :: Successfully Installed {package_name} {ver}', 'bright_green', metadata) if 'You should consider upgrading via' in line: wants = utils.confirm( 'Would you like to upgrade your pip version?') if wants: write('Updating Pip Version', 'bright_green', metadata) Popen(mslex.split('python -m pip install --upgrade pip')) elif mode == 'uninstall': command = 'python -m pip uninstall --no-input --yes' command += f' {package_name}' if version: command += f'=={version}' proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE) py_version = sys.version.split() for line in proc.stdout: line = line.decode('utf-8') if 'Uninstalling' in line and package_name in line: write( f'Python v{py_version[0]} :: Uninstalling {package_name}', 'bright_green', metadata) if 'Successfully uninstalled' in line and package_name in line: ver = line.split('-')[1] write( f'Python v{py_version[0]} :: Successfully Uninstalled {package_name} {ver}', 'bright_green', metadata) _, err = proc.communicate() if err: err = err.decode('utf-8') if f'WARNING: Skipping {package_name}' in err: write( f'Python v{py_version[0]} :: Could Not Find Any Installations Of {package_name}', 'bright_yellow', metadata)
def handle_node_package(package_name: str, mode: str, requested_version: str, metadata: Metadata): """ Installs a node/npm package handling metadata for the method #### Arguments package_name (`str`): The name of the node/npm package to be installed version (`str`): The version of the node/npm package to be installed mode (`str`): The method (installation/uninstallation) metadata (`Metadata`): Metadata for the method """ version_proc = Popen(mslex.split('npm --version'), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) version, err = version_proc.communicate() version = version.decode().strip() if err: click.echo(click.style( 'npm Or node Is Not Installed. Exit Code [0011]', fg='bright_yellow')) utils.disp_error_msg(utils.get_error_message( '0011', 'install', package_name, None, metadata, package_name), metadata) utils.handle_exit('ERROR', None, metadata) if mode == 'install': add_str = f"@{requested_version}" if requested_version else "" command = f'npm i {package_name} -g' + add_str proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) write(f'npm v{version} :: Collecting {package_name}', 'bright_green', metadata) package_version = None for line in proc.stdout: line = line.decode() if 'node install.js' in line: write( f'npm v{version} :: Running `node install.js` for {package_name}', 'bright_green', metadata) if package_name in line and '@' in line and 'install' in line or ' postinstall' in line: package_version = line.split()[1] write( f'npm v{version} :: {package_version} Installing To <=> "{line.split()[3]}"', 'bright_green', metadata) if 'Success' in line and package_name in line or 'added' in line: write( f'npm v{version} :: Successfully Installed {package_version}', 'bright_green', metadata) elif package_name in line and '@' in line: package_version = line.replace( '+ ', '').replace(package_name, '').strip() if 'updated' in line: if package_version: write( f'npm v{version} :: Sucessfully Updated {package_name}{package_version}', 'bright_green', metadata) else: write( f'npm v{version} :: Sucessfully Updated {package_name}', 'bright_green', metadata) else: add_str = f"@{requested_version}" if requested_version else "" command = f'npm uninstall {package_name} -g' + add_str proc = Popen(mslex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) for line in proc.stdout: line = line.decode() if 'audited' in line and 'packages' in line: number = line.split()[1].strip() time = line.split()[4].strip() write(f'npm v{version} :: Successfully Uninstalled {package_name} and {number} Other Dependencies in {time}', 'bright_green', metadata) if 'up to date' in line: write( f'npm v{version} :: Could Not Find Any Existing Installations Of {package_name}', 'bright_yellow', metadata) if 'removed' in line: print(line) number = line.split(' ')[1].strip() time = line.split(' ')[4].strip() write( f'npm v{version} :: Sucessfully Uninstalled {package_name} And {number} Other Dependencies in {time}', 'bright_green', metadata)
def install_dependent_packages(packet: Packet, rate_limit: int, install_directory: str, metadata): from limit import Limiter, TokenBucket from registry import get_environment_keys disp = str(packet.dependencies).replace( "[", "").replace("]", "").replace("\'", "") write(f'{packet.display_name} has the following dependencies: {disp}', 'bright_yellow', metadata) continue_install = confirm( 'Would you like to install the above dependencies ?') if continue_install: write( f'Installing Dependencies For => {packet.display_name}', 'cyan', metadata) if len(packet.dependencies) > 1 and len(packet.dependencies) <= 5: write( f'Using Parallel Installation For Installing Dependencies', 'bright_green', metadata) packets = [] for package in packet.dependencies: res = utils.send_req_package(package) pkg = res keys = list(pkg.keys()) idx = 0 for key in keys: if key not in ['package-name', 'nightly', 'display-name']: idx = keys.index(key) break version = keys[idx] pkg = pkg[version] custom_dir = None if install_directory: custom_dir = install_directory + \ f'\\{pkg["package-name"]}' else: custom_dir = install_directory install_exit_codes = None if 'valid-install-exit-codes' in list(pkg.keys()): install_exit_codes = pkg['valid-install-exit-codes'] packet = Packet( package, res['package-name'], pkg['url'], pkg['file-type'], pkg['clswitch'], pkg['iswitches'], pkg['uswitches'], custom_dir, pkg['dependencies'], install_exit_codes, None, pkg['set-env'] if 'set-env' in list( pkg.keys()) else None, pkg['default-install-dir'] if 'default-install-dir' in list( pkg.keys()) else None, pkg['uninstall'] if 'uninstall' in list( pkg.keys()) else [], pkg['add-path'] if 'add-path' in list( pkg.keys()) else None, pkg['checksum'] if 'checksum' in list( pkg.keys()) else None, pkg['bin'] if 'bin' in list(pkg.keys()) else None, pkg['pre-update'] if 'pre-update' in list( pkg.keys()) else None, ) installation = utils.find_existing_installation( package, packet.json_name) if installation: write_debug( f'Aborting Installation As {packet.json_name} is already installed.', metadata) write_verbose( f'Found an existing installation of => {packet.json_name}', metadata) write( f'Found an existing installation {packet.json_name}.', 'bright_yellow', metadata) write_verbose( f'Package to be installed: {packet.json_name}', metadata) log_info( f'Package to be installed: {packet.json_name}', metadata.logfile) write_verbose( f'Finding closest match to {packet.json_name}...', metadata) log_info( f'Finding closest match to {packet.json_name}...', metadata.logfile) packets.append(packet) write_verbose( 'Generating system download path...', metadata) log_info('Generating system download path...', metadata.logfile) manager = ThreadedInstaller(packets, metadata) paths = manager.handle_multi_download() log_info('Finished Rapid Download...', metadata.logfile) log_info( 'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...', metadata.logfile) manager.handle_multi_install(paths) return else: write('Starting Sync Installation', 'bright_green', metadata) for package in packet.dependencies: res = utils.send_req_package(package) write( f'SuperCached [ {Fore.LIGHTCYAN_EX}{res["display-name"]}{Fore.RESET} ]', 'white', metadata) pkg = res[res['latest-version']] log_info( 'Generating Packet For Further Installation.', metadata.logfile) install_exit_codes = None if 'valid-install-exit-codes' in list(pkg.keys()): install_exit_codes = pkg['valid-install-exit-codes'] packet = Packet( res, res['package-name'], res['display-name'], pkg['url'], pkg['file-type'], pkg['clswitch'], pkg['iswitches'], pkg['uswitches'], install_directory, pkg['dependencies'], install_exit_codes, [], None, False, pkg['set-env'] if 'set-env' in list( pkg.keys()) else None, pkg['default-install-dir'] if 'default-install-dir' in list( pkg.keys()) else None, pkg['uninstall'] if 'uninstall' in list( pkg.keys()) else [], pkg['add-path'] if 'add-path' in list( pkg.keys()) else None, pkg['checksum'] if 'checksum' in list( pkg.keys()) else None, pkg['bin'] if 'bin' in list(pkg.keys()) else None, pkg['pre-update'] if 'pre-update' in list( pkg.keys()) else None, ) log_info( 'Searching for existing installation of package.', metadata.logfile) installation = utils.find_existing_installation( package, packet.json_name) if installation: write_debug( f'Found existing installation of {packet.json_name}.', metadata) write_verbose( f'Found an existing installation of => {packet.json_name}', metadata) write( f'Found an existing installation {packet.json_name}.', 'bright_yellow', metadata) continue if packet.dependencies: ThreadedInstaller.install_dependent_packages( packet, rate_limit, install_directory, metadata) write_verbose( f'Package to be installed: {packet.json_name}', metadata) log_info( f'Package to be installed: {packet.json_name}', metadata.logfile) write_verbose( 'Generating system download path...', metadata) log_info('Generating system download path...', metadata.logfile) download_url = packet.win64 log_info('Initializing Rapid Download...', metadata.logfile) # Downloading The File From Source write_debug( f'Downloading {packet.display_name} from => {packet.win64}', metadata) write_verbose( f"Downloading from '{download_url}'", metadata) log_info( f"Downloading from '{download_url}'", metadata.logfile) if rate_limit == -1: path = utils.download( download_url, packet.json_name, metadata, packet.win64_type) else: log_info( f'Starting rate-limited installation => {rate_limit}', metadata.logfile) bucket = TokenBucket( tokens=10 * rate_limit, fill_rate=rate_limit) limiter = Limiter( bucket=bucket, filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}', ) from urllib.request import urlretrieve urlretrieve( url=download_url, filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}', reporthook=limiter ) path = f'{tempfile.gettempdir()}\Setup{packet.win64_type}' log_info('Finished Rapid Download', metadata.logfile) if metadata.virus_check: write('Scanning File For Viruses...', 'bright_cyan', metadata) utils.check_virus(path, metadata) write( f'Installing {packet.display_name}', 'cyan', metadata) log_info( 'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...', metadata.logfile) write_verbose('Creating registry start snapshot', metadata) log_info('Creating start snapshot of registry...', metadata.logfile) start_snap = get_environment_keys() write_debug( f'Installing {packet.json_name} through Setup{packet.win64_type}', metadata) log_info( f'Installing {packet.json_name} through Setup{packet.win64_type}', metadata.logfile) # Running The Installer silently And Completing Setup utils.install_package(path, packet, metadata) changes_environment = False if packet.shim: changes_environment = True for shim in packet.shim: replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir shim = shim.replace( '<install-directory>', replace_install_dir).replace('<version>', packet.version) shim_name = shim.split( "\\")[-1].split('.')[0].replace('<version>', packet.version) write( f'Generating Shim For {shim_name}', 'cyan', metadata) utils.generate_shim( shim, shim_name, shim.split('.')[-1]) if packet.add_path: replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Appending "{packet.add_path.replace("<install-directory>", replace_install_dir)}" To PATH', 'bright_green', metadata) utils.append_to_path(packet.add_path.replace( '<install-directory>', replace_install_dir)) if packet.set_env: if isinstance(packet.set_env, list): for obj in packet.set_env: name = obj['name'] replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Setting Environment Variable {name}', 'bright_green', metadata) write_verbose( f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata) log_info( f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile) set_environment_variable( name, obj['value'].replace('<install-directory>', replace_install_dir)) else: name = packet.set_env['name'] replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Setting Environment Variable {name}', 'bright_green', metadata) write_verbose( f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata) log_info( f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile) set_environment_variable( name, packet.set_env['value'].replace('<install-directory>', replace_install_dir)) write_verbose( 'Creating Final Snapshot Of Environment Keys', metadata) final_snap = get_environment_keys() if final_snap.env_length > start_snap.env_length or final_snap.sys_length > start_snap.sys_length or changes_environment: write('The PATH environment variable has changed. Run `refreshenv` to refresh your environment variables.', 'bright_green', metadata) write_verbose( 'Successfully Verified Installation Of Packages', metadata) write( f'Successfully Installed {packet.display_name}', 'bright_magenta', metadata) log_info( f'Successfully Installed {packet.display_name}', metadata.logfile) utils.register_package_success( packet, install_directory, metadata) if metadata.reduce_package: os.remove(path) try: os.remove( Rf'{tempfile.gettempdir()}\downloadcache.pickle') except: pass log_info( 'Successfully Cleaned Up Installer From Temporary Directory And DownloadCache', metadata.logfile) write('Successfully Cleaned Up Installer From Temp Directory...', 'bright_green', metadata) write_verbose( 'Dependency successfully Installed.', metadata) log_info('Dependency successfully Installed.', metadata.logfile) else: os._exit(1)
def handle_multi_install(self, paths): from time import strftime write_debug('Initialising Rapid Install Procedure...', self.metadata) processes = [] install_items = self.generate_installers(paths) idx = 0 for item in install_items: if 'msi' in list(item.keys()): for val in item['msi']: self.install_package(val) continue else: from multiprocessing import Process string = '' string = 'other' if 'other' in list(item.keys()) else 'exe' for val in item[string]: write_debug( f'Running Installer For <{val.display_name}> On Thread {item[string].index(val)}', self.metadata) processes.append( Process( target=self.install_package, args=(val,)) ) for process in processes: process.start() for x in processes: x.join() processes.clear() idx += 1 if self.metadata.reduce_package: for path in paths: os.remove(path) write('Successfully Cleaned Up Installer From Temp Directory...', 'bright_green', self.metadata) for packet in self.packets: metadata = self.metadata if packet.add_path: replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Appending "{packet.add_path.replace("<install-directory>", replace_install_dir)}" To PATH', 'bright_green', metadata) write_verbose( f'Appending "{packet.add_path.replace("<install-directory>", replace_install_dir)}" To PATH', metadata) log_info( f'Appending "{packet.add_path.replace("<install-directory>", replace_install_dir)}" To PATH', metadata.logfile) utils.append_to_path(packet.add_path.replace( '<install-directory>', replace_install_dir)) if packet.set_env: if isinstance(packet.set_env, list): for obj in packet.set_env: name = obj['name'] replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Setting Environment Variable {name}', 'bright_green', metadata) write_verbose( f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata) log_info( f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile) set_environment_variable( name, obj['value'].replace('<install-directory>', replace_install_dir)) else: name = packet.set_env['name'] replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir write( f'Setting Environment Variable {name}', 'bright_green', metadata) write_verbose( f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata) log_info( f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile) set_environment_variable( name, packet.set_env['value'].replace('<install-directory>', replace_install_dir)) if packet.shim: for shim in packet.shim: replace_install_dir = '' if packet.directory: replace_install_dir = packet.directory elif packet.default_install_dir: replace_install_dir = packet.default_install_dir shim = shim.replace( '<install-directory>', replace_install_dir).replace('<version>', packet.version) shim_name = shim.split( "\\")[-1].split('.')[0].replace('<version>', packet.version) write( f'Generating Shim For {shim_name}', 'cyan', metadata) utils.generate_shim( shim, shim_name, shim.split('.')[-1]) utils.register_package_success( packet, packet.directory, self.metadata) write('The PATH environment variable has changed. Run `refreshenv` to refresh your environment variables.', 'green', self.metadata) write( 'Successfully Installed Packages!', 'bright_magenta', self.metadata) log_info('Successfully Installed Packages!', self.metadata.logfile) log_info('Refreshing Environment Variables', self.metadata.logfile) write_debug( 'Refreshing Env Variables, Calling Batch Script', self.metadata) write_verbose('Refreshing Environment Variables', self.metadata) write_debug( f'Successfully Refreshed Environment Variables', self.metadata) write_verbose('Installation and setup completed.', self.metadata) log_info('Installation and setup completed.', self.metadata.logfile) write_debug( f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion', self.metadata) log_info( f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion', self.metadata.logfile) if self.metadata.logfile: close_log(self.metadata.logfile, 'Install')
def handle_multi_download(self) -> list: from threading import Thread self.handle_dependencies() metadata = self.metadata package_list = [packet.display_name for packet in self.packets] package_list = str(package_list).replace( '[', '').replace(']', '').replace('\'', '') if not metadata.no_color: write( f'SuperCached [ {Fore.LIGHTCYAN_EX}{package_list}{Fore.RESET} ]', 'white', metadata) else: write( f'SuperCached [ {package_list} ]', 'white', metadata) log_info('Initializing Rapid Download', metadata.logfile) packets = self.packets download_items = [] if len(packets) > 1: for idx, packet in enumerate(packets): download_items.append(Download(packet.win64, packet.win64_type, f'Setup{idx}', packet.display_name, f"{tempfile.gettempdir()}\\electric\\Setup{idx}{packet.win64_type}")) elif len(packets) == 1: download_items.append(Download(packets[0].win64, packets[0].win64_type, 'Setup0', packets[0].display_name, f"{tempfile.gettempdir()}\\electric\\Setup0{packets[0].win64_type}")) for item in download_items: write_verbose( f'Sending request to {item.url} for downloading {item.display_name}', self.metadata) write_debug( f'Downloading {item.display_name} from {item.url} into {item.name}{item.extension}', self.metadata) method = self.calculate_spwn(len(packets)) if method == 'threading': threads = [ Thread(target=self.download, args=(item,)) for item in download_items ] for thread in threads: thread.start() for x in threads: x.join() if method == 'processing': from multiprocessing import Process processes = [Process( target=self.download, args=(item,)) for item in download_items] for process in processes: process.start() for x in processes: x.join() for item in download_items: if self.metadata.virus_check: write( f'\nScanning {item.display_name} For Viruses...', 'bright_cyan', metadata) utils.check_virus(item.path, metadata, None) write_debug( f'Rapid Download Successfully Downloaded {len(download_items)} Packages Using RapidThreading', metadata, newline=True) write_debug('Rapid Download Exiting With Code 0', metadata) if not self.metadata.debug: write('\nSuccessfully Downloaded Installation Files', 'bright_green', metadata) else: write('Successfully Downloaded Installation Files', 'bright_green', metadata) log_info('Finished Rapid Download', metadata.logfile) write_verbose('Running Installers Using Multi-Threading', metadata) write( 'Installing Packages', 'cyan', metadata) log_info( 'Using Rapid Install To Complete Setup, Accept ompts Asking For Admin Permission...', metadata.logfile) return paths
def uninstall_portable(packet: PortablePacket, metadata: Metadata): if find_existing_installation( f'{packet.extract_dir}@{packet.latest_version}'): loc = rf'{home}\electric\\' if packet.dependencies: log_info(f'Uninstalling dependencies for {packet.display_name}', metadata.logfile) uninstall_dependencies(packet, metadata) if packet.bin: log_info( rf'Deleting shims for {packet.display_name} from {loc}\shims', metadata.logfile) write(f'Deleting Shims For {packet.display_name}', 'cyan', metadata) for sh in packet.bin: if isinstance(sh, str): shim_name = sh.split('\\')[-1].split('.')[0] try: os.remove(loc + 'shims\\' + shim_name + '.bat') except FileNotFoundError: pass else: shim_name = sh['shim-name'].split('\\')[-1].split('.')[0] try: os.remove(loc + 'shims\\' + shim_name + '.bat') except FileNotFoundError: pass shortcuts = packet.shortcuts if shortcuts: log_info(f'Deleting shortcuts for {packet.display_name}', metadata.logfile) write(f'Deleting Shortcuts For {packet.display_name}', 'cyan', metadata) for shortcut in shortcuts: try: delete_start_menu_shortcut(shortcut['shortcut-name']) except FileNotFoundError: pass if packet.set_env: write(f'Deleting {packet.set_env["name"]} Environment Variable', 'bright_green', metadata) delete_environment_variable(packet.set_env['name']) log_info( f'Deleting folders related to {packet.display_name}@{packet.latest_version}', metadata.logfile) write(f'Uninstalling {packet.display_name}', 'bright_green', metadata) package_directory = loc + f'{packet.extract_dir}@{packet.latest_version}' proc = Popen(f'del /f/s/q {package_directory} > nul'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) proc.communicate() proc = Popen(f'rmdir /s/q {package_directory}'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) proc.communicate() loc = rf'{home}\electric\shims' if packet.set_env: if isinstance(packet.set_env, list): changes_environment = True for obj in packet.set_env: log_info( f'Setting environment variables for {packet.display_name}', metadata.logfile) write(f'Setting Environment Variable {obj["name"]}', 'bright_green', metadata) delete_environment_variable(obj['name']) else: log_info( f'Removing environment variables for {packet.display_name}', metadata.logfile) write( f'Deleting Environment Variable {packet.set_env["name"]}', 'bright_green', metadata) delete_environment_variable(packet.set_env["name"]) if packet.uninstall_notes: display_notes(packet, '', metadata, uninstall=True) write(f'Successfully Uninstalled {packet.display_name}', 'bright_magenta', metadata) else: write( f'Could Not Find Any Existing Installations Of {packet.display_name}', 'bright_yellow', metadata)
def install_portable(packet: PortablePacket, metadata: Metadata): if find_existing_installation( f'{packet.extract_dir}@{packet.latest_version}'): write(f'Found Existing Installation Of {packet.display_name}', 'bright_yellow', metadata) continue_installation = confirm( f'Would you like to reinstall {packet.display_name}?') if continue_installation: pass else: sys.exit() if packet.dependencies: install_dependencies(packet, metadata) changes_environment = False shortcuts = packet.shortcuts extract_dir = packet.extract_dir write_debug( f'Downloading {packet.json_name}{packet.file_type} from {packet.url}', metadata) log_info( f'Downloading {packet.json_name}{packet.file_type} from {packet.url}', metadata) show_progress_bar = True if not metadata.silent and not metadata.no_progress else False if isinstance(packet.url, str): download(packet, packet.url, '.zip', rf'{home}\electric\\' + f'{packet.extract_dir}@{packet.latest_version}', metadata, show_progress_bar=show_progress_bar, is_zip=True) unzip_dir = unzip_file( f'{packet.extract_dir}@{packet.latest_version}' + '.zip', extract_dir, packet.file_type, metadata) elif isinstance(packet.url, list): idx = 0 for url in packet.url: if idx == 0: download(packet, url['url'], '.zip', rf'{home}\electric\\' + f'{packet.extract_dir}@{packet.latest_version}', metadata, show_progress_bar=show_progress_bar, is_zip=True) unzip_dir = unzip_file( f'{packet.extract_dir}@{packet.latest_version}' + '.zip', extract_dir, url['file-type'], metadata) else: write(f'Downloading {url["file-name"]}{url["file-type"]}', 'cyan', metadata) download( packet, url['url'], url['file-type'], rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}\\{url["file-name"]}', metadata, show_progress_bar=False, is_zip=False) idx += 1 if packet.pre_install: if packet.pre_install['type'] == 'powershell': packet.pre_install['code'] = [ l.replace('<dir>', unzip_dir.replace('\\\\', '\\')) for l in packet.pre_install['code'] ] packet.pre_install['code'] = [ l.replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' .replace('\\\\', '\\')) for l in packet.pre_install['code'] ] if not os.path.isdir(rf'{home}\electric\temp\Scripts'): try: os.mkdir(rf'{home}\electric\temp') except: # temp directory already exists pass os.mkdir(rf'{home}\electric\temp\Scripts') with open(rf'{home}\electric\temp\Scripts\temp.ps1', 'w+') as f: for line in packet.pre_install['code']: f.write(f'\n{line}') os.system( rf'powershell -executionpolicy bypass -File {home}\electric\temp\Scripts\temp.ps1' ) write('Successfully Executed Pre-Install Code', 'bright_green', metadata) if packet.pre_install['type'] == 'bat' or packet.pre_install[ 'type'] == 'cmd': packet.pre_install['code'] = [ l.replace('<dir>', unzip_dir.replace('\\\\', '\\')) for l in packet.pre_install['code'] ] packet.pre_install['code'] = [ l.replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' .replace('\\\\', '\\')) for l in packet.pre_install['code'] ] if not os.path.isdir(rf'{home}\electric\temp\Scripts'): try: os.mkdir(rf'{home}\electric\temp') except: # temp directory already exists pass os.mkdir(rf'{home}\electric\temp\Scripts') with open(rf'{home}\electric\temp\Scripts\temp.bat', 'w+') as f: for line in packet.pre_install['code']: f.write(f'\n{line}') os.system(rf'{home}\electric\temp\Scripts\temp.bat') write('Successfully Executed Pre-Install Code', 'bright_green', metadata) if packet.pre_install['type'] == 'python': code = '''''' for l in packet.pre_install['code']: code += l + '\n' exec(code) if packet.chdir: dir = packet.chdir unzip_dir += f'\\{dir}\\' if packet.bin: if isinstance(packet.bin, list): for bin in packet.bin: shim_dir = unzip_dir shim = ''.join(bin.split('.')[:-1]) shim_ext = bin.split('.')[-1] if '\\' in bin: shim = ''.join(bin.split('\\')[-1]) shim = ''.join(shim.split('.')[:-1]) shim_ext = bin.split('.')[-1] shim_dir += ' '.join(bin.split('\\')[:-1]).replace( ' ', '\\') start = timer() generate_shim(f'{shim_dir}', shim, shim_ext) end = timer() write( f'{Fore.LIGHTCYAN_EX}Successfully Generated {shim} Shim In {round(end - start, 5)} seconds{Fore.RESET}', 'white', metadata) if shortcuts: for shortcut in shortcuts: shortcut_name = shortcut['shortcut-name'] file_name = shortcut['file-name'] create_start_menu_shortcut(unzip_dir, file_name, shortcut_name) if packet.set_env: changes_environment = True write(f'Setting Environment Variable {packet.set_env["name"]}', 'bright_green', metadata) set_environment_variable( packet.set_env['name'], packet.set_env['value'].replace('<install-directory>', unzip_dir).replace('\\\\', '\\')) if changes_environment: write( f'{Fore.LIGHTGREEN_EX}Refreshing Environment Variables{Fore.RESET}', 'white', metadata) refresh_environment_variables() if packet.post_install: for line in packet.post_install: exec( line.replace('<install-directory>', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' )) if packet.install_notes: display_notes(packet, unzip_dir, metadata) write(f'Successfully Installed {packet.display_name}', 'magenta', metadata)
def update_portable(ctx, packet: PortablePacket, metadata: Metadata): import shutil import click from difflib import get_close_matches write(f'Updating [ {Fore.LIGHTCYAN_EX}{packet.display_name}{Fore.RESET} ]', 'white', metadata) options = os.listdir(rf'{home}\electric') matches = get_close_matches( rf'{home}\electric\{packet.json_name}@{packet.latest_version}', options) if len(matches) == 1: # similar package exists and we need to get the version of the currently installed package. current_version = matches[0].split('@')[-1].replace('.json', '') if current_version != packet.latest_version: write( f'{packet.display_name} Will Be Updated From ({current_version}) => ({packet.latest_version})', 'green', metadata) write('Requesting Currently Installed Version', 'yellow', metadata) REQA = 'https://raw.githubusercontent.com/electric-package-manager/electric-packages/master/packages/' try: response = requests.get(REQA + packet.json_name + '.json', timeout=5) except (requests.exceptions.ConnectionError, requests.exceptions.ReadTimeout): click.echo( click.style( f'Failed to request {packet.json_name}.json from raw.githubusercontent.com', 'red')) sys.exit() try: res = json.loads(response.text) except JSONDecodeError: click.echo(click.style(f'{packet.json_name} not found!', 'red')) sys.exit() pkg = res pkg = pkg['portable'] keys = list(pkg[current_version].keys()) data = { 'display-name': res['display-name'], 'package-name': res['package-name'], 'latest-version': res['latest-version'], 'url': pkg[current_version]['url'], 'file-type': pkg[current_version]['file-type'] if 'file-type' in keys else None, 'extract-dir': res['package-name'], 'chdir': pkg[current_version]['chdir'] if 'chdir' in keys else [], 'bin': pkg[current_version]['bin'] if 'bin' in keys else [], 'shortcuts': pkg[current_version]['shortcuts'] if 'shortcuts' in keys else [], 'pre-install': pkg[current_version]['pre-install'] if 'pre-install' in keys else [], 'post-install': pkg[current_version]['post-install'] if 'post-install' in keys else [], 'install-notes': pkg[current_version]['install-notes'] if 'install-notes' in keys else None, 'uninstall-notes': pkg[current_version]['uninstall-notes'] if 'uninstall-notes' in keys else None, 'set-env': pkg[current_version]['set-env'] if 'set-env' in keys else None, 'persist': pkg[current_version]['persist'] if 'persist' in keys else None, 'checksum': pkg[current_version]['checksum'] if 'checksum' in keys else None, 'dependencies': pkg[current_version]['dependencies'] if 'dependencies' in keys else None, } old_packet = PortablePacket(data) # continue updating the package # if a directory has to be saved before uninstallation and installation of the portable if old_packet.persist: install_directory = rf'{home}\electric\{old_packet.json_name}@{current_version}\\' if old_packet.chdir: install_directory += old_packet.chdir + '\\' install_directory = install_directory.replace('\\\\', '\\') if isinstance(old_packet.persist, list): for path in old_packet.persist: # multiple directories to backup try: shutil.copytree( install_directory + path, rf'{home}\electric\Persist\{old_packet.json_name}@{current_version}\{path}' ) except FileExistsError: pass else: # only 1 directory to backup if old_packet.persist: try: shutil.copytree( install_directory + old_packet.persist, rf'{home}\electric\Persist\{old_packet.json_name}@{current_version}\{old_packet.persist}' ) except FileExistsError: pass os.system(f'electric uninstall {packet.json_name} --portable') os.system(f'electric install {packet.json_name} --portable') new_install_dir = rf'{home}\electric\{packet.json_name}@{packet.latest_version}\\' if packet.chdir: new_install_dir += packet.chdir + '\\' new_install_dir = new_install_dir.replace('\\\\', '\\') if old_packet.persist: write('Restoring Old Files And Data', 'green', metadata) if isinstance(old_packet.persist, list): for path in old_packet.persist: shutil.rmtree(new_install_dir + path) shutil.copytree( rf'{home}\electric\Persist\{old_packet.json_name}@{current_version}\{path}', new_install_dir + path) else: shutil.rmtree( new_install_dir.replace('\\\\', '\\') + old_packet.persist.replace('\\\\', '\\')) shutil.copytree( rf'{home}\electric\Persist\{old_packet.json_name}@{current_version}\{old_packet.persist}', new_install_dir + old_packet.persist) # completed backup of files to backups directory write( rf'Successfully Completed Backup Of Required Data To {home}\electric\Persist', 'cyan', metadata) else: write( f'Could not find any existing installations of {packet.display_name}', 'red', metadata) write(f'Successfully Updated {packet.display_name}', 'bright_magenta', metadata) sys.exit()
def install_portable(packet: PortablePacket, metadata: Metadata): if find_existing_installation( f'{packet.extract_dir}@{packet.latest_version}'): log_info(f'Detected an existing installation of {packet.display_name}', metadata.logfile) write(f'Found Existing Installation Of {packet.display_name}', 'bright_yellow', metadata) continue_installation = confirm( f'Would you like to reinstall {packet.display_name}?') if not continue_installation: sys.exit() if packet.dependencies: log_info(f'Installing dependencies for {packet.display_name}', metadata.logfile) install_dependencies(packet, metadata) changes_environment = False shortcuts = packet.shortcuts extract_dir = packet.extract_dir write_debug( f'Downloading {packet.json_name}{packet.file_type} from {packet.url}', metadata) log_info( f'Downloading {packet.json_name}{packet.file_type} from {packet.url}', metadata.logfile) show_progress_bar = not metadata.silent and not metadata.no_progress if isinstance(packet.url, str): download(packet, packet.url, packet.file_type, rf'{home}\electric\\' + f'{packet.extract_dir}@{packet.latest_version}', metadata, show_progress_bar=show_progress_bar, is_zip=True) if packet.checksum: verify_checksum( rf'{home}\electric\\' + f'{packet.extract_dir}@{packet.latest_version}{packet.file_type}', packet.checksum, metadata) unzip_dir = unzip_file( f'{packet.extract_dir}@{packet.latest_version}' + packet.file_type, f'{extract_dir}@{packet.latest_version}', packet.file_type, metadata) elif isinstance(packet.url, list): for idx, url in enumerate(packet.url): if idx == 0: download(packet, url['url'], '.zip', rf'{home}\electric\\' + f'{packet.extract_dir}@{packet.latest_version}', metadata, show_progress_bar=show_progress_bar, is_zip=True) unzip_dir = unzip_file( f'{packet.extract_dir}@{packet.latest_version}' + '.zip', extract_dir, url['file-type'], metadata) else: write(f'Downloading {url["file-name"]}{url["file-type"]}', 'cyan', metadata) download( packet, url['url'], url['file-type'], rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}\\{url["file-name"]}', metadata, show_progress_bar=False, is_zip=False) if packet.pre_install: log_info('Executing pre install code', metadata.logfile) if packet.pre_install['type'] == 'powershell': packet.pre_install['code'] = [ l.replace('<dir>', unzip_dir.replace('\\\\', '\\')) for l in packet.pre_install['code'] ] packet.pre_install['code'] = [ l.replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' .replace('\\\\', '\\')) for l in packet.pre_install['code'] ] if not os.path.isdir(rf'{home}\electric\temp\Scripts'): try: os.mkdir(rf'{home}\electric\temp') except: # temp directory already exists pass os.mkdir(rf'{home}\electric\temp\Scripts') with open(rf'{home}\electric\temp\Scripts\temp.ps1', 'w+') as f: for line in packet.pre_install['code']: f.write(f'\n{line}') os.system( rf'powershell -executionpolicy bypass -File {home}\electric\temp\Scripts\temp.ps1' ) write('Successfully Executed Pre-Install Code', 'bright_green', metadata) if packet.pre_install['type'] in ['bat', 'cmd']: packet.pre_install['code'] = [ l.replace('<dir>', unzip_dir.replace('\\\\', '\\')) for l in packet.pre_install['code'] ] packet.pre_install['code'] = [ l.replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' .replace('\\\\', '\\')) for l in packet.pre_install['code'] ] if not os.path.isdir(rf'{home}\electric\temp\Scripts'): try: os.mkdir(rf'{home}\electric\temp') except: # temp directory already exists pass os.mkdir(rf'{home}\electric\temp\Scripts') with open(rf'{home}\electric\temp\Scripts\temp.bat', 'w+') as f: for line in packet.pre_install['code']: f.write(f'\n{line}') os.system(rf'{home}\electric\temp\Scripts\temp.bat') write('Successfully Executed Pre-Install Code', 'bright_green', metadata) if packet.pre_install['type'] == 'python': code = ''''''.join(l + '\n' for l in packet.pre_install['code']) exec(code) if packet.chdir: dir = packet.chdir.replace('<version>', packet.latest_version) unzip_dir += f'\\{dir}\\' if packet.bin and isinstance(packet.bin, list): for binary in packet.bin: if isinstance(binary, str): shim_dir = unzip_dir shim = ''.join(binary.split('.')[:-1]) shim_ext = binary.split('.')[-1] if '\\' in binary: shim = ''.join(binary.split('\\')[-1]) shim = ''.join(shim.split('.')[:-1]) shim_ext = binary.split('.')[-1] shim_dir += ' '.join(binary.split('\\')[:-1]).replace( ' ', '\\') shim = shim.replace('<version>', packet.latest_version) shim_dir = shim_dir.replace('<version>', packet.latest_version) start = timer() generate_shim(f'{shim_dir}', shim, shim_ext) end = timer() write( f'{Fore.LIGHTCYAN_EX}Successfully Generated {shim} Shim In {round(end - start, 5)} seconds{Fore.RESET}', 'white', metadata) else: val = binary['file-name'] shim_dir = unzip_dir shim = ''.join(val.split('.')[:-1]) shim_ext = val.split('.')[-1] if '\\' in val: shim = ''.join(val.split('\\')[-1]) shim = ''.join(shim.split('.')[:-1]) shim_ext = val.split('.')[-1] shim_dir += ' '.join(val.split('\\')[:-1]).replace( ' ', '\\') shim = shim.replace('<version>', packet.latest_version) shim_dir = shim_dir.replace('<version>', packet.latest_version) val = val.replace('<version>', packet.latest_version) start = timer() generate_shim(f'{shim_dir}', val.split('\\')[-1].split('.')[0], shim_ext, overridefilename=binary['shim-name']) end = timer() write( f'{Fore.LIGHTCYAN_EX}Successfully Generated {binary["shim-name"]} Shim In {round(end - start, 5)} seconds{Fore.RESET}', 'white', metadata) if shortcuts: for shortcut in shortcuts: shortcut_name = shortcut['shortcut-name'] file_name = shortcut['file-name'] log_info(f'Creating shortcuts for {packet.display_name}', metadata.logfile) create_start_menu_shortcut(unzip_dir, file_name, shortcut_name) if packet.set_env: if isinstance(packet.set_env, list): changes_environment = True for obj in packet.set_env: log_info( f'Setting environment variables for {packet.display_name}', metadata.logfile) write(f'Setting Environment Variable {obj["name"]}', 'bright_green', metadata) set_environment_variable( obj['name'], obj['value'].replace('<install-directory>', unzip_dir).replace('\\\\', '\\')) else: changes_environment = True log_info( f'Setting environment variables for {packet.display_name}', metadata.logfile) write(f'Setting Environment Variable {packet.set_env["name"]}', 'bright_green', metadata) set_environment_variable( packet.set_env['name'], packet.set_env['value'].replace( '<install-directory>', unzip_dir).replace('\\\\', '\\')) if changes_environment: log_info( 'Detected change in PATH variable. Requesting `refreshenv` to be run', metadata.logfile) write( f'{Fore.LIGHTGREEN_EX}The PATH environment variable has changed. Run `refreshenv` to refresh your environment variables.{Fore.RESET}', 'white', metadata) if packet.post_install: log_info('Executing post installation code', metadata.logfile) for line in packet.post_install: exec( line.replace('<install-directory>', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' )) if packet.install_notes: log_info('Found Installation Notes, Writing To Console.', metadata.logfile) display_notes(packet, unzip_dir, metadata) write(f'Successfully Installed {packet.display_name}', 'bright_magenta', metadata)
def uninstall_portable(packet: PortablePacket, metadata: Metadata): if find_existing_installation( f'{packet.extract_dir}@{packet.latest_version}'): loc = rf'{home}\electric\\' if packet.dependencies: uninstall_dependencies(packet, metadata) if packet.bin: write(f'Deleting Shims For {packet.display_name}', 'cyan', metadata) for sh in packet.bin: shim_name = sh.split('\\')[-1].replace('.exe', '').replace( '.ps1', '').replace('.cmd', '').replace('.bat', '') try: os.remove(loc + 'shims\\' + shim_name + '.bat') except FileNotFoundError: pass shortcuts = packet.shortcuts if shortcuts: write(f'Deleting Shortcuts For {packet.display_name}', 'cyan', metadata) for shortcut in shortcuts: try: delete_start_menu_shortcut(shortcut['shortcut-name']) except FileNotFoundError: pass if packet.set_env: write(f'Deleting {packet.set_env["name"]} Environment Variable', 'bright_green', metadata) delete_environment_variable(packet.set_env['name']) write(f'Uninstalling {packet.display_name}', 'bright_green', metadata) package_directory = loc + f'{packet.extract_dir}@{packet.latest_version}' proc = Popen(f'del /f/s/q {package_directory} > nul'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) proc.communicate() proc = Popen(f'rmdir /s/q {package_directory}'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) proc.communicate() loc = rf'{home}\electric\shims' write(f'Successfully Uninstalled {packet.display_name}', 'bright_green', metadata) if packet.uninstall_notes: display_notes(packet, '', metadata, uninstall=True) else: write( f'Could Not Find Any Existing Installations Of {packet.display_name}', 'bright_yellow', metadata)
def display_notes(packet: PortablePacket, unzip_dir: str, metadata: Metadata, uninstall=False): write('\n----Notes----', 'white', metadata) if not uninstall: if isinstance(packet.install_notes, list): for line in packet.notes: write( line.replace('$dir', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ).replace('\\\\', '\\'), 'white', metadata) else: write( packet.install_notes.replace('$dir', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ).replace('\\\\', '\\'), 'white', metadata) else: if isinstance(packet.uninstall_notes, list): for line in packet.notes: write( line.replace('$dir', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ).replace('\\\\', '\\'), 'white', metadata) else: write( packet.uninstall_notes.replace('$dir', unzip_dir).replace( '<extras>', rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ).replace('\\\\', '\\'), 'white', metadata) write('\n', 'white', metadata)
def download(packet, url: str, download_extension: str, file_path: str, metadata: Metadata, show_progress_bar=True, is_zip=False): ''' Downloads A File from a URL And Saves It To A location url `(str)`: Link or URL to download the file from. download_extension`(string)`: Extension for the file downloaded like `.exe` or `.txt`. file_path`(string)`: Path to save the file to. Examples(`'C:\\Users\\name\\Downloads'`, `'~/Desktop'`) show_progress_bar `[Optional]` `(bool)`: Whether or not to show the progress bar while downloading. >>> download('https://atom.io/download/windows_x64', '.exe', 'C:\MyDir\Installer') ''' import requests import sys import cursor cursor.hide( ) # Use This If You Want to Hide The Cursor While Downloading The File In The Terminal if not os.path.isdir(rf'{home}\electric'): os.mkdir(rf'{home}\electric') if not is_zip: if not os.path.isdir(rf'{home}\electric\extras'): os.mkdir(rf'{home}\electric\extras') if not os.path.isdir( rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ): os.mkdir( rf'{home}\electric\extras\{packet.extract_dir}@{packet.latest_version}' ) # if not os.path.isdir(file_path.replace('\\\\', '\\')): # os.mkdir(file_path.replace('\\\\', '\\')) try: file_path = file_path.replace('\\\\', '\\') with open(f'{file_path}{download_extension}', 'wb') as f: # Get Response From URL response = requests.get(url, stream=True) # Find Total Download Size total_length = response.headers.get('content-length') # Number Of Iterations To Write To The File chunk_size = 4096 if total_length is None: f.write(response.content) else: dl = 0 full_length = int(total_length) # Write Data To File for data in response.iter_content(chunk_size=chunk_size): dl += len(data) f.write(data) if show_progress_bar: complete = int(25 * dl / full_length) # Replace '=' with the character you want like '#' or '$' fill_c = Fore.LIGHTGREEN_EX + '=' * complete # Replace '-' with the character you want like ' ' (whitespace) unfill_c = Fore.LIGHTBLACK_EX + '-' * (25 - complete) sys.stdout.write( f'\r{fill_c}{unfill_c} {Fore.RESET} {round(dl / 1000000, 1)} / {round(full_length / 1000000, 1)} MB {Fore.RESET}' ) sys.stdout.flush() if is_zip: write(f'\n{Fore.LIGHTGREEN_EX}Initializing Unzipper{Fore.RESET}', 'white', metadata) except KeyboardInterrupt: write(f'\nDownload Was Interrupted!', 'red', metadata) sys.exit()
def update_portable(packet: PortablePacket, metadata: Metadata): write(f'Updating [ {Fore.LIGHTCYAN_EX}{packet.display_name}{Fore.RESET} ]', 'white', metadata) write(f'Successfully Updated {packet.display_name}', 'magenta', metadata)