"""! @file main.py @brief Command-line entry point for the PyPassword Generator. """ import os import sys from password_generator.constants import ( ANSI_BOLD, ANSI_CYAN, ANSI_GREEN, ANSI_MAGENTA, ANSI_RESET, ANSI_YELLOW, TITLE_ART, ) from password_generator.generator import generate_easy_password, generate_hard_password def _colorize(text: str, *codes: str) -> str: """! @brief Wrap text in ANSI color codes when the output supports colors. @details Colors are skipped when stdout is not a terminal or NO_COLOR is set. @param text Text to colorize. @param codes ANSI escape codes to apply. @return The (possibly) colorized text. """ if not sys.stdout.isatty() or "NO_COLOR" in os.environ: return text return "".join(codes) + text + ANSI_RESET def print_title() -> None: """! @brief Print the colored ASCII-art title. """ if sys.stdout.isatty(): os.system("") # Enables ANSI escape sequences in Windows terminals. print(_colorize(TITLE_ART, ANSI_BOLD, ANSI_CYAN)) def _ask_int(prompt: str) -> int: """! @brief Ask the user for a non-negative whole number until a valid one is given. @param prompt Text shown to the user. @return The number entered by the user (0 or more). """ while True: try: value = int(input(prompt)) except ValueError: print("Please enter a whole number.") continue if value < 0: print("Please enter a number of 0 or more.") continue return value def main() -> None: """! @brief Run the interactive program. @details Asks for the number of letters, symbols and numbers, then prints one easy-level and one hard-level password. """ print_title() print(_colorize("Welcome to the PyPassword Generator!", ANSI_BOLD, ANSI_MAGENTA)) nr_letters = _ask_int("How many letters would you like in your password?\n") nr_symbols = _ask_int("How many symbols would you like?\n") nr_numbers = _ask_int("How many numbers would you like?\n") easy = generate_easy_password(nr_letters, nr_symbols, nr_numbers) hard = generate_hard_password(nr_letters, nr_symbols, nr_numbers) print(f"Easy level: {_colorize(easy, ANSI_GREEN)}") print(f"Hard level: {_colorize(hard, ANSI_YELLOW)}") if __name__ == "__main__": main()