passgen

tk password generator
git clone https://git.pastanoggin.com/passgen.git
Log | Files | Refs | README | LICENSE

passgen.py (5923B)


      1 #!/usr/local/bin/python3
      2 """tkinter password generator"""
      3 import tkinter as tk
      4 import string
      5 import random
      6 
      7 DEFAULT_LENGTH = 20
      8 DEFAULT_USE_LOWER = True
      9 DEFAULT_USE_UPPER = True
     10 DEFAULT_USE_NUMBERS = True
     11 DEFAULT_USE_SYMBOLS = True
     12 
     13 
     14 def generate_password(
     15     length=8, uselower=True, useupper=True, usenums=True, usesymbols=False
     16 ):
     17     """Create a radom password based on the options passed"""
     18     chars = []
     19     generated_string = ""
     20     ran = random.SystemRandom()
     21     if uselower:
     22         chars.append(string.ascii_lowercase)
     23     if useupper:
     24         chars.append(string.ascii_uppercase)
     25     if usenums:
     26         chars.append(string.digits)
     27     if usesymbols:
     28         chars.append(string.punctuation)
     29     for _ in range(length):
     30         chosen_list = ran.choice(chars)
     31         chosen_char = chosen_list[ran.randint(0, len(chosen_list) - 1)]
     32         generated_string += chosen_char
     33     return generated_string
     34 
     35 
     36 class MainApp:
     37     """App window"""
     38 
     39     def __init__(self, master):
     40         master.title("Password Generator")
     41         master.resizable(False, False)
     42         master.rowconfigure([0, 1], weight=1)
     43         self.master = master
     44 
     45         # set password options variables
     46         self.options = {
     47             "pass_length": tk.IntVar(value=DEFAULT_LENGTH),
     48             "use_lower": tk.IntVar(value=DEFAULT_USE_LOWER),
     49             "use_upper": tk.IntVar(value=DEFAULT_USE_UPPER),
     50             "use_numbers": tk.IntVar(value=DEFAULT_USE_NUMBERS),
     51             "use_symbols": tk.IntVar(value=DEFAULT_USE_SYMBOLS),
     52         }
     53 
     54         # make a frame for password options and output
     55         frame_main = tk.Frame(master)
     56         frame_main.grid(row=0, column=0, sticky="ew")
     57         frame_main.columnconfigure(0, minsize=700)
     58 
     59         # make checkboxes for password options
     60         check_lower = tk.Checkbutton(
     61             frame_main,
     62             text="Include lowercase letters",
     63             variable=self.options["use_lower"],
     64             command=self.output_pass,
     65         )
     66         check_lower.grid(row=0, column=0, sticky="w", pady=2)
     67         check_upper = tk.Checkbutton(
     68             frame_main,
     69             text="Include uppercase letters",
     70             variable=self.options["use_upper"],
     71             command=self.output_pass,
     72         )
     73         check_upper.grid(row=1, column=0, sticky="w", pady=2)
     74         check_numbers = tk.Checkbutton(
     75             frame_main,
     76             text="Include numbers",
     77             variable=self.options["use_numbers"],
     78             command=self.output_pass,
     79         )
     80         check_numbers.grid(row=2, column=0, sticky="w", pady=2)
     81         check_symbols = tk.Checkbutton(
     82             frame_main,
     83             text="Include symbols",
     84             variable=self.options["use_symbols"],
     85             command=self.output_pass,
     86         )
     87         check_symbols.grid(row=3, column=0, sticky="w", pady=2)
     88 
     89         # make a scale for password length
     90         scale_length = tk.Scale(
     91             frame_main,
     92             from_=4,
     93             to=100,
     94             orient=tk.HORIZONTAL,
     95             variable=self.options["pass_length"],
     96             command=self.change_password_length,
     97         )
     98         scale_length.set(DEFAULT_LENGTH)
     99         scale_length.grid(row=4, column=0, sticky="ew")
    100         self.label_length = tk.Label(
    101             frame_main, text=f"Password length: {DEFAULT_LENGTH}"
    102         )
    103         self.label_length.grid(row=5, column=0)
    104 
    105         # make an entry for the resulting password
    106         self.entry_password = tk.Entry(frame_main)
    107         self.entry_password.grid(row=6, columnspan=2, sticky="ew", pady=5)
    108 
    109         # make a frame for the generate and copy buttons
    110         frame_buttons = tk.Frame(master)
    111         frame_buttons.grid(row=1, column=0)
    112         frame_buttons.columnconfigure([0, 1], weight=1, minsize=150)
    113 
    114         # make a button for generating passwords
    115         button_generate = tk.Button(
    116             frame_buttons, text="\u21BB", width=10, command=self.output_pass
    117         )
    118         button_generate.grid(row=0, column=0, pady=5)
    119 
    120         # make a button for copying the generated password to the clipboard
    121         self.button_copy = tk.Button(
    122             frame_buttons, text="Copy to Clipboard", command=self.copy_password
    123         )
    124         self.button_copy.grid(row=0, column=1, pady=5)
    125         self.label_copy = tk.Label(frame_buttons)
    126 
    127         self.output_pass()
    128 
    129     def change_password_length(self, newval):
    130         """Displays the new len of the passwords and then outputs it"""
    131         self.label_length.config(text=f"Password length: {newval}")
    132         self.output_pass()
    133 
    134     def copy_password(self):
    135         """Copies the password to the clipboard and displays a message"""
    136         if self.entry_password.get():
    137             self.master.clipboard_clear()
    138             self.master.clipboard_append(self.entry_password.get())
    139             self.label_copy.grid(row=1, columnspan=2)
    140             self.flash(250, 4)
    141 
    142     def flash(self, dur, count, first=0):
    143         """Flash a message when the password gets copied to the clipboard"""
    144         if first == 0:
    145             self.button_copy.configure(state="disabled")
    146             count -= 0.5
    147             first += 1
    148         if count == 0:
    149             self.label_copy.grid_forget()
    150             self.button_copy.configure(state="normal")
    151             return
    152         if self.label_copy["text"]:
    153             self.label_copy.config(text="")
    154         else:
    155             self.label_copy.config(text="Password copied to clipboard!!")
    156         self.label_copy.after(dur, lambda: self.flash(dur, count - 0.5, first))
    157 
    158     def output_pass(self):
    159         """Display the generated password"""
    160         self.entry_password.delete(0, tk.END)
    161         values = [value.get() for value in self.options.values()]
    162         if 1 in values:
    163             password = generate_password(*values)
    164             self.entry_password.insert(0, password)
    165 
    166 
    167 if __name__ == "__main__":
    168     root = tk.Tk()
    169     app = MainApp(root)
    170     root.mainloop()