Parse Gmail with Python and mark all older than date as "read"
Asked Answered
A

4

5

Long story short, I created a new gmail account, and linked several other accounts to it (each with 1000s of messages), which I am importing. All imported messages arrive as unread, but I need them to appear as read.

I have a little experience with python, but I've only used mail and imaplib modules for sending mail, not processing accounts.

Is there a way to bulk process all items in an inbox, and simply mark messages older than a specified date as read?

Airminded answered 18/8, 2009 at 20:52 Comment(0)
R
9
typ, data = M.search(None, '(BEFORE 01-Jan-2009)')
for num in data[0].split():
   M.store(num, '+FLAGS', '\\Seen')

This is a slight modification of the code in the imaplib doc page for the store method. I found the search criteria to use from RFC 3501. This should get you started.

Rum answered 18/8, 2009 at 21:25 Comment(2)
For me the date format '(SINCE 01-Jan-2011)' worked ie., DD-MMM-YYYY, thxRiptide
Thanks for the heads up, dhaval. I corrected the example. Worked great for me.Rum
B
2

Based on Philip T.'s answer above and RFC 3501 and RFC 2822, I built some lines of code to mark mails older than 10 days as read. A static list is used for the abbreviated month names. This is not particularly elegant, but Python's %b format string is locale dependent, which could give unpleasant surprises. All IMAP commands are UID based.

import imaplib, datetime

myAccount = imaplib.IMAP4(<imapserver>)
myAccount.login(<imapuser>, <password>)
myAccount.select(<mailbox>)

monthListRfc2822 = ['0', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
beforeDate = datetime.datetime.today() - datetime.timedelta(days = 10)
beforeDateString = ("(BEFORE %s-%s-%s)"
                    % (beforeDate.strftime('%d'),
                       monthListRfc2822[beforeDate.month],
                       beforeDate.strftime('%Y')))
typ, data = myAccount.uid('SEARCH', beforeDateString)
for uid in data[0].split():
    myAccount.uid('STORE', uid, '+FLAGS', '(\Seen)')

By the way: I do not know, why "-" had to be used as a date delimiter in the search string in my case (dovecot IMAP server). To me that seems to contradict RFC 2822. However, dates with simple whitespace as delimiter only returned IMAP errors.

Barahona answered 5/1, 2012 at 9:57 Comment(0)
P
1

Rather than try to parse our HTML why not just use the IMAP interface? Hook it up to a standard mail client and then just sort by date and mark whichever ones you want as read.

Pomona answered 18/8, 2009 at 20:55 Comment(2)
because it's not as fun? To be clear, I'm aiming to use the Imap interface, but I'm trying to learn a new trick on the way. I don't want to install a mail client on my computer, when technically this should be possible without one.Airminded
Ah ok, I didn't realize that fun was a top priority in this project ;)Pomona
F
1

Just go to the Gmail web interface, do an advanced search by date, then select all and mark as read.

Fallible answered 18/8, 2009 at 20:57 Comment(1)
For me, it'll pop up a little message that says "All 20 conversations on this page are selected. Select all conversations that match this search" and you can select all of your messages.Fallible

© 2022 - 2024 — McMap. All rights reserved.