def update_player_data(self, task, data_set, no_prompts): subprocess.run(["clear"]) print_heading(f"Update {data_set}", fg="bright_yellow") spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) spinner.text = "Updating player data..." spinner.start() result = task.execute() if result.failure: spinner.stop() return result spinner.succeed(f"{data_set} was successfully updated!") if no_prompts: return Result.Ok() updated_players = result.value or [] if not updated_players: pause(message="Press any key to continue...") return Result.Ok(updated_players) heading = f"Updated {data_set}: Results" message = f"{len(updated_players)} changes total:" table_viewer = DictListTableViewer( dict_list=updated_players, prompt="Press Enter to continue", confirm_only=True, table_color="bright_yellow", heading=heading, heading_color="bright_yellow", message=message, message_color="blue", ) table_viewer.launch() return Result.Ok(updated_players)
def get_s3_objects_start(self): subprocess.run(["clear"]) self.spinners["default"] = Halo( spinner=get_random_dots_spinner(), color=get_random_cli_color(), text="Retrieving data for all objects stored in S3...", ) self.spinners["default"].start()
def update_spinner(self, file_type, data_set): self.spinners[file_type][data_set] = Halo( spinner=get_random_dots_spinner(), color=get_random_cli_color(), text=(f"Analyzing MLB {self.year} {data_set} {file_type} files " f"(Task {self.task_number}/{self.total_tasks})..."), ) self.spinners[file_type][data_set].start()
def get_all_s3_objects(self): subprocess.run(["clear"]) spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) spinner.text = "Retrieving details of all objects stored in S3..." spinner.start() self.s3_sync.get_all_s3_objects() spinner.stop()
def find_out_of_sync_files_start(self): self.spinners[self.data_set] = Halo( spinner=get_random_dots_spinner(), color=get_random_cli_color(), text= (f"Analyzing MLB {self.year} {self.file_type} {self.data_set} files " f"(Task {self.task_number}/{self.total_tasks})..."), ) self.spinners[self.data_set].start()
def check_app_status(self): if not self.db_setup_complete: return color = get_random_cli_color() if not self.initialized: f = Figlet(font=get_random_figlet_font(), width=120) print_message(f.renderText("vigorish"), wrap=False, fg=f"bright_{color}") spinner = Halo(spinner=get_random_dots_spinner(), color=color) spinner.text = "Updating metrics..." if self.initialized else "Loading..." spinner.start() if self.initialized: del self.app.audit_report self.audit_report = self.app.audit_report spinner.stop()
def combine_scraped_data_for_game(self): subprocess.run(["clear"]) spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) spinner.text = f"Combining scraped data for {self.game_id}..." spinner.start() result = self.combine_data.execute(self.game_id) if (not result["gather_scraped_data_success"] or not result["combined_data_success"] or not result["update_pitch_apps_success"]): spinner.fail(f"Failed to combine data for {self.game_id}!") pause(message="Press any key to continue...") return Result.Fail(result["error"]) pfx_errors = result["results"]["pfx_errors"] fail_results = [ pfx_errors.pop("pitchfx_error", {}), pfx_errors.pop("invalid_pitchfx", {}), ] if all(len(f) <= 0 for f in fail_results): spinner.succeed( f"All scraped data for {self.game_id} was successfully combined!" ) pause(message="Press any key to continue...") return Result.Ok() spinner.stop() subprocess.run(["clear"]) total_pitch_apps = sum(len(f.keys()) for f in fail_results if f) pitch_apps_plural = "pitch appearances" if total_pitch_apps > 1 else "pitch appearance" total_at_bats = sum( len(at_bat_ids) for f in fail_results for at_bat_ids in f.values() if f) at_bats_plural = "at bats" if total_at_bats > 1 else "at bat" error_header = f"PitchFX data could not be reconciled for game: {self.game_id}\n" error_message = ( f"{total_pitch_apps} {pitch_apps_plural} with data errors ({total_at_bats} total {at_bats_plural})\n" ) print_message(error_header, wrap=False, fg="bright_red", bold=True, underline=True) print_message(error_message, fg="bright_red") if not self.prompt_user_investigate_failures(): pause(message="Press any key to continue...") return Result.Ok() subprocess.run(["clear"]) return self.patch_invalid_pfx_single_game()
def apply_pending_changes(self, file_type, data_set, missing_files, outdated_files): subprocess.run(["clear"]) self.spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) self.spinner.start() self.s3_sync.events.sync_files_progress += self.update_sync_progress self.s3_sync.sync_files(self.sync_direction, missing_files, outdated_files, file_type, data_set, self.year) self.s3_sync.events.sync_files_progress -= self.update_sync_progress self.spinner.stop() src_folder = "S3 bucket" if self.sync_direction == SyncDirection.DOWN_TO_LOCAL else "local folder" dest_folder = "local folder" if self.sync_direction == SyncDirection.DOWN_TO_LOCAL else "S3 bucket" message = ( f"All changes have been applied, MLB {self.year} {data_set} {file_type} files in {src_folder} " f"have been synced to {dest_folder}!") print_message(message, fg="bright_green", bold=True) pause(message="Press any key to continue...")
def __init__(self, app): super().__init__(app) self.sync_direction = None self.file_type = None self.data_set = None self.year = None self.spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) self.events = Events( ( "error_occurred", "get_s3_objects_start", "get_s3_objects_complete", "find_out_of_sync_files_start", "find_out_of_sync_files_complete", "sync_files_start", "sync_files_progress", "sync_files_complete", ) )
def combine_scraped_data_for_game(self, combine_game_id): subprocess.run(["clear"]) spinner = Halo(color=get_random_cli_color(), spinner=get_random_dots_spinner()) spinner.text = f"Combining scraped data for {combine_game_id}..." spinner.start() result = self.combine_data.execute(combine_game_id) if not (result["gather_scraped_data_success"] and result["combined_data_success"] and result["update_pitch_apps_success"]): spinner.fail(f"Failed to combine data for {combine_game_id}!") print_message(result["error"], wrap=False, fg="bright_red", bold=True) return Result.Fail(result["error"]) spinner.stop() pfx_errors = result["results"]["pfx_errors"] if pfx_errors.get("pitchfx_error", []): self.pfx_errors[combine_game_id] = pfx_errors["pitchfx_error"] if pfx_errors.get("invalid_pitchfx", []): self.invalid_pfx[combine_game_id] = pfx_errors["invalid_pitchfx"] if self.total_pitch_apps_any_pitchfx_error > 0: pitch_apps_plural = ("pitch appearances" if self.total_pitch_apps_any_pitchfx_error > 1 else "pitch appearance") at_bats_plural = "at bats" if self.total_at_bats_any_pitchfx_error > 1 else "at bat" message = ( f"PitchFX data could not be reconciled for game: {combine_game_id}\n" f"{self.total_pitch_apps_any_pitchfx_error} {pitch_apps_plural} with data errors " f"({self.total_at_bats_any_pitchfx_error} total {at_bats_plural})\n" ) print_message(message, fg="bright_yellow", bold=True) else: message = f"All scraped data for {combine_game_id} was successfully combined!" print_message(message, fg="bright_cyan", bold=True) pause(message="Press any key to continue...") return Result.Ok()
def launch(self): subprocess.run(["clear"]) print_heading("Fix Orphaned Player IDs: In Progress...", fg="bright_yellow") self.spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) self.spinner.text = "0% Complete..." self.spinner.start() self.subscribe_to_events() result = self.task.execute() self.unsubscribe_from_events() if result.failure: self.spinner.fail("Error occurred!") return result fixed_player_ids = result.value if not fixed_player_ids: self.spinner.info( "No orphaned player_ids meet the debut year requirement") return Result.Ok(False) self.spinner.succeed("Successfully fixed all eligible player_ids!") pause(message="Press any key to continue...") heading = "Fix Orphaned Player IDs: Results" message = f"{len(fixed_player_ids)} changes total:" table_viewer = DictListTableViewer( dict_list=[p.as_dict() for p in fixed_player_ids], prompt="Press Enter to continue", confirm_only=True, table_color="bright_yellow", heading=heading, heading_color="bright_yellow", message=message, message_color="blue", ) table_viewer.launch() return Result.Ok(False)
def initialize_spinner(self, game_ids): subprocess.run(["clear"]) self.spinner = Halo(spinner=get_random_dots_spinner(), color=get_random_cli_color()) self.spinner.text = self.get_spinner_text(game_ids[0], 1, len(game_ids)) self.spinner.start()