import imapclient
import email

"""
Explanation: Lesson 47:
Checking your Email Inbox
Python can be used read emails. 
The standard protocol for reading email is 'Internet Message Access Protocol' (IMAP). IMAP is a fairly complex protocol, and are basically as old as the internet itself; Python includes a module called imaplib, but its not very straightforward. 
Instead we will the imapclient and pyzmail modules. Unfortunately, pyzmail is not available for Python 3.4, so we will be using the default email module to simulate is functionality.
End of explanation
"""


conn = imapclient.IMAPClient('imap.gmail.com', ssl=True)

"""
Explanation: The first step in setting up email is creating a connection object again to interact with an email, but this time for the IMAP server.
This function takes a domain name, and an optional parameter asking if we are using SSL encrpytion (which is a variant of TLS discussed in Lesson 45). This domain name again depends on your email provider, an example list is available on Mr. Sweigarts blog in 16-2.
End of explanation
"""


# Real values were used in testing, and removed for Github
# Due to the nature of Gmail's security, you may have to allow access from 'less secure apps' (like this script)
# The setting can be changed here: https://www.google.com/settings/u/2/security/lesssecureapps

conn.login('youremail@gmail.com','yourpassword')

"""
Explanation: We can now pass in our login paramaters via the .login() method.
End of explanation
"""


conn.list_folders()

conn.select_folder('INBOX', readonly=True)

"""
Explanation: We get a byte string with a response if we login correctly.
Next we choose which email folder to access with the .select_folder method. You will typically want the 'Inbox' folder. We will also pass a readonly=True parameter to make sure we don't accidentally delete something. We can use the .list_folders() method to list all available folders, and switch the readonly parameter to false to actually edit messages.
End of explanation
"""


UIDs = conn.search('SINCE 26-May-2016')
print(UIDs)

"""
Explanation: We get a series of byte strings, if we have connected correctly. 
We can now search for specific emails. However, IMAP has its own search syntax, and requires special operators, and will return a list of UIDs (Unique IDs) describing each email. There are many available search keys, depending on the service, with more examples here in 16-3.
End of explanation
"""


conn.delete_messages([88130, 88131, 88132])

# The following function is also available in this module to search Gmail for a line of text. 
# I found this faster than iterating over the set to find the Python test email from Lesson 46
conn.gmail_search('Subject: Python Test Email')

"""
Explanation: We can use the .delete_messages() methods to delete a list of UIDs. We won't be running it here.
End of explanation
"""


rawMessage = conn.fetch([88177], ['BODY[]','FLAGS'])
print(rawMessage)

type(rawMessage)

"""
Explanation: We now have to translate these UIDs into the actual emails, and we can do that using the .fetch() method. 
It requires a list of UIDs to retrive, as well as list of what parts of the email you need; typically ['BODY[]','FLAGS'] which contains most of the information an average user might need.
Below is the email we sent as part of Lesson 46, which we will store in a variable.
End of explanation
"""


message = email.message_from_bytes(rawMessage[88177][b'BODY[]'])

"""
Explanation: Because this value is returned as a collections.defaultdict, we must use a series of keys to parse it and explore its values. This process is explained more thoroughly on Mr. Sweigart's blog.. 
Below is a rough explanation of the key approach, as initially  explain the process behind keys.
End of explanation
"""


print(message)
print(type(message))

"""
Explanation: Once this value has been stored, we can use the .get() method to pull out various variables from the email.
End of explanation
"""


message.get('Subject')

message.get('from')

"""
Explanation: We can now access different elements in this message object.
End of explanation
"""


message.get_payload()

"""
Explanation: The value for an email's body is defined as its 'payload', and accessible via the method get_payload()
End of explanation
"""


conn.logout()

"""
Explanation: We can end our session using the .logout method on the connection object.
End of explanation
"""


