-
-
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'"