import sys
import os
import debug
import sqlite3 as lite
import Tkinter as tk
import Pmw as p
import tkshortcuts as tksc
import database as acdb
class Gui(tk.Frame):
"""Generic GUI, to be fitted to a root window.
Root window fitting should occur in the main script, or should
be defined in __init__ of classes derived from Gui.
initial parameters include parent (root), dimensions, and title
"""
def __init__(self, master=None, w=350, h=225, title='GUI', background='white'):
self.root = master
if not self.root:
self.root = tk.Tk()
self.w = w
self.h = h
self.root.geometry(str(w)+'x'+str(h))
self.frame = tk.Frame(self.root, background=background)
self.frame.grid(row=0, column=0, sticky="nsew")
self.make_ui(title)
def make_ui(self, title):
self.root.title(title)
class UVW(Gui):
"""User Verification Window (UVW), from Gui class.
Asks for username/password before allowing ability to
view/export/add/update database information.
default database is bender_acdb.db
"""
def __init__(self, db='bender_acdb.db', text="powered by python"):
Gui.__init__(self, title="ACDBMS -- User Verification Window")
self.db = db
self.tick = 0
self.default_text = text
def __str__(self):
return "Bender Lab Animal Colony Database Management System\nUser Verification Window"
def make_ui(self, title):
self.root.title(title)
self.title1 = tk.Label(self.frame, text="BENDER LAB ANIMAL COLONY")
self.title1.grid(row=0, column=0, columnspan=2, pady=5, padx=5)
self.title2 = tk.Label(self.frame, text="DATABASE MANAGEMENT SYSTEM")
self.title2.grid(row=1, column=0, columnspan=2, pady=5, padx=5)
import base64 as b64
import urllib
URL = "http://i.imgur.com/QipJK26.gif"
u = urllib.urlopen(URL)
raw_data = u.read()
u.close()
if debug.level > 0: print "image fetched, len=", len(raw_data)
image = tk.PhotoImage(data=b64.encodestring(raw_data))
self.image = tk.Label(self.frame, image=image)
self.image.img = image
self.image.grid(row=0, column=2, rowspan=5)
self.un_frame, self.un_entry = tksc.make_entry(frame=self.frame, caption="Username : ")
self.un_frame.grid(row=2, column=0, columnspan=2, pady=2, padx=5)
self.un_entry.bind("<Return>", self.entry_callback)
self.pw_frame, self.pw_entry = tksc.make_entry(frame=self.frame, caption="Password : ", show="*")
self.pw_frame.grid(row=3, column=0, columnspan=2, pady=2, padx=5)
self.pw_entry.bind("<Return>", self.entry_callback)
self.button = tk.Button(self.frame, text="ENTER", command=self.authenticate)
self.button.grid(row=4, column=0, columnspan=2, pady=5, padx=5)
self.qb = tk.Button(self.frame, text="QUIT", command=self.quit_uvw)
self.qb.grid(row=0, column=2, columnspan=2, pady=5, padx=5)
self.title3 = tk.Label(self.frame, text="powered by python")
self.title3.grid(row=5, column=0, columnspan=2, pady=3, padx=5)
def entry_callback(self, event):
self.authenticate()
def quit_uvw(self):
sys.exit()
def authenticate(self):
un = self.un_entry.get()
pw = self.pw_entry.get()
if not un or not pw:
self.button.config(text="ENTER")
self.title3.config(text="UN/PW MISSING")
return
self.tick += 1
if debug.level > 0:
print "AUTHENTICATING, attempt =", self.tick
search = {}
search['Username']=un
cur = acdb.Colony_cur(self.db, table='Scientists')
check = cur.get(columns='Password', search_param=search)
if debug.level > 0:
try:
check[0][0]
print "input :\n\tUsername =", un, "\n\tPassword =", pw, "\n\tdictionary =", check[0][0], '\n'
except IndexError:
print "input :\n\tUsername =", un, "\n\tPassword =", pw, "\n\tdictionary = NO CORRESPONDING USERNAME ENTRY\n"
if check:
if check[0][0] == pw:
if debug.level > 0:
print "Username and Password match! (check[0][0] == pw)\n"
self.button.config(text="CORRECT")
self.title3.config(text="CLEARED FOR ACCESS")
self.tick = 0
self.user = un
self.next()
return
if debug.level > 0:
print "Username and Password NOT MATCHED. (check[0][0] != pw)\n"
self.button.config(text="INCORRECT UN/PW, TRY AGAIN")
self.title3.config(text=self.default_text)
if self.tick >= 5:
if debug.level > 0:
print "Too many attempts.... pausing for", (self.tick/2.5)**4, "seconds..."
import time
self.button.config(command=None)
self.title3.config(text="TOO MANY ATTEMPTS : TIME OUT")
time.sleep((self.tick/2.5)**4)
self.button.config(command=self.authenticate)
self.title3.config(text=self.default_text)
def next(self, user=None):
if not user:
user=self.user
if debug.level > 0:
print "user passed to MAIN() =", user, "\n"
main = MAIN(db=self.db, user=self.user)
self.root.destroy()
main.root.mainloop()
print "Finished"
class MAIN(Gui):
"""Main Colony Acces Window (MAIN), from Gui class.
Gives access to table manipulation based on tables that user
has access to as defined in database (current user derived from UVW input)
defaults:
-database is bender_acdb.db
-user is from UVW()
"""
def __init__(self, db='bender_acdb.db', user=None):
if not user:
return
self.fancy_format = {
'admin': 1,
'user': 1,
'mice': 1,
'scientists': 1,
'add mice': 0,
'update mice': 2,
'search mice': 2,
'reserve mice': 2,
'sac mice': 2,
'add scientists': 0,
'update scientists': 2,
'search scientists': 2,
}
self.db = db
self.user = user
self.user_class = None
cur = acdb.Colony_cur(self.db, table='Scientists')
search = {}
search['Username']=self.user
if debug.level > 0:
print "search_param =", search
check = cur.get(columns='User_class', search_param=search)
self.user_class = check[0][0]
if debug.level > 0:
print "\ncheck =", check
print "check[0][0] =", check[0][0]
print "\nAUTHORIZED USER =", self.user
print "AUTHORIZATION LEVEL =", self.user_class
Gui.__init__(self, title="ACDBMS -- Main Window", w=800, h=500, background='wheat')
if self.user_class not in ['admin', 'user']:
print "AUTHORIZATION DENIED FOR USER", self.user
sys.exit()
def make_ui(self, title):
p.initialise(self.root)
self.root.title(title)
if self.user_class == 'admin':
self.admin_ui()
elif self.user_class == 'user':
self.user_ui()
def user_ui(self, format='Mice'):
self.display_title = tk.Label(self.frame, text="DISPLAY")
self.display_title.grid(row=0, column=0, padx=5, sticky="w")
self.display = tk.Text(self.frame, state=tk.DISABLED)
self.display.grid(row=1, column=0, padx=5, pady=1, sticky="w")
self.show("DATA TO BE DISPLAYED HERE")
self.title1 = tk.Label(self.frame, text=("User : %s\nAuthorization Level : %s" % (self.user, self.user_class)))
self.title1.grid(row=0, column=1, columnspan=2, pady=5, padx=5, sticky="e")
self.arcframe = self.make_arcframe(self.frame, format=format)
self.arcframe.grid(row=1, column=2, columnspan=2, pady=5, padx=5, sticky="e")
self.qb = tk.Button(self.frame, text="QUIT", command=self.quit_main)
self.qb.grid(row=2, column=2, pady=2, padx=2, sticky='e')
self.mmb = tk.Button(self.frame, text="MAIN MENU", command=self.return_main)
self.mmb.grid(row=3, column=2, pady=1, padx=2, sticky='e')
def admin_ui(self):
self.user_ui(format='admin')
def change_ui(self, selection):
if debug.level > 0:
print "\nSTARTING change_ui....\n\tselection =", selection
if selection.lower() == 'user':
self.selection = 'Mice'
else:
self.selection = selection
self.new_arcframe = self.make_arcframe(self.frame, format=self.selection)
if self.new_arcframe == None:
print "ERROR : FORMAT NOT RECOGNIZED"
self.new_arcframe = 0
return
self.arcframe.grid_forget()
self.arcframe = self.new_arcframe
self.arcframe.grid(row=1, column=1, columnspan=2, pady=5, padx=5)
def make_arcframe(self, frame, format='admin'):
"""Establishes an 'arcframe' based on input format.
Defaults to an admin arcframe, returns None if invalid format
Note that the Tk() that this frame belongs to must have Pmw initialized.
"""
data = None
self.format = format
if debug.level > 0:
print "format =", format
arcframe = tk.Frame(frame)
self.arc_dict = {}
if format.lower() == 'admin':
label = "What would you like to access?"
items = ['Mice', 'Scientists']
elif format.lower() == 'mice':
label = "MOUSE COLONY\nWhat do you want to do?"
items = ['add mice', 'update mice', 'reserve mice', 'sac mice', 'search mice']
elif format.lower() == 'scientists':
label = "RESEARCHER INFORMATION\nWhat do you want to do?"
items = ['add scientists', 'update scientists', 'search scientists']
elif self.fancy_format[format.lower()] in [0,2]:
l_format = format.split()
label = format.upper()
if l_format[0].lower() in ['add', 'update', 'search', 'reserve', 'sac']:
if l_format[1].lower() == 'mice':
data = ['Gender', 'Genotype', 'Dob', 'Sac', 'Reservation', 'Virus', 'Notes']
elif l_format[1].lower() == 'scientists':
data = ['Username', 'Password', 'User_class', 'Type', 'Name', 'Email']
label = format.upper()
else:
print "ERROR : INVALID FORMAT KEY"
return None
if data:
self.data = data
if debug.level > 0:
print "format is now =", format
print "fancy_format value is =", self.fancy_format[format.lower()]
if self.fancy_format[format.lower()]==0:
self.title1 = tk.Label(arcframe, text=label)
self.title1.grid(row=0, column=0, columnspan=2, pady=5, padx=5)
for i in range(len(data)):
f, self.arc_dict[data[i]+'_entry'] = tksc.make_entry(frame=arcframe, caption=data[i])
f.grid(row=i+1, column=0, columnspan=2, pady=2, padx=5)
self.add_button = tk.Button(arcframe, text="ADD", command=self.add_callback)
self.add_button.grid(row=len(data)+2, column=0, columnspan=1, pady=5, padx=5)
return arcframe
elif self.fancy_format[format.lower()]==1:
self.title1 = tk.Label(arcframe, text=label)
self.title1.grid(row=0, column=0, columnspan=2, pady=5, padx=5)
for i in range(len(items)):
if debug.level > 0:
print "\ti =", i
print "\titems[i] =", items[i]
print "\tself.arc_dict[", items[i], "+'_button']"
self.arc_dict[items[i]+'_button'] = tk.Button(arcframe, text=items[i], command=lambda i=i: self.change_ui(items[i]))
self.arc_dict[items[i]+'_button'].grid(row=i+1, column=0, columnspan=2, pady=2, padx=5)
if debug.level > 0:
print "\tself.arc_dict =", self.arc_dict
for i in self.arc_dict:
print i, "calls to", self.arc_dict[i].cget("command")
return arcframe
elif self.fancy_format[format.lower()]==2:
self.title2 = tk.Label(arcframe, text='SEARCH DATA')
self.title2.grid(row=1, column=0, columnspan=2, pady=5, padx=5)
for i in range(len(data)):
f, self.arc_dict[data[i]+'_s_entry'] = tksc.make_entry(frame=arcframe, caption=data[i])
f.grid(row=i+2, column=0, columnspan=2, pady=2, padx=5)
if 'search' not in format:
self.title3 = tk.Label(arcframe, text='UPDATED DATA')
self.title3.grid(row=1, column=2, columnspan=2, pady=5, padx=5)
for i in range(len(data)):
f, self.arc_dict[data[i]+'_u_entry'] = tksc.make_entry(frame=arcframe, caption=data[i])
f.grid(row=i+2, column=2, columnspan=2, pady=2, padx=5)
self.change_button = tk.Button(arcframe, text=l_format[0].upper(), command=self.change_callback)
self.change_button.grid(row=len(data)+3, column=2, columnspan=1, pady=5, padx=5)
else:
self.change_button = tk.Button(arcframe, text=l_format[0].upper(), command=self.change_callback)
self.change_button.grid(row=len(data)+2, column=0, columnspan=1, pady=5, padx=5)
if debug.level > 0:
print self.arc_dict
if 'sac' in format:
self.arc_dict['Sac_u_entry'].insert(0, "SACRIFICED")
if 'reserve' in format:
self.arc_dict['Reservation_u_entry'].insert(0, "RESERVED")
return arcframe
def show(self, results):
self.display.config(state=tk.NORMAL)
self.display.insert(tk.END, '\n----------------\n')
self.display.insert(tk.END, results)
self.display.config(state=tk.DISABLED)
def quit_main(self):
sys.exit()
def return_main(self):
self.change_ui(self.user_class)
def add_callback(self):
dict = {}
for i in self.data:
if i == '':
self.title1.config(text='MUST PROVIDE DATA FOR ALL CELLS, TRY AGAIN')
return
if not self.arc_dict[i+'_entry'].get() == '':
dict[i] = self.arc_dict[i+'_entry'].get()
cur = acdb.Colony_cur()
if 'mice' in self.format:
result = cur.add_mouse(data_dict=dict)
elif 'scientists' in self.format:
result = cur.add_sci(data_dict=dict)
self.title1.config(text='SUCCESSFULLY ADDED TO DATABASE\nCONTINUE OR RETURN TO MAIN MENU')
if debug.level > 0:
print result[0]
self.show(result[0])
def change_callback(self):
dd = {}
if 'mice' in self.format:
sp = {'Sac': 'no', 'Reservation': 'none'}
else:
sp = {}
for i in self.data:
if i == '':
self.title1.config(text='MUST PROVIDE DATA FOR ALL CELLS, TRY AGAIN')
return
if 'search' not in self.format:
if not self.arc_dict[i+'_u_entry'].get() == '':
dd[i] = self.arc_dict[i+'_u_entry'].get()
if not self.arc_dict[i+'_s_entry'].get() == '':
sp[i] = self.arc_dict[i+'_s_entry'].get()
if debug.level > 0:
print "self.format =", self.format
if 'search' in self.format:
if 'mice' in self.format:
cur = acdb.Colony_cur()
result = cur.get(search_param=sp)
elif 'scientists' in self.format:
cur = acdb.Colony_cur(table='Scientists')
result = cur.get(table='Scientists', search_param=sp)
else:
if 'mice' in self.format:
cur = acdb.Colony_cur()
result = cur.update_mouse(data_dict=dd, search_param=sp)
elif 'scientists' in self.format:
print "here!"
cur = acdb.Colony_cur(table='Scientists')
result = cur.update_sci(data_dict=dd, search_param=sp)
self.title1.config(text='SUCCESSFULLY CHANGED IN DATABASE\nCONTINUE OR RETURN TO MAIN MENU')
if debug.level > 0:
print result
self.show(tuple(cur.col_list))
for i in range(len(result)):
if debug.level > 0:
print i
print result[i]
self.show(result[i])