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