예제 #1
0
    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')
예제 #2
0
    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)
예제 #3
0
    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