I'm working on a password manager using python in the PyCharm IDE. I am working with a database to store the passwords, which makes a .db file in the project folder. Then i wanted to clear that file as i wanted a clear db to work with. So i deleted the .db file from my folder, thinking it would create a new file and work fine. However, it did not.
I get the following error message:
Traceback (most recent call last):
File "C:/Users/Gebruiker/PycharmProjects/evault/main.py", line 246, in <module>
open_vault()
File "C:/Users/Gebruiker/PycharmProjects/evault/main.py", line 235, in open_vault
Label(vault, text=(array[i][1]), font=("Helvetica", 12)).place(x=400, y=400)
IndexError: list index out of range
I tried reverting changes with local history, but that wouldn't work for me either (or i just didn't understand)
[EDIT] Does it maybe have something to do with a new, so empty, database being created and then trying to display the contents of that database but failing as there are none? The deleted database file by me had contents, which did display. Might also be completely wrong, idk.
If it would help, this is my whole project code:
from tkinter import *
from tkinter import messagebox
from random import choice
import array
import sqlite3
import hashlib
import pyperclip as pc
from functools import partial
# Database
with sqlite3.connect("vault.db") as db:
cursor = db.cursor()
service = None
username = None
password = None
cursor.execute("""
CREATE TABLE IF NOT EXISTS vault (
id INTEGER PRIMARY KEY,
service TEXT NOT NULL,
username TEXT NOT NULL,
password TEXT NOT NULL);
""")
def hash_password(pw):
hash = hashlib.md5(pw)
hash = hash.hexdigest()
return hash
def validate_login():
# getting form data
uname = username_log.get()
pwd = master_key.get()
# applying empty validation
if uname == '' or pwd == '':
message.set("Please fill in all the fields")
else:
if uname == "Laurens" and pwd == "password":
login_screen.destroy()
open_vault()
else:
message.set("Wrong username or password")
def generate_password():
len = 12
digits = '0123456789'
chars = 'abcdefghijklmn' \
'opqrstuvwxyz'
up = chars.upper()
special = '_!$%&?'
all = digits chars up special
password = ''.join(
choice(all) for i in range(len)
)
# print out password
print(password)
save = messagebox.askyesnocancel("Generated password", f"Your generated safe password is: \n \n {password} "
f"\n \n Click yes to copy to clipboard"
f"\n and click no to generate a new password.")
if save:
# 'Yes' > copy to clipboard
pc.copy(password)
elif not save and save is not None:
# 'No' > generate new password
generate_password()
else:
# 'Cancel'
pass
def save_credentials():
service_input = service.get()
username_input = username.get()
password_input = password.get()
insert_fields = ("""INSERT INTO vault(service, username, password)
VALUES(?, ?, ?)
""")
cursor.execute(insert_fields, (service_input, username_input, password_input))
db.commit()
print(db)
open_vault()
def remove_credentials(input):
cursor.execute("DELETE FROM vault WHERE id = ?", (input,))
db.commit()
open_vault()
def register_credentials():
global service
global username
global password
vault.destroy()
register_screen = Tk()
register_screen.resizable(False, False)
register_screen.title("Login")
register_screen.geometry("350x500")
register_screen.configure(bg='#212121')
service = StringVar()
username = StringVar()
password = StringVar()
# Service Label
Label(register_screen, text="Name of service: ", bg='#212121', fg='#ABABAB').place(relx=0.5, y=100, anchor=CENTER)
# Service textbox
Entry(register_screen, textvariable=service).place(width=180, height=30, relx=0.5, y=140, anchor=CENTER)
# Username Label
Label(register_screen, text="Username: ", bg='#212121', fg='#ABABAB').place(relx=0.5, y=200, anchor=CENTER)
# Username textbox
Entry(register_screen, textvariable=username).place(width=180, height=30, relx=0.5, y=240, anchor=CENTER)
# Password Label
Label(register_screen, text="Password: ", bg='#212121', fg='#ABABAB').place(relx=0.5, y=300, anchor=CENTER)
# Password textbox
Entry(register_screen, textvariable=password).place(width=180, height=30, relx=0.5, y=340, anchor=CENTER)
# Generate password button
Button(register_screen, text="Generate safe password", bg='#ABABAB', fg='#000000', command=generate_password).place(
width=140, height=30, relx=0.5, y=400, anchor=CENTER)
# Save credentials button
Button(register_screen, text="Save credentials", bg='#673AB7', fg='#FFFFFF', command=save_credentials).place(
width=150, height=40, relx=0.5, y=460, anchor=CENTER)
register_screen.mainloop()
def login_screen():
global login_screen
global message
global username_log
global master_key
login_screen = Tk()
login_screen.resizable(False, False)
login_screen.title("Login")
login_screen.geometry("300x210")
login_screen.configure(bg='#212121')
# declaring variable
username_log = StringVar()
master_key = StringVar()
message = StringVar()
# Creating layout of login form
Label(login_screen, width="300", text="Please enter username and master key", bg="#673AB7", fg="#FFFFFF").pack()
# Username Label
Label(login_screen, text="Username: ", bg='#212121', fg='#ABABAB').place(x=20, y=40)
# Username textbox
Entry(login_screen, textvariable=username_log).place(x=90, y=42)
# Password Label
Label(login_screen, text="Master key: ", bg='#212121', fg='#ABABAB').place(x=20, y=80)
# Password textbox
Entry(login_screen, textvariable=master_key, show="*").place(x=90, y=82)
# Label for displaying login status[success/failed]
Label(login_screen, text="", textvariable=message, bg='#212121', fg='#ff0000').place(relx=0.5, y=125, anchor=CENTER)
# Login button
Button(login_screen, text="Login", width=10, height=1, bg='#673AB7', fg='#FFFFFF', command=validate_login).place(
x=110, y=150)
login_screen.mainloop()
def open_vault():
global vault
vault = Tk()
vault.resizable(False, False)
vault.title("Evault")
vault.geometry("750x500")
vault.configure(bg='#212121')
Label(vault, text="Service", bg='#212121', fg='#ABABAB').place(relx=0.2, y=75)
Label(vault, text="Username", bg='#212121', fg='#ABABAB').place(relx=0.45, y=75)
Label(vault, text="Password", bg='#212121', fg='#ABABAB').place(relx=0.7, y=75)
Button(vault, text="Register new credentials", bg='#673AB7', fg='#FFFFFF', command=register_credentials).place(
width=150, height=40, relx=0.5, y=450, anchor=CENTER)
cursor.execute('SELECT * FROM vault')
if cursor.fetchall() != None:
i = 0
while True:
cursor.execute('SELECT * FROM vault')
array = cursor.fetchall()
Label(vault, text=(array[i][1]), font=("Helvetica", 12)).place(x=400, y=400)
i = 1
cursor.execute('SELECT * FROM vault')
if len(cursor.fetchall()) <= i:
break
vault.mainloop()
open_vault()
CodePudding user response:
The error is being thrown by this:
cursor.execute('SELECT * FROM vault')
if cursor.fetchall() != None:
i = 0
while True:
cursor.execute('SELECT * FROM vault')
array = cursor.fetchall()
Label(vault, text=(array[i][1]), font=("Helvetica", 12)).place(x=400, y=400)
i = 1
cursor.execute('SELECT * FROM vault')
if len(cursor.fetchall()) <= i:
break
I confess I don't understand what this code is supposed to do. Why does it repeatedly execute the same query? You probably want something like this:
cursor.execute("SELECT * FROM vault")
START_HEIGHT=400
LINE_HEIGHT=50
for i, row in enumerate(cursor.fetchall()):
line_pos = START_HEIGHT i * LINE_HEIGHT
Label(vault, text=row[1]).place(x=400,y=line_pos)
i.e. just iterate over the rows returned by the cursor directly.
If that is still throwing an error, you need to do some debugging: print what cursor.fetchall()
actually returns. (Specifically, print list(cursor.fetchall())
in case it's an iterator.)