Commit Diff


commit - 38cc25d6d53d3ce3cbf403ae8cb9225cd31de9e3
commit + fd9c657133aa6ad65b3ef679d121b53795c7bd60
blob - /dev/null
blob + 3e33eee895419704ea71b486337f8d411b354203 (mode 644)
--- /dev/null
+++ LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2025 boredpasta <boredpasta@tutanota.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
blob - /dev/null
blob + 20b757e5932a9ec1aa75ac0e679352094370c19a (mode 644)
--- /dev/null
+++ README
@@ -0,0 +1,3 @@
+passgen - a password generator in python+tkinter
+
+that's all, folks (isc license)
blob - /dev/null
blob + 085cb985fb3888d83d672aa434963378a68d0909 (mode 755)
--- /dev/null
+++ passgen.py
@@ -0,0 +1,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()