imaplib STORE failed - Mailbox has read-only access. Cannot Delete Yahoo Email - python

trying to delete emails in my yahoo account using imaplib. i'm new to python, figured out most of the code but unable to find anything that works relating to this error.
imap = imaplib.IMAP4_SSL(imap_server)
imap.login(email_address, password)
imap.select("Learn", readonly=False)
con = imaplib.IMAP4_SSL('imap.mail.yahoo.com',993)
con.login(email_address, password)
con.select('Learn',readonly=False)
imap.select('"Learn"', "(UNSEEN)")
for i in '1':
typ, msg_data = imap.fetch('1', '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
for header in [ 'from' ]:
print('%-8s: %s' % (header.upper(), msg[header]))
imap.store(i, "+FLAGS", "\\Deleted")
#tried commented codes below and same error
#imap.expunge()
#result, data = imap.uid('STORE', str(i) , '+FLAGS', '(\\Deleted)')
#imap.uid('STORE', i, '+X-GM-LABELS', '\\Trash')
con.close()
con.logout()
i get the error below
STORE command error: BAD [b'[CANNOT] STORE failed - Mailbox has read-only access']
any help would be greatly appreciated

imap.select('"Learn"', "(UNSEEN)")
Select does not take a search criterion. The second parameter is “readonly”, so this is the same as:
imap.select('"Learn"', readonly="(UNSEEN)")
Which as a non-empty string is the same as:
imap.select('"Learn"', readonly=True)
Which is why you can’t make any changes to that mailbox. Delete the second parameter:
imap.select('"Learn"')
You appear to be wanting to do a search for unseen messages. Use search for this.

Related

python IMAP content of email contains a string

I am able to log in a gmail account with python IMAP
imap = imaplib.IMAP4_SSL('imap.gmail.com')
imap.login(myDict["emailUsername"], myDict["emailPassword"])
imap.select(mailbox='inbox', readonly=False)
resp, items = imap.search(None, 'All')
email_ids = items[0].split()
latest_email_id = email_ids[-1]
resp, data = imap.fetch(latest_email_id, "(UID)")
print ("resp= ", resp, " data=", data)
#msg_uid = parse_uid(data[0])
match = pattern_uid.match(data[0].decode("utf-8"))
#print ("match= ", match)
msg_uid = match.group('uid')
I need to make sure that the UID for the last email I have contains a certain string (XYZ). I am NOT looking for header subject but the content of email. How can I do that ?
There's a couple ways you could go:
Fetch the message and walk through the text body parts looking for your string -- example at Finding links in an emails body with Python
Get the server to do the search by supplying 'latest_email_id' and your search criteria back to the server in a UID SEARCH command. For Gmail, you can even use the X-GM-RAW attribute to use the same syntax support by the GMail web interface. See https://developers.google.com/gmail/imap/imap-extensions for details of that.

Getting complaint email from SES abuse report email

I am using python Imaplib to scrape zoho inbox for getting bounced emails & failed emails which are being sent from SES.
Now while trying to get the email from abuse report notification, the email body gives no result (NONE)
The Code is:
def ss():
yesterday = (datetime.today() - timedelta(days=30)).strftime('%d-%b-%Y')
M = imaplib.IMAP4_SSL('imap.zoho.com')
M.login('email', password)
M.select()
line = '(FROM "complaints#us-west-2.email-abuse.amazonses.com" SINCE {0})'.format(yesterday)
typ, data = M.uid('search', line)
# print(typ,data)
for i in reversed(data[0].split()):
print(i)
result, data = M.fetch(i, "(RFC822)")
print(data)
Normally M.fetch(i, "(RFC822)") returns Body of the email.
Here the data is None. I want to know how to get the right content so that i could use regex to get relevant mail id
Got the solution, It was a bad mistake.
Instead of using
result, data = M.fetch(i, "(RFC822)")
I had to use :
result, data = M.uid('fetch', i, '(RFC822)')
As previously I had searched through UID instead fo the volatile id. Then later I was trying to get RFC822 or body of mail by volatile id.
It was perhaps giving none because the mail might have been deleted or something.

Python IMAP select multiple folders

I'm trying to get the informations from all the folders but it seems that the code gives me the following error:
command SEARCH illegal in state AUTH, only allowed in states SELECTED
I've googled it but no results for me.
This is the code:
M = imaplib.IMAP4_SSL('',993)
M.login(user,password)
folders = M.list()
for folder in folders[1]:
for allfolders in re.findall('"\/"(.*)',folder):
finalfolders = allfolders.replace(" ",'')
M.select(finalfolders, readonly=True)
print finalfolders
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
email_message = email.message_from_string(data[0][1])
su = email_message['From']
allz = re.findall("<(.*)>",su)
for x in allz:
print x
results.write(x+'\n')
results.flush()
#print su
M.close()
M.logout()
Basically I'm trying to fetch "From", from all the folders founded into my email account.
You can only have one folder selected at any given time using one IMAP connection. This means that your code should EXAMINE or SELECT a mailbox at first, then FETCH whatever you need to download, then do not call CLOSE because it removes messages marked for deletion, and upon entering the next loop iteration, call EXAMINE or SELECT once again, and...

How to delete most recently mail sent in python?

Using python and imaplib, how can I delete the most recently sent mail?
I have this:
mail = imaplib.IMAP4_SSL('imap-mail.outlook.com')
mail.login('MYEMAIL#hotmail.com', 'MYPASS')
mail.select('Sent')
mail.search(None, "ALL") # Returns ('OK', ['1 2 ... N'])
# doubt
Thanks in advance!
You'll need to use the select method to open the appropriate folder with read and write permissions. If you do not want to mark your messages as seen, you need to use the examine method.
The sort command is available, but it is not guaranteed to be supported by the IMAP server. For example, Gmail does not support the SORT command.
To try the sort command, you would replace M.search(None, 'ALL') with M.sort(search_critera, 'UTF-8', 'ALL')
Then search_criteria would be a string like:
search_criteria = 'DATE' #Ascending, most recent email last
search_criteria = 'REVERSE DATE' #Descending, most recent email first
search_criteria = '[REVERSE] sort-key' #format for sorting
According to RFC5256 these are valid sort-key's:
"ARRIVAL" / "CC" / "DATE" / "FROM" / "SIZE" / "SUBJECT" / "TO"
I found a solution that worked for me. After get sent mailbox access I was needing to found a message with fetch() function and then delete the email message with expunge() function. From imaplib documentation:
IMAP4.expunge()
Permanently remove deleted items from selected
mailbox. Generates an EXPUNGE response for each deleted message.
Returned data contains a list of EXPUNGE message numbers in order
received.
My code:
mail = imaplib.IMAP4_SSL('imap-mail.outlook.com')
mail.login('MYEMAIL#hotmail.com', 'MYPASS')
mail.select('Sent')
typ, data = mail.search(None, 'ALL')
control = 0
tam = len(data[0].split())
while control < tam:
typ, data = mail.fetch(tam - control, '(RFC822)')
if str(data).find(msg['Subject']) and str(data).find(msg['To']) != -1:
print "Msg found! ", control + 1, "most recently message!"
mail.store(str(tam - control), '+FLAGS', '\\Deleted')
mail.expunge()
break
control = control + 1
mail.close()
mail.logout()

imaplib.error: command FETCH illegal in state AUTH

I'm trying to download attachments from Gmail, using a combination of pieces of code I found online, and some editing from myself. However, the following code:
import email, getpass, imaplib, os, random, time
import oauth2 as oauth
import oauth2.clients.imap as imaplib
MY_EMAIL = 'example#gmail.com'
MY_TOKEN = "token"
MY_SECRET = "secret"
consumer = oauth.Consumer('anonymous', 'anonymous')
token = oauth.Token(MY_TOKEN, MY_SECRET)
url = "https://mail.google.com/mail/b/"+MY_EMAIL+"/imap/"
m = imaplib.IMAP4_SSL('imap.gmail.com')
m.authenticate(url, consumer, token)
m.select('INBOX')
items = m.select("UNSEEN");
items = items[0].split()
for emailid in items:
data = m.fetch(emailid, "(RFC822)")
returns this error:
imaplib.error: command FETCH illegal
in state AUTH
Why would Fetch be illegal while I'm authorized?
You're lacking error checking on your calls to select. Typically, this is how I'll structure the first parts of a connection to a mailbox:
# self.conn is an instance of IMAP4 connected to my server.
status, msgs = self.conn.select('INBOX')
if status != 'OK':
return # could be break, or continue, depending on surrounding code.
msgs = int(msgs[0])
Essentially, the trouble you're encountering is that you've selected a mailbox that doesn't exist, your status message is probably not "OK" as it should be, and the value you're iterating over isn't valid. Remember, select expects a mailbox name. It does not search based on a flag (which may be what you're attempting with "UNSEEN"). When you select a non-existent mail box you actually get this as a response:
('NO', ['The requested item could not be found.'])
In which case, for email id in items is not operating properly. Not what you're after in any way, unfortunately. What you'd get on a valid mailbox would be like this:
('OK', ['337'])
Hope that helps.
To address the question in comments, if you want to actually retrieve the unseen messages in the mailbox you'd use this:
status, msgs = self.conn.select('INBOX')
# returns ('OK', ['336'])
status, ids = self.conn.search(None, 'UNSEEN')
# returns ('OK', ['324 325 326 336'])
if status == 'OK':
ids = map(int, ids[0].split())
The response is going to be similar to the response from select, but instead of a single integer for the number of messages you'll get a list of ids.
Why would Fetch be illegal while I'm authorized?
IMAP has a state concept.
You can only fetch messages if you have selected a folder.
Here is a nice picture which shows this:
Image source: http://www.tcpipguide.com/free/t_IMAP4GeneralOperationClientServerCommunicationandS-2.htm

Categories