def client(): # connecting to the server spinner3 = Halo(text='Loading', spinner='dots2', color="yellow") spinner3.start("Connecting to central server ...") s.connect(("localhost", port_no)) time.sleep(1) spinner3.succeed('Succesfully connected with central server') spinner3.stop() while True: print("---------------------------------") try: task_aws = prompt(client_qus) cmd = task_aws["task"] if cmd == "close": con_aws = prompt(confirm_qus) if con_aws["exit"]: s.send(bytes(cmd, "utf-8")) result = s.recv(1024).decode("utf-8") s.close() print("---------------------------------") break else: continue print("---------------------------------") s.send(bytes(cmd, "utf-8")) result = s.recv(1024).decode("utf-8") print(result) except: print("Error") s.close() break s.close()
def _check_for_updates_with_appimageupdatetool(self, path_appimageupdate, show_spinner=True): path_to_old_appimage = self.appdata().get('path') if show_spinner: spinner = Halo('Checking for updates', spinner='dots') spinner.start() _check_update_command = shlex.split( "{au} --check-for-update {app}".format( au=path_appimageupdate, app=path_to_old_appimage, )) _check_update_proc = subprocess.Popen(_check_update_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) e_code = _check_update_proc.wait(600) if e_code == 0: if show_spinner: spinner.succeed("Already up-to-date!") return elif e_code == 1: if show_spinner: spinner.info("Updates found") else: if show_spinner: spinner.fail("Update information is not embedded within the " "AppImage. ") spinner.fail("Consider informing the AppImage author to add a " ".zsync file") spinner.fail( "Alternatively, pass the --no-appimageupdate option") spinner.stop()
def _consolidate_reg_params(self): """Updates the value (by addition) of omega across the tasks the model is exposed to. """ device = self.device() reg_params = self.reg_params halo = Halo(text='Consolidating omega values', spinner='dots').start() for name, param in self.vae.named_parameters(): if param not in reg_params: continue param_dict = reg_params[param] prev_omega = param_dict['prev_omega'] new_omega = param_dict['omega'] new_omega = torch.add(prev_omega, new_omega) del param_dict['prev_omega'] param_dict['omega'] = new_omega reg_params[param] = param_dict halo.succeed('Successfully consolidated omega values') self.reg_params = reg_params
def find_operator_info(args: argparse.Namespace, operator_name: str) -> None: """With the specified arguments, calls all the functions needed to find information and print all information out to the screen. This function will determine whether to use Gamepress or JSON for information, then call either one's appropriate information-getting functions and build an Operator object using the provided information. The Operator object will be used for printing. Nothing is returned. """ spinner = Halo(text="Fetching...", spinner="dots", color="magenta") # Initialize the arguments for cmd purposes spinner.start() operator_dict, operator_key = get_operator_dict(operator_name) spinner.text = "Parsing..." spinner.color = "yellow" operator = parse_operator_data(args, operator_dict, operator_key, operator_name) # ---------------------------------------- if operator is not None: spinner.succeed("Success!") if operator_dict == {} or args.gamepress: sys.stdout.write("\nSkipping JSON; Using gamepress.\n") # Print out the results sys.stdout.write("\n\n" + operator.name + " ") sys.stdout.write("*" * operator.rarity + " ") # Star rarity sys.stdout.write(operator.profession + "\n") sys.stdout.write(operator.get_formatted_tags() + "\n\n") for desc_text in operator.description: sys.stdout.write(desc_text) all_properties = [ operator.get_property(prop) for prop in operator.get_all_properties() ] # Fetch the stats all_messages = ([parse_stats(operator.stats)] + all_properties if (operator.has_stats()) else all_properties) for prop in all_messages: for text in prop: sys.stdout.write(text + "\n") else: spinner.fail("Failed.") sys.stdout.write("\n\n" + operator_name.replace("-", " ").title() + "\n") sys.stdout.write("\n" + "Could not find operator! " + "Either the server is down, or your spelling is! \n") sys.stdout.write("\n\n")
def squash_embeddings(embeddings): spinner = Halo('squashing embeddings down to 2d and normalising').start() embeddings = UMAP(n_components=2).fit_transform(embeddings) normalised_embeddings = ((embeddings - embeddings.min(axis=0)) / (embeddings.max(axis=0) - embeddings.min(axis=0))) spinner.succeed() return normalised_embeddings
def unit_owner_repo(name, repo, token, limiter) -> UnitOwnerRepo: """ Handles request for a single organization/user repository. Has no limits since it fetches data from a single repo, cannot use `--limit` flag with the `--repo` option. """ if token: request_headers["Authorization"] = f"token {token}" url: str = f"https://api.github.com/repos/{name}/{repo}/issues?labels=good first issue" spinner = Halo(text="Fetching issues...", spinner="dots") spinner.start() # Make request to the API. response: Response = caller(url, request_headers) spinner.succeed("Issues fetched.") issues: Dict = response.json() # Extract rate_limit from response header. rate_limit: Optional[str] = dict( response.headers).get("X-RateLimit-Remaining") return helpers.unit_repo_issue_extract(issues, limiter), rate_limit
def unshorten_adfly_url(self, adfly_url: str): spinner = Halo(text='Grabbing url...', spinner='dots') spinner.start(text='Getting url...') current_link = adfly_url while True: try: url = self.unshorten.unshorten(uri=current_link) current_link = url if 'adfly' in url: pass else: request = self.session.get(url=url) soup = BeautifulSoup(request.text, 'html.parser') if 'redirecting' in request.url: current_link = soup.find_all('p')[2].text.replace('You will be visiting: ', '') spinner.succeed(text='Successfully retrieved url!') return current_link except (InvalidURL, MissingSchema, ConnectionError, NotFound, UnshortenFailed) as exception: spinner.fail(text=f'Error: {exception}') return
def worker(): # connecting to the server s.connect(("localhost", port_no)) spinner2 = Halo(text='Loading', spinner='dots2', color="yellow") spinner2.start("Connecting to central server ...") time.sleep(1) spinner2.succeed('Succesfully connected with central server') spinner2.stop() while True: try: msg = s.recv(1024).decode("utf-8") try: if msg == "close": break s.close() else: s.send(bytes(find_sum(json.loads(msg)), "utf-8")) except: print(msg) except Exception as e: print(e) break s.close() s.close()
def google_wiki2(ques, options, neg): spinner = Halo(text='Googling and searching Wikipedia', spinner='dots2') spinner.start() num_pages = 1 points = list() content = "" maxo = "" maxp = -sys.maxsize print(ques) search_wiki = google.search(ques + ' wiki', num_pages) link = search_wiki[0].link print(link) content = get_page(link) soup = BeautifulSoup(content, "lxml") page = soup.get_text().lower() for o in options: o = o.lower() temp = 0 temp = temp + ((page.count(o)) * 1000) words = split_string(o) for word in words: temp = temp + (page.count(word)) if neg: temp *= -1 points.append(temp) if temp > maxp: maxp = temp maxo = o spinner.succeed() spinner.stop() return points, maxo
def main(): print_banner() args = get_args() spinner = Halo(spinner='dots') try: spinner.start(text='Parsing configuration file') config = ConfParse() spinner.succeed() except Exception as e: spinner.fail() print("\n\nError parsing configuration file: {}\n".format(e)) exit(1) try: spinner.start(text="Retrieving hpHosts feed: {}".format(args.c)) hphosts_feed = HpHostsFeed(args.c) spinner.succeed() except Exception as e: spinner.fail() print("\n\nError retrieving hpHosts feed: {}\n".format(e)) exit(1) # Create object and load in the retrieved values from above report_filename = "hpHosts-{}-{}".format(args.c, args.o) report = Report(hphosts_feed, report_filename, config) # Process results print("\nProcessing {} entries, this may take a while:\n".format(args.n)) report.write_results(args.n) print("\nGreat success.\n") # Plot stats histogram report.print_stats_diagram(args.n) print("\nDetailed report is available in {}\n".format(report_filename))
def concurrent_requests(all_repo_urls: List, request_headers: Dict, limiter: Optional[int]) -> List: """ Send concurrent requests to the repo urls fetched. """ issues: List = [] spinner = Halo(text="Looking for good first issues...", spinner="dots") spinner.start() # Send concurrent requests to the API. with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: submit = [ executor.submit( caller, url, request_headers, ) for url in all_repo_urls ] for future in concurrent.futures.as_completed(submit): if limiter and len(issues) >= limiter: break # Ignore empty values. if not future.result(): continue issues.extend(future.result().json()) spinner.succeed("Parsing complete.") return issues[:limiter]
def require(package): """ Specifies a package that should be installed. By default, this method will use the default package manager of the OS (brew for Mac, apt-get for Ubuntu, etc.), but you can override the default package by specifying it in the `package_aliases.py` file. Args: package (str): User-friendly name of package. Most often, this will be the same as the actual name of the package in the package manager, but some packages will have different names on different systems. Use your best judgement to determine what name to use. """ DefaultPackageManager = default_package_managers[get_platform()] command = DefaultPackageManager(package) if package in package_aliases: default = package_aliases[package].get('default', command) command = package_aliases[package].get(get_platform(), default) if command is None: return spinner = Halo( text="Installing {}".format(package), spinner="dots", placement="right" ) spinner.start() successful = command.execute() if not successful: spinner.fail() else: spinner.succeed()
def countryActivity(self, chunks=4, main_country='United States'): """ Returns a tuples of the contribution count of the main country and other countries. Will ignore activities without a proper country. Parameters ---------- chunks: int The number of chunks to break up a 24 hour day into. Must be a factor of 24. main_country: str The name of the country to compare to all other countries. Returns ------- tuple: (int, int) The first int is the contribution count of the main country followed by all other countries. """ spinner = Halo(text='Analyzing Country Activities', spinner='dots') spinner.start() if 24 % chunks != 0: raise ValueError( 'Bad chunk value. Chunk value must be factor of 24.') dt_data = self.data.sort_values('created_at') dt_data['tod'] = dt_data['created_at'].dt.hour.floordiv(24 / chunks) dt_data = dt_data.loc[dt_data['country'] != ''] main_tod = dt_data[dt_data['country'] == main_country] other_tod = dt_data[dt_data['country'] != main_country] main_counts = main_tod.groupby('tod')['repository_url'].count().values other_counts = other_tod.groupby( 'tod')['repository_url'].count().values country_data = list(zip(main_counts, other_counts)) spinner.succeed('Country Activity Analysis Complete!') return country_data
def getAuthInfo(): # cacheが存在する場合 if os.path.exists(const.CACHE_FILE): cache = util.getCache() # 期限OK if cache.deadline > time.time(): authInfo = cache.auth # 期限NG else: spinner = Halo(text=const.MSG_REQUEST_TOKEN, spinner='dots') spinner.start() try: authInfo = authorize() except Exception: spinner.fail() raise exception.AuthorizeError(const.MSG_AUTHORIZE_ERROR) else: spinner.succeed() else: spinner = Halo(text=const.MSG_REQUEST_TOKEN, spinner='dots') spinner.start() try: authInfo = authorize() except Exception: spinner.fail() raise exception.AuthorizeError(const.MSG_AUTHORIZE_ERROR) else: spinner.succeed() return authInfo
def test_text_animation(self): """Test the text gets animated when it is too long """ text = 'This is a text that it is too long. In fact, it exceeds the eighty column standard ' \ 'terminal width, which forces the text frame renderer to add an ellipse at the end of the ' \ 'text. ' * 6 spinner = Halo(text=text, spinner='dots', stream=self._stream, animation='marquee') spinner.start() time.sleep(1) spinner.succeed('End!') output = self._get_test_output()['text'] terminal_width = get_terminal_columns() self.assertEqual( output[0], '{0} {1}'.format(frames[0], text[:terminal_width - 2])) self.assertEqual( output[1], '{0} {1}'.format(frames[1], text[1:terminal_width - 1])) self.assertEqual(output[2], '{0} {1}'.format(frames[2], text[2:terminal_width])) pattern = re.compile(r'(✔|v) End!', re.UNICODE) self.assertRegexpMatches(output[-1], pattern)
def countryTopLanguages(self, country, num): """ Returns a given countries top list of programming languages. Parameters ---------- country: str The country name to get top languages on. num: int The number of top languages to return. Returns ------- list: tuple A list of tuples containing the top languages and their repository count. """ spinner = Halo(text='Analyzing Country Top Languages', spinner='dots') spinner.start() country_data = self.data.loc[self.data['actor_attributes_location'] == country] count = country_data.groupby('repository_language').count() lang_rank = count.sort_values('repository_url', ascending=False) lang_rank = lang_rank.nlargest(num, ['repository_url']) top_country_languages = lang_rank['repository_url'] size = len(top_country_languages) languages = np.pad(top_country_languages.index.values, (0, num - size), 'constant', constant_values=('')) values = np.pad(top_country_languages.values, (0, num - size), 'constant', constant_values=(0)) spinner.succeed('Country Top Language Analysis Complete!') return (languages, values)
def compile_contract(self, contract_name: str): title = contract_name.replace('.py', '') echo(title) echo('-' * len(title)) contract_path, avm_save_path = self.prepare_to_compile(contract_name) compile_spinner = Halo(text=f"Compiling {contract_name}", spinner='bouncingBar') compile_spinner.start() avm_code = self.compile_py_contract_in_remote(contract_path) if len(avm_code) == 0: compile_spinner.fail() return False compile_spinner.succeed() save_spinner = Halo(text=f'Saving avm file...') save_spinner.start() try: save_avm_file(avm_code, avm_save_path) except PunicaException as e: save_spinner.fail() echo(e.args[1]) return False save_spinner.succeed() end_msg = f'> Avm file written to {path.split(avm_save_path)[0]}' echo(''.join(['-' * len(end_msg)])) echo(f'{end_msg}\n') return True
def export_metrics_data(): spinner = Halo({'text': 'Exporting metrics data', 'spinner': 'dots'}) spinner.start() metrickeys = [] for metrics in MAPTABLES.keys(): if metrics == 'states': continue metrickeys.append(metrics) msg = "Exporting {} metrics".format(metrics) metrics_data = [] for m in DB[metrics].all(): m['state_data'] = DB['states'].find_one(state_code=m['state_code']) del m['id'] if m['state_data'] and 'id' in m['state_data']: del m['state_data']['id'] metrics_data.append(m) with open('{}/metrics_level/{}.json'.format(BUILD_DIR, metrics), 'w') as f: json.dump(metrics_data, f) with open('{}/metrics_level/metrics_list.json'.format(BUILD_DIR), 'w') as f: msg = "Exporting metrics list" json.dump(metrickeys, f) spinner.succeed("Export metrics data complete")
def main(): print_banner() p = PrimeAPI() spinner = Halo(spinner='dots') db = create_engine('sqlite:///techxdb.db') Base.metadata.create_all(db) Base.metadata.bind = db DBSession = sessionmaker(bind=db) dbs = DBSession() #Process Data spinner.start(text='Processing Data...') devices = DataCollector(p, dbs) time.sleep(5) spinner.succeed(text='Data Collected') #Send Message for bot Request = True spinner.start(text='Sending Notification...') try: response = SparkNotifier(dbs) logger.info('Notification sent') logger.info('Process Completed') spinner.suceed(text='Notification sended') spinner.suceed(text='Process completed') except Exception as e: logger.error('Notification Fails message: {}'.format(e)) spinner.fail(text='Notification failed') response = {"status_code": 500} return response
def handle(self, *args, **options): spinner = Halo(text="Creating super user..", text_color="yellow", spinner="dots") spinner.start() time.sleep(3) admin_url = f"http://127.0.0.1:8000/{settings.ADMIN_URL}" default_password = "******" default_username = "******" try: user = User.objects.create_user( username=default_username, password=default_password, first_name="John", last_name="Doe", is_superuser=True, is_staff=True, email="*****@*****.**", ) spinner.succeed(crayons.green("Success!")) print( crayons.normal( f"ℹ Username: {crayons.yellow(default_username)} - Password: {crayons.yellow(default_password)} - Connect to: {crayons.yellow(admin_url)} \n" )) except IntegrityError: spinner.fail( crayons.red( "The superuser has already been created! use command: 'python manage.py createsuperuser'" ))
def test_text_ellipsing(self): """Test the text gets ellipsed if it's too long """ text = 'This is a text that it is too long. In fact, it exceeds the eighty column standard ' \ 'terminal width, which forces the text frame renderer to add an ellipse at the end of the ' \ 'text. ' * 6 spinner = Halo(text=text, spinner='dots', stream=self._stream) spinner.start() time.sleep(1) spinner.succeed('End!') output = self._get_test_output() terminal_width = get_terminal_columns() # -6 of the ' (...)' ellipsis, -2 of the spinner and space self.assertEqual( output[0], '{0} {1} (...)'.format(frames[0], text[:terminal_width - 6 - 2])) self.assertEqual( output[1], '{0} {1} (...)'.format(frames[1], text[:terminal_width - 6 - 2])) self.assertEqual( output[2], '{0} {1} (...)'.format(frames[2], text[:terminal_width - 6 - 2])) pattern = re.compile(r'(✔|v) End!', re.UNICODE) self.assertRegexpMatches(output[-1], pattern)
def get_audience_id(): print('\nCreate Audience:') spinner = Halo(text='Creating audience', spinner='dots') spinner.start() values = { 'name': audience.name, 'description': audience.description, 'subtype': 'CUSTOM', 'customer_file_source': 'USER_PROVIDED_ONLY', 'access_token': access_token } data = urllib.parse.urlencode(values) data = data.encode('ascii') try: with urlopen( "https://graph.facebook.com/v3.2/act_" + account_id + "/customaudiences", data) as response: info = response.read().decode('ASCII') spinner.succeed("Audience was created") response_data = json.loads(str(info)) except HTTPError as e: spinner.fail("Audience creation failed") response = e.read() print(response) sys.exit(-1) return response_data['id']
class HaloFeedback(Feedback): def __init__(self, message=None): self.spinner = Halo(text=message or '', spinner='dots') if message and not default_config.debug: self.spinner.start() def update_message(self, message): super().update_message(message) if not self.spinner._spinner_id and not default_config.debug: self.spinner.start() self.spinner.text = (message + ' ...') if self.message else '' def succeeded(self): self.spinner.text = self.message self.spinner.succeed() def errored(self, error): # self.spinner.text = str(error) if error else self.message self.spinner.text = f'{self.message} ... {colored(str(error), "red")}' self.spinner.fail() sys.exit(1) def warning(self, warning): self.spinner.text = f'{self.message} ... {colored(str(warning), "yellow")}' self.spinner.warn() def info(self, message): self.spinner.info(message) def exists(self, error): self.warning('exists')
def topActorCountries(self, num): """ Returns the top countires for repository contribution in descending order. Parameters ---------- num: int The number of top locations to return. Returns ------- list: tuple A list of tuples containing the top countries and their contribution counts based on how many actors contributed to the repositories. """ spinner = Halo(text='Analyzing Top Actor Countries', spinner='dots') spinner.start() country_count = self.data.loc[self.data['country'] != ''].groupby( 'country').count() country_rank = country_count.sort_values('repository_url', ascending=False) country_rank = country_count.nlargest(num, ['repository_url']) top_actor_countries = country_rank['repository_url'] spinner.succeed('Top Country Analysis Complete!') return (top_actor_countries.index.values, top_actor_countries.values)
def add_terrain(): twin = load_config() bbox = twin["bbox"] package = Package(".") dl = gsi.Downloader(CACHE_DIR) # TODO: Fix basemap_zoom = 18 tiles = mercantile.tiles(*bbox, basemap_zoom) # left, bottom, right, top tiles = list(tiles) spinner = Halo(text="", spinner="bouncingBar") spinner.start( "Installing {}".format(typer.style("terrain", fg=typer.colors.GREEN, bold=True)) ) filenames = dl.download_dem5a(tiles) merged = utils.geojson_merge(filenames) # print(merged.head()) merged.to_file(package.assets.joinpath("merged_dem5a.geojson"), driver="GeoJSON") extract_meshed_level(merged, outfile=package.assets.joinpath("levelmap.json")) spinner.succeed() spinner.stop()
def getWatchersContributors(self, repo_url): """ Returns the peak number of watchers of a repository at any point and unique contributors count as a tuple of ints. Parameters ---------- repo_url: str The url of the target repository. Returns ------- tuple: (int, int) The peak number of watchers and unique contributors. """ spinner = Halo(text='Analyzing Watchers and Contributors', spinner='dots') spinner.start() repo_data = self.data[self.data['repository_url'] == repo_url] contribution_events = repo_data[repo_data['type'] != 'WatchEvent'] watchers = repo_data['repository_watchers'].max() contributors = len( contribution_events['actor_attributes_login'].unique()) spinner.succeed('Watcher and Contributors Analysis Complete!') return (watchers, contributors)
async def download_multiple_images(available_sources, results_to_download): """ Accepts a list of instantiated sources and a list of images to download. Downloads images in list. """ semaphore = asyncio.Semaphore(config["max_simultaneous_downloads"]) spinner = Halo("Downloading images...", color="magenta") async with aiohttp.ClientSession() as session: images = await get_images_to_download( session, available_sources, results_to_download ) async with semaphore: download_task = [ bound_download_image_file(session, semaphore, **image) for image in images ] with spinner: results = await asyncio.gather(*download_task) if results: spinner.succeed("Images downloaded.") if len(results) <= 8: for res in results: click.secho(res, fg="green")
def dayOfWeek(self, chunks=4): """ Gets data on time of day activity broken into days of the week. Parameters ---------- chunks: int The number of chunks to break up a 24 hour day into. Must be a factor of 24. Returns ------- list: list A list of list containing chunks of data for each day of the week. Each list within the list represents the data for one weekday. """ spinner = Halo(text='Analyzing Days of the Week Activities', spinner='dots') spinner.start() if 24 % chunks != 0: raise ValueError( 'Bad chunk value. Chunk value must be factor of 24.') dt_data = self.data.sort_values('created_at') dt_data['tod'] = dt_data['created_at'].dt.hour.floordiv(24 / chunks) dt_data['weekday'] = dt_data['created_at'].dt.weekday tod_by_week = list() for i in range(chunks): tod_data = dt_data.groupby('tod').get_group(i)[['url', 'weekday']] d = tod_data.groupby('weekday').count()['url'].values tod_by_week.append(d) spinner.succeed('Days of Week Activity Analysis Complete!') return np.transpose(tod_by_week)
def _init_reg_params_subseq_tasks(self, freeze: List[str] = []): """Initialize the omega values from MAS (subsequent tasks). Args: freeze (List[str], optional): Name of layers to freeze. Defaults to []. """ device = self.device() reg_params = self.reg_params halo = Halo(text='Initializing omega values (subseq task)', spinner='dots').start() for name, param in self.vae.named_parameters(): if name in freeze or param not in reg_params: continue param_dict = reg_params[param] prev_omega = reg_params['omega'] new_omega = torch.zeros(param.size(), device=device) init_val = param.clone().to(device) param_dict['prev_omega'] = prev_omega param_dict['omega'] = new_omega param_dict['init_val'] = init_val reg_params[param] = param_dict halo.succeed('Successfully initialized omega values (subseq task)') self.reg_params = reg_params
class StatusUpdate(object): def __init__(self, title): if sys.stdout.isatty(): self.spinner = Halo(title, spinner='dots') self.spinner.start() else: self.spinner = None print(title) def complete(self, success, message): if self.spinner: if success is True: self.spinner.succeed(message) elif success is False: self.spinner.fail(message) else: self.spinner.warn(message) self.spinner.stop() else: if success is True: print("success: ", message) elif success is False: print("failed: ", message) else: print("warning: ", message)
def _init_reg_params_first_task(self, freeze: List[str] = []): """Initialize the omega values from MAS (initial task). Args: freeze (List[str], optional): Name of layers to freeze. Defaults to []. """ device = self.device() reg_params = {} halo = Halo(text='Initializing omega values (first task)', spinner='dots').start() for name, param in self.vae.named_parameters(): if name in freeze: continue omega = torch.zeros(param.size(), device=device) init_val = param.clone().to(device) # Omega is initialized to zero on first task param_dict = { 'omega': omega, 'init_val': init_val, } reg_params[param] = param_dict halo.succeed('Successfully initialized omega values (first task)') self.reg_params = reg_params
def link(src, dest, backup_dir): """ Creates a symbolic link at the specified location. Args: src (str): Path to the file that we want to link to. dest (str): Path of the link that will be created. backupd_dir (str): Path to directory to backup existing files. """ message = "linking %s" % os.path.basename(src) spinner = Halo(text=message, spinner="dots", placement="right") spinner.start() if os.path.islink(dest): os.unlink(dest) if os.path.exists(dest): _backup(dest, backup_dir) os.symlink(src, dest) spinner.succeed()
def default_shell(name): """ Sets default shell for the current user. """ spinner = Halo( text="Default shell `{}`".format(name), spinner="dots", placement="right" ) spinner.start() try: path = sh.which(name).strip() user = sh.whoami().strip() with Authentication(): sh.chsh("-s", path, user) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error changing default shell to %s: %s", name, err_message ) spinner.fail()
def configure(namespace, key, *values): """ Sets configuration on mac using `defaults` """ spinner = Halo( text="Setting {}".format(key), spinner="dots", placement="right" ) spinner.start() try: if namespace: sh.defaults("write", namespace, key, *values) else: sh.defaults("write", key, *values) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error with `defaults write -g %s %s: %s", key, values, err_message ) spinner.fail()
def remap_key(src, dest): """ Remaps src key to dest key. An example of remapping the caps lock key to act like the left control key would be to call `remap_key('capslock', 'left-ctrl') Args: src (str): Key name in keyboard dict. This is the key that will change functionality. dest (str): Key name in keyboard dict. The key defined in `src` should act like this key. """ # TODO (phillip): Right now, these changes do not survive a reboot. I am # going to just change this manually in the keyboard settings, but I might # be able to figure out how to do it with `defaults`. # https://apple.stackexchange.com/questions/141069/updating-modifier-keys-from-the-command-line-takes-no-effect spinner = Halo( text="Remapping {} to {}".format(src, dest), spinner="dots", placement="right" ) spinner.start() remap_dict = { 'UserKeyMapping': [ { 'HIDKeyboardModifierMappingSrc': keyboard[src], 'HIDKeyboardModifierMappingDst': keyboard[dest] } ] } try: sh.hidutil("property", "--set", str(remap_dict).replace("'", '"')) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error with `hidutil property --set %s : %s", str(remap_dict), err_message ) spinner.fail()
def curl(src, dest): """ Installs `src` to path `dest` """ spinner = Halo( text="curl {}".format(dest), spinner="dots", placement="right" ) spinner.start() if os.path.exists(dest): spinner.info("{} already exists".format(dest)) return try: sh.curl("-fLo", dest, src) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error downloading file `%s`: %s", src, err_message ) spinner.fail()
def extract(src, dest): """ Extracts the source file in dest """ spinner = Halo( text="extract {}".format(src), spinner="dots", placement="right" ) spinner.start() try: # TODO (phillip): This should choose the correct decompression based # on the filename where possible. with tarfile.open(src, "r:gz") as tar: tar.extractall(dest) sh.rm(src) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error extracting file `%s`: %s", src, err_message ) spinner.fail()
def font(name): """ Installs fonts using curl. Args: name (str): The name of the font as defined in `font_library` dictionary. """ spinner = Halo( text="Font {}".format(name), spinner="dots", placement="right" ) spinner.start() try: library = os.path.join(HOME, "Library/Fonts") path = os.path.join(library, name) sh.curl("-fLo", path, font_library[name]) spinner.succeed() except sh.ErrorReturnCode as err: err_message = "\n\t" + err.stderr.replace("\n", "\n\t") logging.error( "Error installing font `%s`: %s", name, err_message ) spinner.fail()
def install_homebrew(): """ Installs or upgrades homebrew on mac. If homebrew is not installed, this command will install it, otherwise it will update homebrew to the latest version. Additionally, it will offer to upgrade all homebrew packages. Upgrading all packages can take a long time, so the user is given the choice to skip the upgrade. """ print("Checking homebrew install") if sh.which("brew"): spinner = Halo( text="Updating homebrew", spinner="dots", placement="right" ) spinner.start() sh.brew("update") spinner.succeed() print( "Before using homebrew to install packages, we can upgrade " "any outdated packages." ) response = user_input("Run brew upgrade? [y|N] ") if response[0].lower() == "y": spinner = Halo( text="Upgrade brew packages", spinner="dots", placement="right" ) spinner.start() sh.brew("upgrade") spinner.succeed() else: print("Skipped brew package upgrades") else: # TODO (phillip): Currently, this homebrew installation does not work on a fresh # computer. It works from the command line, but not when run from the script. I # need to figure out what is going on. It could be because user input is needed. spinner = Halo( text="Installing homebrew", spinner="dots", placement="right" ) spinner.start() try: script = sh.curl("-fsSL", BREW_GITHUB).stdout sh.ruby("-e", script) spinner.succeed() except sh.ErrorReturnCode: logging.error("Unable to install homebrew. Aborting...") spinner.fail() exit(1)
from halo import Halo # pip install halo first import time spinner = Halo({'text': 'Calculating...', 'color': 'red','spinner': 'dots8'}) spinner.start() counter = 0 while counter < 51: # print(counter) counter += 1 time.sleep(.1) # Run time consuming work here # You can also change properties for spinner as and when you want # spinner.stop() spinner.succeed()
def file(path, template_file, load_vars=lambda: {}): """ Installs a template file using symlinks. If a file already exists at the specified path and it is not a symbolic link, then this function will print an error and return. If the file is a symlink to the `build` directory of your dotfiles repo, then this will check to see if the template has been modified since the file was last built. Args: path (str): Filesystem path where we should install the filled out template file. template_file (str): The filename of the template to install. The file should be located in the $ROOT/templates directory of this repository. load_vars (func): A function that will be run when the file is built to fill in template information. This is passed in as a function so that user input is only asked for when the file is built. """ spinner = Halo(text=path, spinner="dots", placement="right") spinner.start() if os.path.exists(path) and not os.path.islink(path): print("Error: {} exists and is not a soft link".format(path)) spinner.fail() return try: # Load template as a Jinja2 Template template_path = os.path.join( ROOT, os.path.join("templates", template_file) ) template_mtime = os.path.getmtime(template_path) with open(template_path, "r") as template_file: template = Template(template_file.read()) build_path = os.path.join( ROOT, os.path.join("build", os.path.basename(path)) ) if not os.path.exists(build_path): build_mtime = 0 else: build_mtime = os.path.getmtime(build_path) # Build the template if the template has been modified since last build if template_mtime > build_mtime: # TODO (plemons): I should only do this if I actually need user # input. Theoretically, the load_vars function could just read # from a config file making this unnecessary spinner.info("Asking for user input for {}".format(path)) if not os.path.exists(os.path.dirname(build_path)): os.makedirs(os.path.dirname(build_path)) with open(build_path, 'w') as outfile: outfile.write(template.render(**load_vars())) path = os.path.expanduser(path) dirpath = os.path.dirname(path) if not os.path.exists(dirpath): os.makedirs(dirpath) if os.path.islink(path): os.unlink(path) os.symlink(build_path, path) spinner.succeed() except OSError as err: print(err) spinner.fail()