def interactive_task_collect_nonwords( # pylint: disable=unused-argument interaction, reponame, target, nonword_delegate=None, nonstop=False): """ Saves nonwords until a typo is found """ if nonword_delegate is None: nonword_delegate = interactive_nonword_delegate(interaction, target) key = "repository_map" repository_map = get_json_value(key, {}) repodir = repository_map[reponame] repodirpath = Path(repodir) jsonpath = repodirpath / "spelling.json" if not jsonpath.is_file(): interaction.send(f"Unable to locate spelling at {jsonpath}") return with io.open(jsonpath, "r", encoding="utf-8") as fobj: jsonobj = json.load(fobj) state = NonwordState( interaction=interaction, target=target, word=None, details=None, repopath=repodirpath, nonword_delegate=nonword_delegate, ) completed = interactive_task_collect_nonwords_run(state, nonstop, jsonobj) if completed: interaction.send(f"{Fore.YELLOW}Found all words" f" for {reponame}!{Style.RESET_ALL}")
def task_add_repo(obj, eng): # pylint: disable=unused-argument """ Ensures a repo has been forked. """ key = "repository_map" repository_list = get_json_value(key, {}) if not repository_list: interactive_add_one_new_repo(obj.target)
def handler(): reponame = context.taskjson["reponame"] set_multi_repo(reponame, []) repository_map = get_json_value("repository_map", {}) if reponame in repository_map: reposave = repository_map[reponame] remove_repo_for(reponame, reposave, confirm=False) context.controller.add( {"name": "prompt_quit", "interactive": True, "priority": 10} )
def manually_add_new_repo(target): """ Allow entry of a new repository manually """ choices = sorted(os.listdir(target)) option = make_simple_choice(choices, "Which Directory?") if option is None: raise NoRepoException() repository_map = get_json_value("repository_map", {}) repository_map[option] = str(Path(target) / option) set_json_value("repository_map", repository_map)
def task_submit(obj, eng): # pylint: disable=unused-argument """ Submits the typo """ repository_saves = get_json_value("repository_saves", {}) count = len(repository_saves) if count < 1: print(f"Unexpected number of repostories - {count}") return reponame, reposave = next(iter(repository_saves.items())) fast_prepare_a_pr_or_issue_for(reponame, reposave)
def task_cleanup(obj, eng): # pylint: disable=unused-argument """ Submits the typo """ key = "repository_map" repository_map = get_json_value(key, {}) count = len(repository_map) if count < 1: print(f"Unexpected number of repostories - {count}") return reponame, reposave = next(iter(repository_map.items())) remove_repo_for(reponame, reposave, confirm=False)
def task_collect_nonwords(obj, eng): # pylint: disable=unused-argument """ Saves nonwords until a typo is found """ key = "repository_map" repository_list = get_json_value(key, {}) count = len(repository_list) if count < 1: print(f"Unexpected number of repostories - {count}") return reponame = next(iter(repository_list.keys())) interactive_task_collect_nonwords(reponame, obj.target)
def add_repo_save(self, repopath, newspell, word, file_paths): """ Default Implementation saves immediately rather than storing and completing later """ key = "multiitem_submit" saved_items = get_json_value(key, deflt=[]) saved_items.append( { "repopath": str(repopath), } )
def add_repo_save(repodir, add_word, del_word, file_paths): """ Record a typo correction """ saves = get_json_value("repository_saves", {}) reponame = Path(repodir).name saves[reponame] = { "add_word": add_word, "del_word": del_word, "file_paths": file_paths, "repodir": repodir, } set_json_value("repository_saves", saves)
def pick_repo_common(key): """ Select an available repository """ repository_list = get_json_value(key, {}) if not repository_list: print("No repositories available.", file=sys.stderr) raise NoRepoException() option = make_simple_choice(repository_list, "Which Repository?") if option is None: raise NoRepoException() repo_data = repository_list[option] return option, repo_data
def handler(): target = context.controller.target reponame = context.taskjson["reponame"] if reponame in get_json_value("repository_map", {}): interactive_task_collect_nonwords( reponame, target, nonword_delegate=noninteractive_nonword_delegate(context), ) context.controller.add({ "name": "submit", "interactive": True, "priority": 50, "reponame": reponame, })
def handler(): target = context.controller.target reponame = context.taskjson["reponame"] repodir = target / reponame repository_map = get_json_value("repository_map", {}) repository_map[reponame] = str(repodir) set_json_value("repository_map", repository_map) display_repo_intro(repodir) context.controller.add({ "name": "collect_nonwords", "interactive": True, "priority": 50, "reponame": reponame, }) if get_confirmation("Do you want to quit?"): context.controller.quit()
def get_suggestion(word): """ Use the internet to determine if the provided word is a nonword or a typo """ key = f"suggestion.{word}" existing = get_json_value(key) if existing is not None: if existing.get("no_suggestion"): return None return Suggestion.load(existing) suggestion = search_suggestion(word) if suggestion is None: set_json_value(key, {"no_suggestion": True}) return None set_json_value(key, suggestion.save()) return suggestion
def remove_repo_for(repo, repodir, confirm=True): """ Remove specified repo """ for name in ("repository_map", "repository_saves"): repository_map = get_json_value(name, {}) try: del repository_map[repo] set_json_value(name, repository_map) except (KeyError, TypeError): continue if confirm: option = make_simple_choice(["Yes", "No"], "Delete the directory?") else: option = "Yes" if option == "Yes": if os.path.isdir(repodir): shutil.rmtree(repodir, ignore_errors=True)
def multiworker_core(interaction, target): """ Support for different kinds of interaction with multiple worker processing """ key = "multiworker_workload" workload = get_json_value(key, deflt=[]) workload = update_workload(workload) handlers = get_handlers() input_queue = get_input_queue() threadpool = get_pool(handlers) controller = Controller( handlers=handlers, input_queue=input_queue, threadpool=threadpool, target=target ) with controller: for task in workload: controller.add(task) result = controller.run(interaction) set_json_value(key, result)
def interactive_task_collect_nonwords( # pylint: disable=unused-argument reponame, target, nonword_delegate=None, nonstop=False): """ Saves nonwords until a typo is found """ if nonword_delegate is None: nonword_delegate = interactive_nonword_delegate(target) key = "repository_map" repository_map = get_json_value(key, {}) repodir = repository_map[reponame] repodirpath = Path(repodir) jsonpath = repodirpath / "spelling.json" if not jsonpath.is_file(): print(f"Unable to locate spelling at {jsonpath}", file=sys.stderr) return with io.open(jsonpath, "r", encoding="utf-8") as fobj: jsonobj = json.load(fobj) words = get_sorted_words(jsonobj) my_engine = GenericWorkflowEngine() my_engine.callbacks.replace( [check_websearch, is_nonword, is_typo, what_now]) for word in words: state = NonwordState( target=target, word=word, details=jsonobj[word], repopath=repodirpath, nonword_delegate=nonword_delegate, ) try: my_engine.process([state]) except HaltProcessing: if state.done and not nonstop: return print( f"{Fore.YELLOW}Completed checking all words for {reponame}!{Style.RESET_ALL}" )
def non_interactive_pickrepo(): """ Select next free repo """ forking = [] return_repo = None with LOCK: repository_forked = get_json_value("repository_forked", {}) for orgrepo in obtain_sources(): _, origrepo = orgrepo.split("/", 1) if origrepo in repository_forked: continue try: orgrepo = get_true_orgrepo(orgrepo) except GithubException: continue _, repo = orgrepo.split("/", 1) if repo in repository_forked: continue if check_forked(orgrepo): repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) continue forking.append(orgrepo) if is_archived(orgrepo): repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) continue repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) return_repo = repo break for orgrepo in forking: fork(orgrepo) return return_repo
def handler(): reponame = context.taskjson["reponame"] repository_saves = get_json_value("repository_saves", {}) if reponame in repository_saves: reposave = repository_saves[reponame] suggest_plain = check_if_plain_pr(reposave) add_word = reposave["add_word"] del_word = reposave["del_word"] file_paths = reposave["file_paths"] files = ", ".join(file_paths) print(f"Fix in {reponame}: {del_word} -> {add_word} over {files}") if suggest_plain: submit_plain = get_confirmation( "Analysis suggests plain pr, agree?") else: submit_plain = get_confirmation( "Complex repo submit plain pr anyway?") context.controller.add({ "name": "plain_pr" if submit_plain else "full_pr", "interactive": False, "reponame": reponame, "reposave": reposave, })
def interactive_pickrepo(): """ Select next free repo """ repository_forked = get_json_value("repository_forked", {}) for orgrepo in obtain_sources(): _, origrepo = orgrepo.split("/", 1) if origrepo in repository_forked: continue try: orgrepo = get_true_orgrepo(orgrepo) except GithubException: continue _, repo = orgrepo.split("/", 1) if repo in repository_forked: continue print(f"Checking {orgrepo}") if check_forked(orgrepo): repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) continue print(f"Have not forked {orgrepo}") print(f"Forking {orgrepo}") fork(orgrepo) if is_archived(orgrepo): print(f"Skipping archived repo {orgrepo}") repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) continue repository_forked[origrepo] = True repository_forked[repo] = True set_json_value("repository_forked", repository_forked) return repo return None
def show_work_queue(target): # pylint: disable=unused-argument """ Dispay the current workload queue """ key = "multiworker_workload" pprint.pprint(get_json_value(key, deflt=[]))