# coding=utf-8 import imaplib # GUI library for password entry import tkinter as tk import os # Modify the following lines as directed in the exercise. # Initially, no mailbox is selected for display. IMAP_SERVER = 'outlook.office365.com' EMAIL_POSTFIX = '@msoe.edu' IMAP_MAILBOX = 'Inbox' IMAP_MESSAGE_NUM = '1' IMAP_MESSAGE_FETCH_SPEC = '(BODY[])' IMAP_PRINT_FETCH_DATA = False # You can experiment with some of these message fetch specifications. # IMAP_MESSAGE_FETCH_SPEC = '(BODY)' # IMAP_MESSAGE_FETCH_SPEC = '(BODY[HEADER])' # IMAP_MESSAGE_FETCH_SPEC = '(BODY[1])' # IMAP_MESSAGE_FETCH_SPEC = '(BODY[HEADER.FIELDS (FROM SUBJECT)])' # IMAP_MESSAGE_FETCH_SPEC = '(BODYSTRUCTURE)' # IMAP_MESSAGE_FETCH_SPEC = '(BODY[TEXT])' def main(): # Prompt user for email password (imap_user, password) = login_gui() imap_interface = imaplib.IMAP4_SSL(IMAP_SERVER) imap_interface.login(imap_user,password) password = '' # Clear password once used for extra security (especially when debugging) # Uncomment the ".debug" line to get IMAP debugging output. # Don't turn on debug earlier than this point in the code, # or your password will appear in clear text in the output!! imap_interface.debug = 4 mailboxes = imap_interface.list() # print "mailboxes=",mailboxes # Status is in the first element of "list" return value print('### List status = {0}'.format(mailboxes[0])) # Mailboxes are in the second element of "list" return value for mbox in mailboxes[1]: print('### Mailbox = {0}'.format(mbox)) # If a mailbox was specified, fetch its contents. if IMAP_MAILBOX: print('### Fetching mailbox "{0}"'.format(IMAP_MAILBOX)) imap_interface.select(IMAP_MAILBOX) # Search for "ALL" messages in mailbox. search_criteria = "ALL" (status,data) = imap_interface.search(None,search_criteria) print('### Search status = "{0}"'.format(status)) # print 'data="{0}"'.format(data) # Get string with message numbers, and separate them into a list. message_numbers = data[0].split() print('### Found {0} messages in mailbox'.format(len(message_numbers))) # print 'message_numbers=',message_numbers # Limit number of messages to list? # Modify the "slice" specification if you want to change the messages listed. message_numbers = message_numbers[0:5] # print 'message_numbers limited =',message_numbers for num in message_numbers: status,data = imap_interface.fetch(num,'(UID BODY[TEXT])') print('### Fetch status = "{0}"'.format(status)) print('### Message {0}:\n {1}\n\n'.format(num, data[0][1])) if IMAP_MESSAGE_NUM: print('### Processing message {0} . . .'.format(IMAP_MESSAGE_NUM)) status,data = imap_interface.fetch(IMAP_MESSAGE_NUM,IMAP_MESSAGE_FETCH_SPEC) print('### Message {0} fetch status = {1} data length = {2}'.format(IMAP_MESSAGE_NUM, status, len(data))) if IMAP_PRINT_FETCH_DATA: for dd in data: if isinstance(dd,tuple) and len(dd) == 2: print( '### Fetch data: envelope = {0},' ' data:\n####Begin####{1}\n####End####'.format(dd[0], dd[1])) else: print('### Fetch data length = {0} data: {1}'.format(len(dd), dd)) with open('imaplib-mail.txt','wb') as outfile: # Element 'data[0]' should (almost?) always be a tuple (pair) with envelope # info (fetch spec and length) and data, # but handle the case when it might not be, just in case. if isinstance(data[0],tuple) and len(data[0]) == 2: print('### Writing data from fetch tuple, envelope: "{0}"'.format(data[0][0])) outfile.write(data[0][1]) else: print("### Writing data from fetch object") outfile.write(data[0]) # Close the selected mailbox imap_interface.close() imap_interface.logout() def login_gui(): """Creates a graphical user interface for secure user authorization. Returns: email_value -- The user's email as a string. password_value -- The password as a string. Author: Tripp Horbinski """ gui = tk.Tk() gui.title("MSOE Email Client") center_gui_on_screen(gui, 370, 120) tk.Label(gui, text="Please enter your MSOE credentials below:") \ .grid(row=0, columnspan=2) tk.Label(gui, text="Email Address: ").grid(row=1) tk.Label(gui, text="Password: ").grid(row=2) username = tk.StringVar() username_input = tk.Entry(gui, textvariable=username) username_input.grid(row=1, column=1) password = tk.StringVar() password_input = tk.Entry(gui, textvariable=password, show='*') password_input.grid(row=2, column=1) auth_button = tk.Button(gui, text="Authenticate", width=25, command=gui.destroy) auth_button.grid(row=3, column=1) gui.mainloop() username_value = username.get() password_value = password.get() return username_value, password_value def center_gui_on_screen(gui, gui_width, gui_height): """Centers the graphical user interface on the screen. Args: gui: The graphical user interface to be centered. gui_width: The width of the graphical user interface. gui_height: The height of the graphical user interface. Returns: The graphical user interface coordinates for the center of the screen. Author: Tripp Horbinski """ screen_width = gui.winfo_screenwidth() screen_height = gui.winfo_screenheight() x_coord = (screen_width / 2) - (gui_width / 2) y_coord = (screen_height / 2) - (gui_height / 2) return gui.geometry('%dx%d+%d+%d' % (gui_width, gui_height, x_coord, y_coord)) main()