# Import necessary libraries
from tkinter import * # Imports everything from the tkinter library
from tkinter import messagebox # Import the messagebox module from tkinter
from random import randint, choice, shuffle # Import specific functions from the random module
import pyperclip # Import the pyperclip library for clipboard operations
import json # Import the json module for working with JSON data
Here's a brief description of each import:
tkinter
: This is Python's standard GUI (Graphical User Interface) library. It allows you to create windows, buttons, labels, and more.messagebox
: This is a submodule of tkinter used to display message boxes for showing messages or getting simple inputs.random
: This module provides functions to generate random numbers, sequences, and more.randint
: Used to generate random integers.choice
: Used to choose a random element from a sequence.shuffle
: Used to shuffle a sequence in-place.
pyperclip
: This library allows you to easily copy and paste text to and from the clipboard.json
: This module provides functions for encoding and decoding JSON data.
def searchPass():
try:
# Open the 'passwords.json' file for reading
with open('passwords.json', 'r') as file:
# Load the JSON data from the file into the 'data' variable
data = json.load(file)
# Get the website name from the 'website_field' Text widget
website = website_field.get("1.0", END)[:-1]
# Check if the website is in the loaded JSON data
if website in data:
# If the website is found, get the password and email associated with it
password = data[website]["password"]
email = data[website]["email"]
# Show an information message box with the email and password
messagebox.showinfo(title=website, message=f"Email: {email}\nPassword: {password}")
else:
# If the website is not found, show a warning message box
warning = messagebox.showwarning(title="Warning", message=f"There is no password stored for {website} website")
# Handle the case where the 'passwords.json' file is not found
except FileNotFoundError:
warning = messagebox.showwarning(title="Warning", message="No file found")
Here's a breakdown of what each part does:
-
The
try
block is used to catch exceptions that might occur during the execution of the code within it. -
with open('passwords.json', 'r') as file:
: This opens the 'passwords.json' file in read mode ('r'
). Thewith
statement ensures that the file is properly closed after its suite finishes. -
data = json.load(file)
: This loads the JSON data from the opened file into thedata
variable. -
website = website_field.get("1.0", END)[:-1]
: This gets the text from thewebsite_field
Text widget."1.0"
means "line 1, character 0", andEND
means the end of the text.[:-1]
is used to remove the trailing newline character. -
if website in data:
: This checks if thewebsite
is a key in thedata
dictionary loaded from the JSON file. -
If the
website
is found in thedata
:password = data[website]["password"]
: This gets the password associated with thewebsite
from thedata
dictionary.email = data[website]["email"]
: This gets the email associated with thewebsite
from thedata
dictionary.messagebox.showinfo(...)
: This displays an information message box showing the email and password associated with thewebsite
.
-
If the
website
is not found in thedata
:messagebox.showwarning(...)
: This displays a warning message box indicating that there is no password stored for thewebsite
.
-
The
except FileNotFoundError:
block catches theFileNotFoundError
exception that might occur if the 'passwords.json' file is not found. It displays a warning message box indicating that no file was found.
This function is designed to search for a password in the 'passwords.json' file based on the website entered by the user in the website_field
. If the website is found, it displays the associated email and password in an information message box. If the website is not found, it displays a warning message box. If the 'passwords.json' file is not found, it displays a warning message box indicating the absence of the file.
def generatePass():
# Delete any old password from the password field
passwordField.delete("1.0", END)
# Generate a new password
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', '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 = ['!', '#', '$', '%', '&', '(', ')', '*', '+']
# Create an empty list to store the characters of the password
password_list = []
# Add random letters to the password list (8 to 10 letters)
password_list += [choice(letters) for _ in range(randint(8, 10))]
# Add random symbols to the password list (5 to 6 symbols)
password_list += [choice(symbols) for _ in range(randint(5, 6))]
# Add random numbers to the password list (3 to 5 numbers)
password_list += [choice(numbers) for _ in range(randint(3, 5))]
# Shuffle the password list to mix the characters
shuffle(password_list)
# Join the characters in the password list to create the password
password = ''.join(password_list)
# Insert the generated password into the password field
passwordField.insert(END, password)
# Copy the password to the clipboard
pyperclip.copy(password)
Here's what each part does:
-
passwordField.delete("1.0", END)
: Clears any existing text in thepasswordField
, which is likely a tkinter Text widget used for displaying the generated password. -
letters
,numbers
, andsymbols
: These are lists containing characters to be used in generating the password—letters, numbers, and symbols. -
password_list = []
: Creates an empty list to store the characters of the generated password. -
password_list += [choice(letters) for _ in range(randint(8, 10))]
: Adds 8 to 10 random letters to thepassword_list
. -
password_list += [choice(symbols) for _ in range(randint(5, 6))]
: Adds 5 to 6 random symbols to thepassword_list
. -
password_list += [choice(numbers) for _ in range(randint(3, 5))]
: Adds 3 to 5 random numbers to thepassword_list
. -
shuffle(password_list)
: Shuffles the characters inpassword_list
to mix them up. -
password = ''.join(password_list)
: Joins the characters inpassword_list
into a single string to form the generated password. -
passwordField.insert(END, password)
: Inserts the generated password into thepasswordField
, likely displaying it to the user. -
pyperclip.copy(password)
: Copies the generated password to the clipboard, allowing the user to easily paste it elsewhere.
This function is designed to generate a random password with a mix of letters, numbers, and symbols, display it in a tkinter Text widget (passwordField
), and copy it to the clipboard for easy use.
def savePass():
# Get the text from the website, email, and password fields
website = website_field.get("1.0", END)
email = emailField.get("1.0", END)
password = passwordField.get("1.0", END)
# Create a new dictionary with website as key and email/password as values
new_data = {
website[:-1]: {
"email": email[:-1], # Remove the trailing newline character
"password": password[:-1] # Remove the trailing newline character
}
}
# Check if any of the fields are empty
if len(website) == 1 or len(password) == 1:
# Show a warning message if any field is empty
warning = messagebox.showwarning(title="Warning", message="You left one or more fields empty!")
else:
# Ask for confirmation to save the details
is_ok = messagebox.askokcancel(title=website, message=f"These are the details entered: \nEmail: {email}Password: {password} \nIs it ok to save?")
if is_ok:
try:
with open('passwords.json', 'r') as file:
# Read existing data from the 'passwords.json' file
data = json.load(file)
# Update the data with the new entry
data.update(new_data)
except FileNotFoundError:
# If the file doesn't exist, use the new_data as the initial data
data = new_data
finally:
with open('passwords.json', 'w') as file:
# Write the updated data back to the 'passwords.json' file
json.dump(data, file, indent=4)
# Clear the website and password fields after saving
website_field.delete("1.0", END)
passwordField.delete("1.0", END)
Here's a breakdown of what each part does:
-
website = website_field.get("1.0", END)
: Gets the text from thewebsite_field
Text widget, likely containing the website name. -
email = emailField.get("1.0", END)
: Gets the text from theemailField
Text widget, likely containing the email. -
password = passwordField.get("1.0", END)
: Gets the text from thepasswordField
Text widget, likely containing the password. -
new_data
: Creates a new dictionary with the website as the key and a nested dictionary with email and password as values. -
Checks if any of the fields are empty:
if len(website) == 1 or len(password) == 1:
: This condition checks if the length ofwebsite
orpassword
is 1, which usually means they are empty.
-
If any field is empty, it shows a warning message:
warning = messagebox.showwarning(...)
: Displays a warning message box if any field is empty.
-
If all fields are filled, it asks for confirmation to save the details:
is_ok = messagebox.askokcancel(...)
: Displays a confirmation message box with the entered details.
-
If the user confirms to save (
is_ok
isTrue
), it updates the JSON data:- It tries to open the 'passwords.json' file for reading.
- If the file exists, it reads the existing data from the file using
json.load(file)
. - It updates the existing data with the new entry using
data.update(new_data)
.
-
If the 'passwords.json' file doesn't exist, it uses the
new_data
as the initial data. -
Finally, it writes the updated data back to the 'passwords.json' file:
json.dump(data, file, indent=4)
: Writes the updateddata
dictionary back to the file with an indentation of 4 spaces.
-
It then clears the
website_field
andpasswordField
after saving, likely preparing for the next entry.
This function is designed to save the website, email, and password entered by the user into a JSON file named 'passwords.json'. Before saving, it checks if any field is empty and asks for confirmation from the user. If the file already exists, it updates the existing data with the new entry; otherwise, it creates a new file with the new entry.
# Create the main window
window = Tk()
window.title("Password Manager") # Set the title of the window
window.config(padx=20, pady=20) # Add padding to the window
# Create a Canvas widget for the logo
c = Canvas(width=200, height=200)
logoimg = PhotoImage(file="logo.png") # Load the logo image
c.create_image(60, 100, image=logoimg) # Place the logo image on the canvas
c.grid(row=0, column=1) # Grid placement of the canvas
# Labels and Text Entry for Website
website_label = Label(window, text="Website:") # Create a label for website
website_label.grid(row=1, column=0) # Grid placement of the website label
website_field = Text(window, height=1, width=20) # Create a text entry for website
website_field.grid(row=1, column=1, sticky='w') # Grid placement of the website text entry
website_field.focus() # Set focus to the website text entry
# Labels and Text Entry for Email/Username
emailLabel = Label(window, text="Email/Username: ") # Create a label for email
emailLabel.grid(row=2, column=0) # Grid placement of the email label
emailField = Text(window, height=1, width=40) # Create a text entry for email
emailField.insert(END, "upesddn@gmail.com") # Insert a default email
emailField.grid(row=2, column=1) # Grid placement of the email text entry
# Labels and Text Entry for Password
passwordLabel = Label(window, text="Password:") # Create a label for password
passwordLabel.grid(row=3, column=0) # Grid placement of the password label
passwordField = Text(window, height=1, width=20) # Create a text entry for password
passwordField.grid(row=3, column=1, sticky="w") # Grid placement of the password text entry
# Button to Generate Password
generate_button = Button(window, text="Generate Password", command=generatePass, height=1, width=20)
generate_button.grid(row=3, column=1, sticky="e") # Grid placement of the generate password button
# Button to Add Password
add_button = Button(window, text="Add", command=savePass, height=1, width=45) # Create a button to add password
add_button.grid(row=4, column=1) # Grid placement of the add button
# Button to Search for Password
search_button = Button(window, text="Search", command=searchPass, height=1, width=20) # Create a button to search for password
search_button.grid(row=1, column=1, sticky="e") # Grid placement of the search button
window.mainloop() # Start the main event loop for the window
Here's a basic explanation of the code:
-
Creating the Window and Setting Up:
- The
Tk()
function creates the main window for the application. window.title("Password Manager")
sets the title of the window to "Password Manager".window.config(padx=20, pady=20)
adds padding of 20 pixels to the x and y directions inside the window.
- The
-
Adding the Logo:
- A
Canvas
widget namedc
is created with a width and height of 200 pixels. - The logo image (
logo.png
) is loaded usingPhotoImage
. - The logo image is placed on the canvas at coordinates (60, 100).
- The canvas (
c
) is placed in the grid at row 0, column 1.
- A
-
Text Entries and Labels:
website_label
is a label with the text "Website:".website_field
is a text entry widget for the user to input the website.- It is placed in the grid at row 1, column 1.
- The
sticky='w'
option means it will stick to the west (left) side of its cell. website_field.focus()
sets the focus to this field when the window opens.
emailLabel
is a label with the text "Email/Username:".emailField
is a text entry widget for the user to input the email or username.- It has a default value of "upesddn@gmail.com" inserted into it.
- It is placed in the grid at row 2, column 1.
passwordLabel
is a label with the text "Password:".passwordField
is a text entry widget for the user to input the password.- It is placed in the grid at row 3, column 1.
- The
sticky="w"
option means it will stick to the west (left) side of its cell.
-
Buttons:
generate_button
is a button labeled "Generate Password" with the commandgeneratePass
.- It is placed in the grid at row 3, column 1, sticking to the east (right) side of its cell.
add_button
is a button labeled "Add" with the commandsavePass
.- It is placed in the grid at row 4, column 1.
search_button
is a button labeled "Search" with the commandsearchPass
.- It is placed in the grid at row 1, column 1, sticking to the east (right) side of its cell.
-
Main Loop:
window.mainloop()
starts the Tkinter event loop, which listens for events (such as button clicks, window resizing, etc.) and responds to them.
In summary, this code creates a simple password manager GUI using Tkinter. It includes fields for the website, email/username, and password. Users can generate passwords, add new password entries, and search for existing passwords. The logo is displayed on the canvas at the top of the window.