Python imaplib search Variables - python

I'm trying to do a search using imaplib with variables. When I hard code the information the search works great.
result, data = mail.search(None,'(SENTSINCE "15-Oct-2015" SENTBEFORE "19-Oct-2015")'.format(date=date))
I've tried lots of ways to setup variables and from other posts it seems the best way is setup the entire search parameters as the variable and call it that way.
search_string = '(SENTSINCE \"' + start_date_format + '\" SENTBEFORE \"' + format_endday + '\" )\'.format(date=date)'
result, data = mail.search(None, search_string)
The print of the variable setup looks accurate:
(SENTSINCE "12-Oct-2015" SENTBEFORE "19-Oct-2015" )'.format(date=date)
I'm getting the following error:
Traceback (most recent call last):
File "infringment-report.py", line 74, in <module>
result, data = mail.search(None, search_string)
File "/usr/lib/python2.7/imaplib.py", line 639, in search
typ, dat = self._simple_command(name, *criteria)
File "/usr/lib/python2.7/imaplib.py", line 1087, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "/usr/lib/python2.7/imaplib.py", line 917, in _command_complete
raise self.error('%s command error: %s %s' % (name, typ, data))
imaplib.error: SEARCH command error: BAD ['The specified message set is invalid.']
I've been banging my head on this for a while, an help is appreciated.

I am also a newbie in python and imaplib but i guess this will work just fine.
For retrieving mails having name stored in a variable say fromname
then
let criteria = ['From', fromname]
typ, [msg_id] = mail.search(None, *criteria).

Related

"EOF error" when fetching emails in bulk using imap_tools python

I've build a very simple script that fetches emails from an Outlook inbox. It looks like this:
from imap_tools import MailBox
inbox = MailBox("outlook.office365.com").login("email", "password")
for email in inbox.fetch(): # bulk=True
print(email)
It's working when I use it like this. Though, when passing the arg bulk=True on the fetch() function it will raise the following error:
Traceback (most recent call last):
File "/Users/julius/Library/Application Support/JetBrains/IntelliJIdea2022.3/scratches/scratch_1.py", line 5, in <module>
for email in inbox.fetch(bulk=True):
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/imap_tools/mailbox.py", line 171, in fetch
for fetch_item in (self._fetch_in_bulk if bulk else self._fetch_by_one)(nums, message_parts, reverse): # noqa
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/imap_tools/mailbox.py", line 144, in _fetch_in_bulk
fetch_result = self.client.fetch(','.join(message_nums), message_parts)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/imaplib.py", line 548, in fetch
typ, dat = self._simple_command(name, message_set, message_parts)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/imaplib.py", line 1230, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/imaplib.py", line 1008, in _command
raise self.abort('socket error: %s' % val)
imaplib.IMAP4.abort: socket error: EOF occurred in violation of protocol (_ssl.c:2396)
Has anyone got a clue on how to fix this?
Right answer: combine bulk and limit args.
Text from docs:
For actions with a large number of messages imap command may be too large and will cause exception at server side, use 'limit' argument for fetch in this case.

Trying to mass delete emails using Python 3.7.2 & IMAPClient - imaplib.IMAP4.error: UID command error: BAD [b'Command line too large']

