def choose_config(config: Any) -> Any: """Chooses a random value from a list of config options or returns the config if it is not in a list.""" if isinstance(config, list): choice = random.choice(config) CONSOLE.print(f"[blue]Chose {choice}.[/blue]") return choice return config
def run_file(self, file: str) -> Union[tuple, str]: """Send code form file to the api and return the response.""" args = helpers.get_args() stdin = helpers.get_stdin() try: with open(file, "r", encoding="utf-8") as f: code = f.read() if not any(file.endswith("." + ext) for ext in self.extensions): CONSOLE.print("File Extension language is not supported!", style="bold red") helpers.close() except FileNotFoundError: CONSOLE.print("Path is invalid; File not found", style="bold red") helpers.close() language = self.extensions[file[file.rfind(".") + 1:]] payload = PistonQuery( language=language, code=code, args=args, stdin=stdin, ) data = services.query_piston(CONSOLE, payload) if len(data["output"]) == 0: return "Your code ran without output.", language return data["output"].split("\n"), language
def ask_input(self, theme: str) -> Union[tuple, str]: """ Make a multiline prompt for code input and send the code to the api. The compiled output from the api is returned. """ language = helpers.get_lang() args = helpers.get_args() stdin = helpers.get_stdin() CONSOLE.print( "[green]Enter your code, (press esc + enter to run)[/green]") style = helpers.set_style(theme) CONSOLE.print() code = prompt( "", lexer=PygmentsLexer(lexers_dict[language]), include_default_pygments_style=False, style=style, multiline=True, ) payload = PistonQuery(language=language, args=args, stdin=stdin, code=code) data = services.query_piston(CONSOLE, payload) if len(data["output"]) == 0: return "Your code ran without output.", language return data["output"].split("\n"), language
def fix_prompt(self) -> str: """Fixes the prompt_start configuration variables.""" if self.validate_prompt(): return choose_config(self.prompt) CONSOLE.print( f"[red]Prompt start invalid. {repr(self.prompt)} contains a new" "line character. Using default prompt start instead.[/red]") return self.default_prompt
def check_box_exists(box: str) -> bool: """Ensures that a given box style exists.""" if box not in BOX_STYLES: CONSOLE.print( f'[red]Box Style invalid, "{box}" not recognized. Using default box style.[/red]' ) return False return True
def check_theme_exists(theme: str) -> bool: """Ensures that a given theme exists.""" if theme not in themes: CONSOLE.print( f'[red]Theme invalid, "{theme}" not recognized. Using default theme.[/red]' ) return False return True
def set_language(self, language: str) -> None: """ Set the language to the option passed by use. If language is not supported then exit the CLI. """ if language not in languages_: CONSOLE.print("[bold red]Language is not supported![/bold red]") helpers.close() self.language = language
def theme_list() -> None: """List all available themes with a short code snippet.""" for theme in themes: CONSOLE.print(f"[bold red underline]Theme {theme}: [/bold red underline]\n") try: style = get_style_by_name(theme) except ClassNotFound: style = scheme_dict[theme] finally: print( highlight( THEME_PREVIEW, Python3Lexer(), Terminal256Formatter(style=style) ) )
def get_code() -> Union[bool, str]: """Prompt the user for the pastebin link.""" link = CONSOLE.input("[green]Enter the link:[/green] ").lower() base_url = urllib.parse.quote_plus( link.split(" ")[-1][5:].strip("/"), safe=";/?:@&=$,><-[]" ) domain = base_url.split("/")[2] if domain == "paste.pythondiscord.com": if "/raw/" in base_url: url = base_url token = base_url.split("/")[-1] if "." in token: token = token[: token.rfind(".")] # removes extension url = f"https://paste.pythondiscord.com/raw/{token}" else: CONSOLE.print( "[red]Can only accept links from paste.pythondiscord.com.[/red]" ) return False response = requests.get(url) if response.status_code == 404: CONSOLE.print("[red]Nothing found. Check your link[/red]") return False elif response.status_code != 200: CONSOLE.print( f"[red]An error occurred (status code: {response.status_code}).[/red]" ) return False return response.text
def validate_type(self) -> bool: """Validates the type of a given configuration.""" if self.current_type is not self.target_type and self.current_type is not list: CONSOLE.print( f'[red]Configuration "{self.config.__name__}" invalid, use type {self.target_type.__name__}, ' f"not {self.current_type.__name__}. Using default setting.[/red]" ) return False if self.current_type is list: for item in self.config: if not isinstance(item, self.target_type): CONSOLE.print( f'[red]A possible "{item}" in the list of "{self.name}" configurations ' f"specified has an invalid type, use type {self.target_type.__name__}. " f"not {type(item).__name__}. Using default setting.[/red]" ) return False CONSOLE.print( f'[blue]A list of possible configurations was found for the "{self.name}" option. ' "Choosing a random one.") return True
def run_shell(self, language: str, theme: str, prompt_start: str, prompt_continuation: str) -> None: """Run the shell.""" CONSOLE.print( "[bold blue]NOTE: stdin and args will be prompted after code. " "Use escape + enter to finish writing the code. " "To quit, use ctrl + c. [/bold blue]") self.set_language(language) self.set_prompt_session(prompt_start, prompt_continuation) self.style = helpers.set_style(theme) while True: query = self.prompt() data = services.query_piston(CONSOLE, query) if len(data["output"]) == 0: CONSOLE.print("Your code ran without output.") else: CONSOLE.print("\n".join([ f"{i:02d} | {line}" for i, line in enumerate(data["output"].split("\n"), 1) ]))
def main() -> None: """Implement the main piston-cli process.""" args = commands_dict["base"]() if args.version: print(version.__version__, flush=True) helpers.close() if args.list: list_commands = { "themes": commands_dict["theme_list"], "languages": ("Languages", grouper(languages_, 2)), "boxes": ("Box Styles", grouper(BOX_STYLES, 2)), } try: # If the value is an tuple i.e. it is formatted for a box. if isinstance(list_commands[args.list], tuple): table = make_table(*list_commands[args.list]) CONSOLE.print(table) else: # Else it is just a callable and we can call it. list_commands[args.list]() except KeyError: CONSOLE.print( f"[red] Invalid option provided - Valid " f"options include:[/red] [cyan]{', '.join(list_commands.keys())}[/cyan]" ) helpers.close() config_loader = ConfigLoader(args.config) config = config_loader.load_config() output = None init_lexers() if args.theme: CONSOLE.print( f"[indian_red]- Theme flag specified, overwriting theme loaded from " f"config: {args.theme}[/indian_red]") if args.file: output, language = commands_dict["from_file"](args.file) elif args.pastebin: output, language = commands_dict["from_link"]() elif args.shell: try: commands_dict["from_shell"]( args.shell, args.theme or config["theme"], config["prompt_start"], config["prompt_continuation"], ) except KeyboardInterrupt: pass else: output, language = commands_dict["from_input"](args.theme or config["theme"]) if output: CONSOLE.print(f"\nHere is your {language} output:") CONSOLE.print( helpers.print_msg_box( output, style=config["box_style"], )) helpers.close()