· 9 years ago · Apr 19, 2017, 01:32 AM
1# python ./AddressBook.py
2from tkinter import *
3
4
5
6###################################Christian code####################################################
7
8# python ./AddressBook.py
9
10import os
11
12class Contact:
13
14 def __init__(self, first_name = "", last_name = "", phone = "" , email = "", street_address = "", home_city = "", home_state = "", home_zip = ""):
15 self.name = first_name + " " + last_name
16
17 #if len(str(phone)) == 10 or len(str(phone)) == 11:
18 # errorMessages.append("phone number must be 10 numbers (including area code)")
19 #else:
20 self.phone = phone
21
22 #if '@' in email:
23 #...
24 #else:
25 self.email = email
26
27 #if len(str(home_zip)) == 5:
28 # errorMessages.append("zip code must be 5 numbers")
29 #else:
30 self.home = street_address + "\n" + home_city + ", " + home_state + " " + str(home_zip)
31
32 def __str__(self):
33 return("Name: {0}\nPhone Number: {1}\nE-mail Address: {2}\nHome Address: {3} ").format(self.name, self.phone, self.email, self.home)
34
35 def name(self, first_name, last_name):
36 self.name = first_name + " " + last_name
37
38 def email(self, email):
39 #if '@' in email:
40 # errorMessages.append("e-mail must contain a domain")
41 #else:
42 self.email = email
43
44 def phone(self, phone):
45 #if len(str(phone)) == 10 or len(str(phone)) == 11:
46 # errorMessages.append("phone number must be 10 numbers (including area code)")
47 #else:
48 self.phone = phone
49
50 def home(self, street_address = "", home_city = "", home_state = "", home_zip = ""):
51 #if len(str(home_zip)) == 5:
52 # errorMessages.append("zip code must be 5 numbers")
53 #else:
54 self.home = street_address + "\n" + home_city + ", " + home_state + " " + str(home_zip)
55
56 #def printErrorMessages(errorMessages):
57 # for error in errorMessages:
58 # print(error)
59
60
61contacts_list = []
62
63def retrieveContactInfo():
64 try:
65 contact_first_name = str(input("First Name: "))
66 contact_last_name = str(input("Last Name: "))
67 contact_phone = int(input("Phone Number: "))
68 contact_email = str(input("E-mail Address: "))
69 contact_street = str(input("Enter street address: "))
70 contact_city = str(input("Enter city: "))
71 contact_state = str(input("Enter state: "))
72 contact_zip = int(input("Enter zip code: "))
73
74 contact = Contact(contact_first_name, contact_last_name, contact_phone, contact_email,contact_street, contact_city, contact_state, contact_zip)
75
76 if len(contact.errorMessages) > 0:
77 print(contact.errorMessages)
78
79 return contact
80 except ValueError:
81 print("Not a valid entry")
82
83def addContact():
84 try:
85 contact = retrieveContactInfo()
86 contacts_list.append(contact)
87 except ValueError:
88 print("Error in the entry")
89
90
91def displayContacts():
92 if len(contacts_list) == 0:
93 for contact in contacts_list:
94 print(contact.name)
95 else:
96 "No Contacts"
97
98def searchContact():
99 found_contacts_list = []
100 search_contact = input("Search by Name or Number: ")
101 search_contact_input = search_contact.lower()
102
103 for contact in contacts_list:
104 contact_name = contact.name
105 contact_name = contact_name.lower()
106
107 if search_contact_input in contact_name or contact.phone == search_contact_input:
108 found_contacts_list.append(contact)
109
110 if found_contacts_list == []:
111 print("No Results Found")
112 else:
113 showContactInfo(contact)
114
115def showContactInfo(contact):
116 #incomplete until GUI
117 # Just return values into corresponding fields
118 print(contact)
119 #str(contact)
120
121def deleteContact():
122 try:
123 if contacts_list == []:
124 print("No Contacts")
125 else:
126 nameToDelete = input("Enter the name to delete:" )
127
128 for i in range(0, len(contacts_list)):
129 currContact = contacts_list[i].name
130 if nameToDelete in currContact:
131 print("deleting {0} ...".format(currContact))
132 del contacts_list[i]
133 except IndexError:
134 print("Out of range")
135
136
137#######################################################################################################################
138
139import sqlite3
140import os
141
142class UserAlreadyExistsException(Exception):
143 pass
144
145class UserNotFoundException(Exception):
146 pass
147
148class DatabaseNotConnectedException(Exception):
149 pass
150
151class DatabaseInterface:
152 '''Interface between the program functionality and the database storage of data.'''
153 #Names of database columns
154 class KEYS:
155 FirstName = 'FirstName'
156 LastName = 'LastName'
157 Phone = 'Phone'
158 Email = 'Email'
159 Address = 'Address'
160 def __iter__(self):
161 yield DatabaseInterface.KEYS.FirstName
162 yield DatabaseInterface.KEYS.LastName
163 yield DatabaseInterface.KEYS.Phone
164 yield DatabaseInterface.KEYS.Email
165 yield DatabaseInterface.KEYS.Address
166
167 def __init__(self, username):
168 self.__currentUser = str(username)
169 if self.__currentUser == ':memory:':
170 self.__currentUser = 'DEBUG'
171 self.__dbConnection = None
172
173 def __enter__(self):
174 self.Connect()
175 return self
176
177 def __exit__(self, exc_type, exc_value, traceback):
178 self.CloseOut()
179
180 def __rowToContact(self, row):
181 return Contact(row[DatabaseInterface.KEYS.FirstName],
182 row[DatabaseInterface.KEYS.LastName],
183 row[DatabaseInterface.KEYS.Phone],
184 row[DatabaseInterface.KEYS.Email],
185 row[DatabaseInterface.KEYS.Address])
186
187 @property
188 def CurrentUser(self):
189 return self.__currentUser
190
191 @property
192 def Contacts(self):
193 if self.__dbConnection == None:
194 raise DatabaseNotConnectedException()
195 return [self.__rowToContact(row) for row in self.__dbConnection.execute('select * from {}'.format(self.__currentUser)).fetchall()]
196
197 def Connect(self):
198 '''Connect to the database for the current user'''
199 self.__dbConnection = sqlite3.connect(os.path.join(os.getcwd(), 'contacts.db')
200 if self.__currentUser != 'DEBUG' else ':memory:') #debug
201 self.__dbConnection.row_factory = sqlite3.Row
202 self.__dbConnection.execute('''create table if not exists {} ({} text, {} text, {} int, {} text, {} text)'''
203 .format(self.__currentUser, *DatabaseInterface.KEYS()))
204 self.__dbConnection.execute('''create table is not exists Users (username text PRIMARY KEY, password text)''')
205
206 # def UserExists(self):
207 # '''Returns true if the current user of this database interface exists, false otherwise'''
208 # if self.__dbConnection == None:
209 # raise DatabaseNotConnectedException()
210 # return 0 != len(conn.execute('''select * from Users''').fetchall())
211
212 def RegisterUser(self, username, password):
213 '''Register a new user to the users table. Raises a UserAlreadyExists exception if username already exists'''
214 if self.__dbConnection == None:
215 raise DatabaseNotConnectedException()
216 if 0 != len(self.__dbConnection.execute('''select * from Users where username=?''', (username,)).fetchall()):
217 raise UserAlreadyExistsException()
218 self.__dbConnection.execute('''insert into Users (username, password) values (?, ?)''', (username, password))
219
220 def LoginExists(self, username, password):
221 '''Returns true if there exists user with username and their password is password'''
222 if self.__dbConnection == None:
223 raise DatabaseNotConnectedException()
224 if not self.UserExists(username):
225 return False
226 return self.__dbConnection.execute('''select * from Users where username=? and password=?''', (username, password)).fetchall()[0]['password'] == password
227
228 def Commit(self):
229 '''Commit changes to the database.
230 Not strictly necessary, as all changes will be committed
231 when Closing Out, but this function is here if you need it.'''
232 if self.__dbConnection == None:
233 raise DatabaseNotConnectedException()
234 if self.__dbConnection:
235 self.__dbConnection.commit()
236
237 def Close(self):
238 '''Close the database connection without committing.
239 Not for the faint of heart.'''
240 if self.__dbConnection == None:
241 raise DatabaseNotConnectedException()
242 self.__dbConnection.close()
243
244 def CloseOut(self):
245 '''Commit changes and close the database connection'''
246 if self.__dbConnection == None:
247 raise DatabaseNotConnectedException()
248 self.Commit()
249 self.Close()
250
251 def AddContact(self, contact):
252 '''Add contact into the current user's database'''
253 #Check if it's already in
254 #I would use unique and primary keys,
255 #but we have to check against both first and last name
256 if self.__dbConnection == None:
257 raise DatabaseNotConnectedException()
258 if self.__dbConnection.execute('''select exists(select 1 from {} where {}=? and {}=? limit 1)'''
259 .format(self.__currentUser,
260 DatabaseInterface.KEYS.FirstName,
261 DatabaseInterface.KEYS.LastName),
262 (contact.name.split(' '))).fetchone()[0] == 0:
263 name = None
264 try:
265 name = contact.name.split()
266 except AttributeError:
267 name = [None, None]
268 if len(name) < 2:
269 name.append(None)
270 self.__dbConnection.execute('''insert into {} ({}, {}, {}, {}, {}) values (?, ?, ?, ?, ?)'''
271 .format(self.__currentUser, *DatabaseInterface.KEYS()),
272 (name[0],
273 name[1],
274 contact.phone,
275 contact.email,
276 contact.home))
277 def Search(self, searchStr):
278 '''Returns a list of contacts that contain searchStr anywhere within any of their columns.
279 e.g. Search(813) will return people with 813 phone numbers and people who live on 813 North St.
280 Wildcards: % is 0 or more characters; _ is any single character. e.g. Search(8_3) returns numbers with 813 and 863.'''
281 if self.__dbConnection == None:
282 raise DatabaseNotConnectedException()
283 searchStr = '%' + searchStr + '%'
284 return [self.__rowToContact(row)
285 for row in self.__dbConnection.execute('''select * from {}
286 where {} like ? or
287 {} like ? or
288 {} like ? or
289 {} like ? or
290 {} like ?'''
291 .format(self.__currentUser,
292 *DatabaseInterface.KEYS()),
293 [searchStr for i in range(5)]).fetchall()]
294
295 def DeleteContact(self, contact):
296 '''Given a contact, deletes contacts with matching fields.'''
297 if self.__dbConnection == None:
298 raise DatabaseNotConnectedException()
299 name = None
300 try:
301 name = contact.name.split()
302 except AttributeError:
303 name = [None, None]
304 if len(name) < 2:
305 name.append(None)
306 self.__dbConnection.execute('delete from {} where {}=? and {}=? and {}=? and {}=? and {}=?'
307 .format(self.__currentUser,
308 *DatabaseInterface.KEYS()),
309 (name[0],
310 name[1],
311 contact.phone,
312 contact.email,
313 contact.home))
314
315 def EditContact(self, contact, newContact):
316 '''Given a contact, replaces the contact in the database with newContact'''
317 if self.__dbConnection == None:
318 raise DatabaseNotConnectedException()
319 name = None
320 try:
321 name = contact.name.split()
322 except AttributeError:
323 name = [None, None]
324 if len(name) < 2:
325 name.append(None)
326 newName = None
327 try:
328 newName = newContact.name.split()
329 except AttributeError:
330 newName = [None, None]
331 while len(newName) < 2:
332 newName.append(None)
333
334 self.__dbConnection.execute('update {} set {}=?, {}=?, {}=?, {}=?, {}=? where {}=? and {}=?'
335 .format(self.__currentUser,
336 *DatabaseInterface.KEYS(),
337 *DatabaseInterface.KEYS()),
338 (newName[0],
339 newName[1],
340 newContact.phone,
341 newContact.email,
342 newContact.home,
343 name[0],
344 name[1]))
345
346
347##########################################Jacobs code##################################################################
348class LoginP():
349 def __init__(self, master):
350 self.master = master
351 self.frame = Frame(self.master)
352 self.insideFrame = Frame(width=200, height=100)
353 master.geometry("950x550+500+150")
354 master.resizable(width=False, height=False)
355
356 self.LoginID = Entry(master, width=25)
357 #LoginID.insert(0, 'Login ID')
358 self.LoginID.place(x=325, y=155)
359 self.LoginIDLabel = Label(text="Login ID")
360 self.LoginIDLabel.place(x=325, y=175)
361
362 self.LoginPASS = Entry(width=25)
363 #LoginPASS.insert(0, 'Password')
364 self.LoginPASS.place(x=325, y=255)
365 self.LoginPasswordLabel = Label(text="Password")
366 self.LoginPasswordLabel.place(x=325, y=275)
367
368 self.insideFrame.place(x=325, y=325)
369
370 def checkLoginInput():
371 self.loginInput = self.LoginID.get()
372 self.passwordInput = self.LoginPASS.get()
373
374 if DatabaseInterface.LoginExists(self.loginInput, self.passwordInput):
375 self.load_window()
376 else:
377 self.loginFailLabel = Label(text="User does not exist")
378 self.oginFailLabel.place(x=325, y=135)
379
380 self.loginButton = Button(self.insideFrame, text='login', width=28, command=checkLoginInput)
381 self.loginButton.pack()
382
383 self.newUserButton = Button(self.insideFrame, text='New User Registration', width=28, command=self.new_window)
384 self.newUserButton.pack()
385
386 def __close(self):
387 self.LoginID.destroy()
388 self.IDlbl.destroy()
389 self.LoginPASS.destroy()
390 self.PASSlbl.destroy()
391 self.button1.destroy()
392 self.button2.destroy()
393
394
395 def new_window(self):
396 self.newWindow = Toplevel(self.master)
397 self.app = RegisterP(self.newWindow)
398
399 def load_window(self):
400 self.newWindow = self.master
401 self.app = MainP(self.newWindow)
402 self.__close()
403
404#where yours guys code need to be put in the button functions
405class MainP():
406 def __init__(self, master):
407 self.master = master
408 self.frame = Frame(self.master)
409 self.insideFrame = Frame(width=200, height=100)
410 master.geometry("950x550+500+150")
411 master.resizable(width=False, height=False)
412
413 self.AddressL = Listbox()
414 self.AddressL.place(x=0, y=0)
415 self.AddressL.config(width=45, height=34)
416
417 self.insideFrame.place(x=275, y=485)
418
419
420
421
422 #################button functions##########################
423
424
425 #create new contact
426 #allow to edit entry boxes
427 #def contactCB():
428 #try:
429 #contact = retrieveContactInfo()
430 #contacts_list.append(contact)
431 # except ValueError:
432 # print("Error in the entry")
433 self.Newbtn = Button(self.insideFrame, text='New', width=18)
434 self.Newbtn.pack(side=LEFT)
435
436
437 #allow to edit entry boxes
438
439 self.Editbtn = Button(self.insideFrame, text='Edit', width=18)
440 self.Editbtn.pack(side=LEFT)
441
442 #save contact information to current contacts data parameters
443 #disable editing entry boxes
444 self.Savebtn = Button(self.insideFrame, text='Save', width=18)
445 self.Savebtn.pack(side=LEFT)
446
447 #delete contact from list
448 self.Deletebtn = Button(self.insideFrame, text='Delete', width=18)
449 self.Deletebtn.pack(side=LEFT)
450
451 #just disable entry boxes and not save changes
452 self.Cancelbtn = Button(self.insideFrame, text='Cancel', width=18)
453 self.Cancelbtn.pack(side=LEFT)
454
455
456
457
458 #formating for labels and entry boxes
459
460 self.Fname = Entry(width=25, state=DISABLED).place(x=325, y=155)
461 self.Fnamelbl = Label(text="First Name").place(x=325, y=175)
462
463 self.Fname = Entry(width=25, state=DISABLED).place(x=325, y=155)
464 self.Fnamelbl = Label(text="First Name").place(x=325, y=175)
465
466 self.Lname = Entry(width=25, state=DISABLED).place(x=575, y=155)
467 self.Lnamelbl = Label(text="Last Name").place(x=575, y=175)
468
469 self.Phone = Entry(width=25, state=DISABLED).place(x=325, y=195)
470 self.Phonelbl = Label(text="Phone Number").place(x=325, y=215)
471
472 self.Email = Entry(width=25, state=DISABLED).place(x=325, y=235)
473 self.Emaillbl = Label(text="Email").place(x=325, y=255)
474
475 self.Street = Entry(width=25, state=DISABLED).place(x=325, y=275)
476 self.Streetlbl = Label(text="Address").place(x=325, y=295)
477
478 self.City = Entry(width=25, state=DISABLED).place(x=325, y=315)
479 self.Citylbl = Label(text="City").place(x=325, y=335)
480
481 self.State = Entry(width=25, state=DISABLED).place(x=325, y=355)
482 self.Statelbl = Label(text="State").place(x=325, y=375)
483
484 self.Zip = Entry(width=25, state=DISABLED).place(x=325, y=395)
485 self.Ziplbl = Label(text="Zip Code").place(x=325, y=415)
486
487#############dont worry about stuff here for now#######################
488class RegisterP:
489 def __init__(self, master):
490 self.master = master
491 self.frame = Frame(self.master)
492 #self.insideFrame = Frame(width=200, height=100)
493 master.geometry("950x550+500+150")
494 master.resizable(width=False, height=False)
495
496 self.usernameEntry = Entry(width=25, state=DISABLED).place(x=325, y=155)
497 self.userNameLabel = Label(text="Username: ").place(x=325, y=175)
498
499 self.passwordEntry = Entry(width=25, state=DISABLED).place(x=575, y=155)
500 self.passwordLabel = Label(text="Password: ").place(x=575, y=175)
501
502 self.reenterPasswordEntry = Entry(width=25, state=DISABLED).place(x=325, y=195)
503 self.reenterPasswordLabel = Label(text="Re-Enter Password: ").place(x=325, y=215)
504
505 #self.firstNameEntry = Entry(width=25, state=DISABLED).place(x=325, y=155)
506 #self.firstNameLabel = Label(text="First Name: ").place(x=325, y=175)
507
508 #self.lastNameEntry = Entry(width=25, state=DISABLED).place(x=575, y=155)
509 #self.lastNameLabel = Label(text="Last Name: ").place(x=575, y=175)
510
511 #self.phoneEntry = Entry(width=25, state=DISABLED).place(x=325, y=195)
512 #self.phoneLabel = Label(text="Phone Number: ").place(x=325, y=215)
513
514 #self.emailEntry = Entry(width=25, state=DISABLED).place(x=325, y=235)
515 #self.emailLabel = Label(text="Email: ").place(x=325, y=255)
516
517 #self.streetEntry = Entry(width=25, state=DISABLED).place(x=325, y=275)
518 #self.streetLabel = Label(text="Address: ").place(x=325, y=295)
519
520 #self.cityEntry = Entry(width=25, state=DISABLED).place(x=325, y=315)
521 #self.cityLabel = Label(text="City: ").place(x=325, y=335)
522
523 #self.stateEntry = Entry(width=25, state=DISABLED).place(x=325, y=355)
524 #self.stateLabel = Label(text="State: ").place(x=325, y=375)
525
526 #self.zipEntry = Entry(width=25, state=DISABLED).place(x=325, y=395)
527 #self.zipLabel = Label(text="Zip Code: ").place(x=325, y=415)
528
529 def registerUser():
530 self.usernameInput = self.usernameEntry.get()
531 self.passwordInput = self.passwordEntry.get()
532 self.reenteredPasswordInput = self.reenterPasswordEntry.get()
533
534 if self.passwordInput == self.reenteredPasswordInput:
535 DatabaseInterface.RegisterUser(self.usernameInput, self.passwordInput)
536 else:
537 self.passwordsMismatchlabel = Label(text="Passwords do not match")
538 self.passwordsMismatchlabel.place(x=325, y=135)
539
540 self.registerButton = Button(self.insideFrame, text='login', width=28, command=registerUser)
541 self.registerButton.pack()
542
543 self.cancelButton = Button(self.insideFrame, text='New User Registration', width=28, command=self.new_window)
544 self.cancelButton.pack()
545
546 def close_windows(self):
547 self.master.destroy()
548
549def main():
550 root = Tk()
551 app = LoginP(root)
552 root.mainloop()
553
554if __name__ == '__main__':
555 main()
556
557####################################################################################################################