Class-12-Project / manager.py
manager.py
Raw
try:
    from tkinter import *
    from tkinter import ttk
except ImportError:
    from Tkinter import *
    import ttk

import Add
import hashlib
import os
import encode
import List
import Search
import pickle


LARGE_FONT = ("Verdana", 13)
BUTTON_FONT = ("Sans-Serif", 10, "bold")
class Login(Tk):
    """docstring for Login"""
    
    def __init__(self, *args):
        Tk.__init__(self, *args)

        '''Needs update'''
        if os.name == 'nt':
            Tk.iconbitmap(self, default='icon.ico')
        Tk.wm_title(self, "Password Manager")
        self.state = {
            "text": "Login to access password database.", "val": False
        }
        if encode.password:
            self.addLoginFrame()
        else:
            self.addRegisterFrame()

        # Adding frames

    def addLoginFrame(self, *kwargs):
        login = Frame(self, padx=2, pady=2, bd=2)
        login.pack()

        loginLabel = Label(login, text=self.state['text'],
                           bd=10, font=LARGE_FONT, width=30)
        loginLabel.grid(row=0, columnspan=4)

        unameLabel = Label(login, text="Username")
        unameLabel.grid(row=1, column=0)
        uname = ttk.Entry(login)
        uname.grid(row=1, column=1, pady=3)
        uname.focus_set()
        
        entryLabel = Label(login, text="Password")
        entryLabel.grid(row=2, column=0)
        entry = ttk.Entry(login, show="*")
        entry.grid(row=2, column=1, pady=3)

        # _ marks an unused variable; used for lambda compatibility
        # Bind event for when enter is pressed in the Entry
        entry.bind('<Return>', lambda _: self.checkPwd(
            login, label=loginLabel, entry=entry, btn=submitBtn))
        entry.focus_set()

        r = ttk.Style()
        r.configure("Submit.TButton", font=BUTTON_FONT)
        registerBtn = ttk.Button(login, text="Register", style="Submit.TButton",
                               command=lambda:[login.destroy(), self.addRegisterFrame()])
        registerBtn.grid(row=3, column=0, pady=3)
        s = ttk.Style()
        s.configure("Submit.TButton", font=BUTTON_FONT)
        submitBtn = ttk.Button(login, text="Submit", style="Submit.TButton",
                               command=lambda: self.checkPwd(
                                   login, label=loginLabel, uname=uname, entry=entry,
                                   sbtn=submitBtn, rbtn=registerBtn, ulab=unameLabel, elab=entryLabel))

        submitBtn.grid(row=3, column=1, pady=3)
        
    """Kwargs = loginLabel, password entry, and submit button"""
    def checkPwd(self, frame, **kwargs):
        una= kwargs['uname'].get()
        chk = kwargs['entry'].get().encode('utf-8')
        # if username match
        if una in encode.password:
            if hashlib.md5(chk).hexdigest() == encode.password[una]:

                self.state['text'] = f"Logged In\nHello {una}!! "
                self.state['val'] = True
                Add.USER=una
                # Using .config() to modift the args
                kwargs['label'].config(text=self.state['text'])
                for i in ['elab','ulab','rbtn','uname','sbtn','entry']:
                    kwargs[i].grid_forget()
                
                
                # adding buttons
                self.addConfigBtn(frame)

            # If passwords don't match
            else:
                kwargs['label'].config(text=self.state['text'] + "\nWrong Password, Try Again!!!")
                # Removing previosly entered Passwords
                kwargs['entry'].delete(0, 'end')
            
        else:
                kwargs['label'].config(text=self.state['text'] + "\nUsername doesnt exist, Try Again!!!")
                # Removing previosly entered Passwords
                kwargs['entry'].delete(0, 'end')
                kwargs['uname'].delete(0, 'end')
            

    def addConfigBtn(self, login):
        # configured buttons
        # btnList = (addBtn, listBtn, getBtn)

        # Creating temp references to images using temp1,2,3 so as to disallow
        # garbage collection problems
        btnList = ["Add", "List", "Search"]
        btnCmdList = [lambda: Add.AddWindow(self),
                      lambda: List.ListWindow(self),
                      lambda: Search.SearchWindow(self)]
        f = []  # Frames array
        img = []  # image array
        self.temp = []  # temp array

        for i in range(3):
            f.append(Frame(login, padx=2, width=50, height=50))
            f[i].grid(row=3, column=i)
            img.append(PhotoImage(
                file=btnList[i] + ".png", width=48, height=48))
            self.temp.append(img[i])
            ttk.Button(f[i], image=img[i], text=btnList[i], compound="top",
                       style="Submit.TButton",
                       command=btnCmdList[i]).grid(sticky="NWSE")

    def addRegisterFrame(self, *arg):
        register = Frame(self, padx=2, pady=2, bd=2)
        register.pack()

        info = "Register with a Username and Password\nTo start using the manager"
        registerLabel = Label(register, text=info,
                              bd=10, font=LARGE_FONT, width=30)
        registerLabel.grid(row=0, columnspan=4)

        unameLabel = Label(register, text="Username")
        unameLabel.grid(row=1, column=0)
        uname = ttk.Entry(register)
        uname.grid(row=1, column=1, pady=3)
        uname.focus_set()
        
        entryLabel = Label(register, text="Password")
        entryLabel.grid(row=2, column=0)
        entry = ttk.Entry(register, show="*")
        entry.grid(row=2, column=1, pady=3)
        entry.bind('<Return>', lambda _: self.register(register,
                                                          uname, entry))

        s = ttk.Style()
        s.configure("Submit.TButton", font=BUTTON_FONT)
        submitBtn = ttk.Button(register, text="Register",
                               style="Submit.TButton",
                               command=lambda: self.register(register,
                                                              uname, entry))
        submitBtn.grid(row=3, column=1, pady=3)
        
    def register(self, frame, *pwd):
        error=""
        errorLabel = Label(frame, text=error,
                            bd=10, font=("Verdana", 11), fg="red")
        errorLabel.grid(row=4, column=1, pady=3)
        
        if  pwd[0].get() == "" or pwd[1].get() == "":
            error = "Username or Password is empty!!\nTry again."
            errorLabel.config(text=error)
        else:    
            # pwd is a list containing uname and password inputs
            if pwd[0].get() not in encode.password.keys():
                password = hashlib.md5(pwd[1].get().encode('utf-8')).hexdigest()
                encode.password[pwd[0].get()]= password
                # Saving password for future use.
                with open(".pwd", "wb") as outfile:
                    pickle.dump(encode.password,outfile)
                
                frame.destroy()
                self.addLoginFrame()
            else:
                error = "User already exists. Please Login!!\nOr try another name."
                errorLabel.config(text=error)

if __name__ == '__main__':
    new = Login()
    new.mainloop()