Friday, May 20, 2022

Python - Project - Password Manager (Day 29)

This is a 100 Days challenge to learn a new language (Python). 100 Days of Code - The Complete Python Pro Bootcamp 

I will post some notes to motivate myself to finish this challenge.


Goal



Create a GUI program to manage password.
* generate password randomly
* show dialog for user confirmation and form validation error
* save user info into the file system


Tkinter - Grid - Layout



*columnspan: How many columns widget occupies; default 1.


Ex: 
import tkinter as tk


# Init
root = tk.Tk()
root.title("Exp")
root.config(padx=20, pady=20)
root.minsize(width=200, height=200)

# Init Button
button_1 = tk.Button(text="1", bg="red")
button_1.grid(column=0, row=0)
button_2 = tk.Button(text="2", bg="blue")
button_2.grid(column=1, row=0)
button_3 = tk.Button(text="3", bg="green")
button_3.grid(column=2, row=0)
button_4 = tk.Button(text="4", bg="yellow")
button_4.grid(column=0, row=3)
button_5 = tk.Button(text="5", bg="purple")
# Make this button widget to occupy 2 columns
button_5.grid(column=1, row=2, columnspan=2)

# Start the Event Loop
root.mainloop()

Result:



Manipulate Entry



focus()
get()
insert(0, 'text')
delete(0, END)


Ex: 
import tkinter as tk


def get():
    """Get entry value"""
    print(f"Get: {entry.get()}")


def set_value():
    """Update entry value"""
    entry.delete(0, tk.END)
    entry.insert(0, "HIHI")


def delete():
    """Clear text of entry"""
    entry.delete(0, tk.END)


# Init
root = tk.Tk()

# Init ENtry
entry = tk.Entry()
entry.insert(0, "Hello World")
entry.focus()
entry.pack()

# Init Button
get_button = tk.Button(text="Get", command=get)
get_button.pack()
set_value_button = tk.Button(text="Set", command=set_value)
set_value_button.pack()
delete_button = tk.Button(text="Delete", command=delete)
delete_button.pack()

# Start the Event Loop
root.mainloop()


Tkinter - messagebox


Combine elements of a List into a string


Ex: Regular
my_list = ["h", "e", "l", "l", "o"]
new_str = ""

for char in my_list:
    new_str += char

print(new_str)

Ex: Using join()
my_list = ["h", "e", "l", "l", "o"]
new_str = "".join(my_list)

print(new_str)


How to copy text to clipboard


Project - Password Manager




Ex:
import random
import tkinter as tk
from tkinter import messagebox
import pyperclip


def copy_to_clipboard(message):
    """Use pyperclip library to copy message to clipboard"""
    pyperclip.copy(message)


def generate_password():
    """Generate random password and show it to GUI"""
    letters = [
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
        "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
        "u", "v", "w", "x", "y", "z",
    ]
    numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
    symbols = ["!", "#", "$", "%", "&", "(", ")", "*", "+"]

    password_letter_list = [
        random.choice(letters) for _ in range(random.randint(8, 10))
    ]
    password_symbols_list = [
        random.choice(symbols) for _ in range(random.randint(2, 4))
    ]
    password_numbers_list = [
        random.choice(numbers) for _ in range(random.randint(2, 4))
    ]
    password_list = password_letter_list + password_symbols_list +
password_numbers_list
    random.shuffle(password_list)

    password = "".join(password_list)
    pwd_entry.insert(0, password)
    copy_to_clipboard(password)


def save():
    """Save user info to the file system"""
    website = website_entry.get()
    username = username_entry.get()
    pwd = pwd_entry.get()

    # Form Validation
    if len(website) == 0 or len(username) == 0 or len(pwd) == 0:
        messagebox.showerror(
            title="Info", message="Please make sure to enter all fields"
        )

        return

    # Pop-up confirmation
    is_ok = messagebox.askokcancel(
        title=website,
        message=f"Is that ok to save {username} / {pwd} ?",
    )

    if is_ok:
        # Use with statement to open a file
        with open("data.txt", encoding="utf-8", mode="a") as file:
            file.write(f"{website} | {username} | {pwd}\n")

        # Clear User Input
        website_entry.delete(0, tk.END)
        pwd_entry.delete(0, tk.END)


# Init
root = tk.Tk()
root.title("Password Manager")
root.config(padx=50, pady=50)

# Init canvas
canvas = tk.Canvas(width=200, height=200)
logo_image = tk.PhotoImage(file="logo.png")
canvas.create_image(100, 100, image=logo_image)
canvas.grid(column=1, row=0)

# Website
website_label = tk.Label(text="Website:")
website_label.grid(column=0, row=1)
website_entry = tk.Entry()
website_entry.grid(sticky="ew", column=1, row=1, columnspan=2)
# Focus entry
website_entry.focus()

# Email/Username
username_lable = tk.Label(text="Email/Username:")
username_lable.grid(column=0, row=2)
username_entry = tk.Entry()
username_entry.grid(sticky="ew", column=1, row=2, columnspan=2)
username_entry.insert(0, "frank@demo.com")

# Password
pwd_lable = tk.Label(text="Password:")
pwd_lable.grid(column=0, row=3)
pwd_entry = tk.Entry()
pwd_entry.grid(sticky="ew", column=1, row=3)

# PWD Generation Btn
generate_pwd_btn = tk.Button(text="Generate Password",
command=generate_password)
generate_pwd_btn.grid(sticky="ew", column=2, row=3)

# Add Btn
add_btn = tk.Button(text="Add", command=save)
add_btn.grid(sticky="ew", column=1, row=4, columnspan=2)

# Start the Event Loop
root.mainloop()

No comments:

Post a Comment