I'm very new to programming so I'm looking for some help here. I have an email folder that has over 200k emails. I am trying to delete them all because they're slowing me down. I wrote a script in Python 3.7.2 using IMAPClient to try and delete them en masse but I keep getting an error.
I have tried to delete all emails in the folder, and I have tried to delete a single days worth. An average single day has about 2k emails. Using both 'ALL' and 'ON DD-MMM-YYYY"
import imapclient
imapObj = imapclient.IMAPClient('imap.server.com', ssl=True)
imapObj.login('email', 'password')
import pprint
pprint.pprint(imapObj.list_folders())
[((b'\\NoInferiors',), b'/', 'INBOX'),
((b'\\HasNoChildren',), b'/', 'Folder I want to delete'),
--all folders--
imapObj.select_folder('Folder I want to delete', readonly=False)
{b'PERMANENTFLAGS': (b'\\Answered', b'\\Flagged', b'\\Draft',
b'\\Deleted', b'\\Seen', b'$Forwarded', b'$NotJunk', b'NotJunk',
b'$MailFlagBit1', b'$MailFlagBit0', b'$MailFlagBit2', b'\\*'),
b'FLAGS': (b'\\Answered', b'\\Flagged', b'\\Draft', b'\\Deleted',
b'\\Seen', b'$Forwarded', b'$NotJunk', b'NotJunk', b'$MailFlagBit1',
b'$MailFlagBit0', b'$MailFlagBit2'), b'EXISTS': 3792507, b'RECENT':
0, b'UNSEEN': [b'3792504'], b'UIDVALIDITY': 1398179813, b'UIDNEXT':
7577201, b'READ-WRITE': True}
UIDs = imapObj.search('ALL')
imapObj.delete_messages(UIDs)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
imapObj.delete_messages(UIDs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-
packages/imapclient/imapclient.py", line 1171, in delete_messages
return self.add_flags(messages, DELETED, silent=silent)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-
packages/imapclient/imapclient.py", line 1081, in add_flags
return self._store(b'+FLAGS', messages, flags, b'FLAGS',
silent=silent)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-
packages/imapclient/imapclient.py", line 1567, in _store
uid=True)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-
packages/imapclient/imapclient.py", line 1535, in
_command_and_check
typ, data = self._imap.uid(command, *args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/imaplib
.py", line 879, in uid
typ, dat = self._simple_command(name, command, *args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/imaplib
.py", line 1196, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/imaplib
.py", line 1027, in _command_complete
raise self.error('%s command error: %s %s' % (name, typ, data))
imaplib.IMAP4.error: UID command error: BAD [b'Command line too large']
I expect the emails to be delete but the command just errors out to the above.
The list of UIds is to long to make one request , we need to split every deletion.
UIDs = imapObj.search('ALL')
for UID in UIDs
imapObj.delete_messages([UID])
print( 'Deleted--->'+str(UID))

How can I search a mail in my imap folder starting from an EML file with python?

I'm trying to select a specific mail in my imap folder without having a clear identifier. The only thing I have is a plaintext copy of the mail saved as an eml file.
I tried to load the mail from the file using the email module but I keep getting errors whenever I run the search function of the imaplib module starting from the data contained in the mail.
In this instance I'm assuming that the mail comes from the current mailbox.
This is the code I'm using now
import imaplib, email
m = imaplib.IMAP4_SSL(IMAP_SERVER)
m.login(IMAP_USER, IMAP_PWD)
m.select()
mail_file = open('./file.eml')
raw_mail = mail_file.read()
mail = email.message_from_string(raw_mail)
resp, items = m.search(None, '(FROM "' + mail["FROM"] +'")')
But I'm getting the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\user\AppData\Local\conda\conda\envs\py353\lib\imaplib.py", line 707, in search
typ, dat = self._simple_command(name, *criteria)
File "C:\Users\user\AppData\Local\conda\conda\envs\py353\lib\imaplib.py", line 1180, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "C:\Users\user\AppData\Local\conda\conda\envs\py353\lib\imaplib.py", line 1011, in _command_complete
raise self.error('%s command error: %s %s' % (name, typ, data))
imaplib.error: SEARCH command error: BAD [b'Error in IMAP command SEARCH: Unknown argument DATE (0.000 + 0.000 secs).']`
How should I do this and what filters can I use to have a reasonable chance of getting exactly the mail I want in the results?
Edit: as requested my mail['FROM'] returns 'test sender\n\t<sender#domain.com>'
I made a test hardcoding a similar format and removing the special characters but of course I'm returned a different mail with matched sender.
Also I'm trying to get to the correct mail without altering any data in the most automatic way possible.

How to sort email by time in imaplib using python

I would like to sort the emails by arrival time.
Here is the code:
data = get_credential('info.txt')
imap_conn = create_connection(data, 'outlook.office365.com')
imap_conn.select('INBOX', readonly=False)
result, messages = imap_conn.sort('ARRIVAL', 'UTF-8', 'FROM peter#gmail.com SINCE "'+(datetime.date.today()-datetime.timedelta(4)).strftime('%d-%b-%Y')+'"
It returns the following error:
File "C:\Program Files\Python37\lib\imaplib.py", line 794, in sort
typ, dat = self._simple_command(name, sort_criteria, charset, *search_criteria)
File "C:\Program Files\Python37\lib\imaplib.py", line 1196, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "C:\Program Files\Python37\lib\imaplib.py", line 1027, in _command_complete
raise self.error('%s command error: %s %s' % (name, typ, data))
imaplib.IMAP4.error: SORT command error: BAD [b'Command Error. 12']
How to solve the problem?
Is the input charset UTF-8 correct? How to get it from messages?
Office365 doesn't support the SORT extension.
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CLIENTACCESSRULES CLIENTNETWORKPRESENCELOCATION BACKENDAUTHENTICATE CHILDREN IDLE NAMESPACE LITERAL+
You should check CAPABILITY before using any extensions.

imaplib.error: command SEARCH illegal in state AUTH, only allowed in states SELECTED

def connect_imap():
m = imaplib.IMAP4_SSL("imap.gmail.com", 993)
print("{0} Connecting to mailbox via IMAP...".format(datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")))
details = login_credentials()
m.login(details[0], details[1])
return m
m = connect_imap()
typ, data = m.search(None, 'ALL')
m.close()
m.logout()
The Output of the above code is:
2016-08-24 10:55:34 Connecting to mailbox via IMAP...
Traceback (most recent call last):
File "/home/zoikmail/Desktop/test.py", line 25, in <module>
typ, data = m.search(None, 'ALL')
File "/usr/lib/python2.7/imaplib.py", line 640, in search
typ, dat = self._simple_command(name, *criteria)
File "/usr/lib/python2.7/imaplib.py", line 1088, in _simple_command
return self._command_complete(name, self._command(name, *args))
File "/usr/lib/python2.7/imaplib.py", line 838, in _command
', '.join(Commands[name])))
imaplib.error: command SEARCH illegal in state AUTH, only allowed in states SELECTED
[Finished in 1.2s with exit code 1]
[shell_cmd: python -u "/home/zoikmail/Desktop/test.py"]
[dir: /home/zoikmail/Desktop]
[path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games]
What's wrong in the above code?
You need to select a mailbox after connecting successfully to the IMAP-Server.
Use
m.select()
after connecting and before search.

Categories