How do I fetch emails leaving them read/unread in Python?

Frew Schmidt

I have a little tool that exists because my email client does not support IMAP Push extensions as implemented by gmail. Typical usage is something like this:

live-email -n 10

Which shows the id and subject of the first 10.

So some example output might be:

1242: Hello!
1241: Your email
1240: Re: 
...

The code (simplified for this question) is the following:

#!/usr/bin/env python3

from imaplib import IMAP4_SSL
from netrc import netrc
from email import message_from_bytes
from argparse import ArgumentParser

parser = ArgumentParser(description='Check email')
parser.add_argument('-n', '--count', dest='count', action='store',
                   default=1, type=int,
                   help='How many messages to show')

args = parser.parse_args()

conn = IMAP4_SSL('imap.gmail.com')
auth = netrc().hosts['imap.gmail.com']

conn.login(auth[0], auth[2])
conn.select()

typ, data = conn.search(None, 'ALL')
i = 0
for num in reversed(data[0].split()):
    i += 1
    typ, data = conn.fetch(num, '(RFC822)')
    email = message_from_bytes(data[0][1])
    print("%i: %s" % (int(num), email.get('subject')))
    if i == args.count:
        break

conn.close()
conn.logout()

The above works. The problem is that the act of fetching each email marks it as read. I'd like to leave the state of the email alone. I suspect I'd know how to do this if I knew more about IMAP but I alas do not know that protocol. Any ideas?

Frew Schmidt

Unsurprisingly, reading over RFC 2060 gave me the answer. The solution is to use (BODY.PEEK[]) instead of (RFC822). So the complete answer is:

#!/usr/bin/env python3

from imaplib import IMAP4_SSL
from netrc import netrc
from email import message_from_bytes
from argparse import ArgumentParser

parser = ArgumentParser(description='Check email')
parser.add_argument('-n', '--count', dest='count', action='store',
                   default=1, type=int,
                   help='How many messages to show')

args = parser.parse_args()

conn = IMAP4_SSL('imap.gmail.com')
auth = netrc().hosts['imap.gmail.com']

conn.login(auth[0], auth[2])
conn.select()

typ, data = conn.search(None, 'ALL')
i = 0
for num in reversed(data[0].split()):
    i += 1
    typ, data = conn.fetch(num, '(BODY.PEEK[])')
    email = message_from_bytes(data[0][1])
    print("%i: %s" % (int(num), email.get('subject')))
    if i == args.count:
        break

conn.close()
conn.logout()

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How do I fetch the correct image id from specific row and send the individual emails?

How do I extract specific emails from list in python?

How to forward emails leaving the original intact

I've get a resultset by python BeautifulSoup, but I don't know how to fetch the NavigableString inside them

How do i fetch the list of date folders in ADLS and pass them to delete activity?

How do I target each image seperately, and fetch API data from them, instead of collect it all at once

How can I automatically retrieve texts of emails and further scrape them?

How do I preview emails in Rails?

How do I set Cron to send emails?

Selenium (python): how do I fetch only the first element with href

How do I locate files with glob lib in Python and print them

Trying to fetch emails via python

How do I quit top without leaving the output on the terminal?

OJET - How do I alert a user before leaving my page?

How do I animate a rectangle in JavaScript/Canvas without leaving a trail?

How do I stop user from leaving quantity empty?

How do I send HTML Formatted emails, through the gmail-api for python

Using useEffect on several fetch functions causes them to run before a button click, how do I use useCallback instead?

how to fetch my syllables so I can console log them

how do i use expand on entrys while i can position them python 3 tkinter

how do emails with + in them works e.g "[email protected]"

How do I use the result of a useEffect fetch in a subsequent fetch?

How do I send emails through PHP to GMail?

How do I forward emails in thunderbird in a format other than .eml?

How do I configure Thunderbird to send plain text emails by default?

How do I purge a linux mail box with huge number of emails?

How do I copy a large number of emails to an IMAP folder in Thunderbird?

How do I get rid of the empty rows with no emails?

How do I get django-allauth to send html emails