-
-
Save styrmis/9637945 to your computer and use it in GitHub Desktop.
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| # copies of the Software, and to permit persons to whom the Software is | |
| # furnished to do so, subject to the following conditions: | |
| # | |
| # The above copyright notice and this permission notice shall be included in | |
| # all copies or substantial portions of the Software. | |
| # | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| # THE SOFTWARE. | |
| import email, getpass, imaplib, os, sys | |
| # The following script will download all attachments from a given sender | |
| # that you specify. Little to no error handling, use at your own risk! | |
| # | |
| # IMPORTANT: If you first used Gmail in the UK then you need to select | |
| # a different mailbox (please see below and uncomment the appropriate line). | |
| # | |
| # Adapted from http://stackoverflow.com/questions/10182499/how-do-i-download-only-unread-attachments-from-a-specific-gmail-label | |
| # Directory where to save attachments ('.' = current directory) | |
| detach_dir = '.' | |
| user = raw_input("Gmail username: ") | |
| pwd = getpass.getpass("Password: ") | |
| sender_email = raw_input("Enter the sender's email (to filter by): ") | |
| # Connecting to the gmail imap server | |
| m = imaplib.IMAP4_SSL("imap.gmail.com") | |
| m.login(user,pwd) | |
| # Select the mailbox | |
| m.select("[Gmail]/All Mail") | |
| # If you get an error "command SEARCH illegal in state AUTH, only allowed in states SELECTED" | |
| # then it is likely that the mailbox you have tried to select doesn't exist. | |
| # If you were originally a Google Mail user (i.e. a user in the UK) then you should uncomment | |
| # the line below. | |
| # m.select("[Google Mail]/All Mail") # here you a can choose a mail box like INBOX instead | |
| # Alternatively you can search for emails in the inbox only | |
| # m.select("INBOX") | |
| # Use m.list() to get all the mailboxes | |
| resp, items = m.search(None, 'FROM', '"%s"' % sender_email) | |
| items = items[0].split() | |
| for emailid in items: | |
| resp, data = m.fetch(emailid, "(RFC822)") | |
| email_body = data[0][1] | |
| mail = email.message_from_string(email_body) | |
| if mail.get_content_maintype() != 'multipart': | |
| continue | |
| subject = "" | |
| if mail["subject"] is not None: | |
| subject = mail["subject"] | |
| print "["+mail["From"]+"] :" + subject | |
| for part in mail.walk(): | |
| if part.get_content_maintype() == 'multipart': | |
| continue | |
| if part.get('Content-Disposition') is None: | |
| continue | |
| filename = part.get_filename() | |
| counter = 1 | |
| if not filename: | |
| filename = 'part-%03d%s' % (counter, 'bin') | |
| counter += 1 | |
| att_path = os.path.join(detach_dir, filename) | |
| if not os.path.isfile(att_path) : | |
| fp = open(att_path, 'wb') | |
| fp.write(part.get_payload(decode=True)) | |
| fp.close() |
moirod did you get this figured out? I just ran into the same error and it's because I'm using Python 3, which has a different syntax for the print statement. Just wrap everything after the print statement in parenthesis like print(whatever + "you want to print")
Hai i would like to request u i wanna some code here
How to read and display at sametime gmail attachements in a python window....?
and im using windows OS using python version 2.7.14
I have tried executing this code but it shows the following error:
Traceback (most recent call last):
File "config.py", line 25, in
mail = email.message_from_string(email_body)
File "C:\Users\sappa\AppData\Local\Programs\Python\Python37-32\lib\email_init_.py", line 38, in message_from_string
return Parser(*args, **kws).parsestr(s)
File "C:\Users\sappa\AppData\Local\Programs\Python\Python37-32\lib\email\parser.py", line 68, in parsestr
return self.parse(StringIO(text), headersonly=headersonly)
TypeError: initial_value must be str or None, not bytes
SOLVED IT 💯
mail = email.message_from_string(email_body)
The above line in the code must be replaced with the following line and it works perfectly
mail = email.message_from_bytes(email_body)
in short: "email.message_from_string" must be replaced with "email.message_from_bytes". Because the data is present in bytes not in the string format.
mycode: wokring fine
import imaplib,email,smtplib
import os
detach_dir = '.'
if 'attachments' not in os.listdir(detach_dir):
os.mkdir("attachments")
user='[email protected]'
pwd="delu@2250012"
imap_url='imap.gmail.com'
con= imaplib.IMAP4_SSL('imap.gmail.com')
con.login(user, pwd)
con.select('INBOX')
type, data=con.uid('search', None, '(HEADER Subject "invoice")')
typ, data = con.search(None, '(SUBJECT "invoice")')
type, data = con.search(None, 'ALL')
mail_ids = data[0]
id_list = mail_ids.split()
for msgId in data[0].split():
typ, messageParts = con.fetch(msgId, '(RFC822)')
if typ != 'OK':
print ('Error fetching mail.')
raise
emailBody = messageParts[0][1]
# print(emailBody)
mail = email.message_from_bytes(emailBody)
for part in mail.walk():
if part.get_content_maintype() == 'multipart':
# print(part.as_string())
continue
if part.get('Content-Disposition') is None:
# print (part.as_string())
# print("done")
continue
fileName = part.get_filename()
print('done')
if bool(fileName):
filePath = os.path.join(detach_dir, 'attachments', fileName)
if not os.path.isfile(filePath) :
print (fileName)
fp = open(filePath, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
SOLVED IT 💯
mail = email.message_from_string(email_body)The above line in the code must be replaced with the following line and it works perfectly
mail = email.message_from_bytes(email_body)in short: "email.message_from_string" must be replaced with "email.message_from_bytes". Because the data is present in bytes not in the string format.
Thanks for that @RahulSapparapu !
In addition to that, I had to make the following minor changes to make it python3 compatible
- Use input in place of raw_input
- Use additional single quote at
('"[Gmail]/All Mail"')
- Use parentheses at
print("["+mail["From"]+"] :" + subject)
Finally, added the following to filename as my attachments were of the same name and were getting overwritten:
datestring = mail['date']
datestring2 = utils.parsedate_to_datetime(datestring).strftime("%Y_%m_%d")
filename = datestring2 + '_' + part.get_filename()
Thank you @styrmis for sharing this!
I know this sounds so retarded. I'm not a programmer and I don't understand which things I need to change in the script to run it. Please tell me what I'm doing wrong. Interpreter says "Missing Parenthesis in call to 'print'"