From 7e1d46ac590be2f3351c367418c2af7e3cacc04a Mon Sep 17 00:00:00 2001 From: Josh de Kock Date: Thu, 5 Dec 2019 22:55:00 +0000 Subject: [PATCH] Add IDLE support to imaplib --- Example: with imaplib.IMAP4_SSL(server) as m: m.login(user, password) m.select() while True: print('+idling') for msg in m.idle(): print(msg) if msg.endswith(b'EXISTS'): m.done() print('You got mail!') Lib/imaplib.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index a4f499383e..a7017b25d1 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -66,6 +66,7 @@ Commands = { 'CREATE': ('AUTH', 'SELECTED'), 'DELETE': ('AUTH', 'SELECTED'), 'DELETEACL': ('AUTH', 'SELECTED'), + 'DONE': ('IDLE'), 'ENABLE': ('AUTH', ), 'EXAMINE': ('AUTH', 'SELECTED'), 'EXPUNGE': ('SELECTED',), @@ -74,6 +75,7 @@ Commands = { 'GETANNOTATION':('AUTH', 'SELECTED'), 'GETQUOTA': ('AUTH', 'SELECTED'), 'GETQUOTAROOT': ('AUTH', 'SELECTED'), + 'IDLE': ('SELECTED'), 'MYRIGHTS': ('AUTH', 'SELECTED'), 'LIST': ('AUTH', 'SELECTED'), 'LOGIN': ('NONAUTH',), @@ -499,6 +501,18 @@ class IMAP4: """ return self._simple_command('DELETEACL', mailbox, who) + def done(self): + """Exit the IDLE state. + """ + if self.state == 'IDLE': + self._command('DONE') + # XXX: need to check for 'A002 OK IDLE terminated' somehow + self.state = 'SELECTED' + return None + else: + self.error('DONE outside of IDLE') + return None + def enable(self, capability): """Send an RFC5161 enable string to the server. @@ -578,6 +592,22 @@ class IMAP4: typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') return typ, [quotaroot, quota] + def idle(self): + """Enter or continue an IDLE state + + """ + if 'IDLE' not in self.capabilities: + raise IMAP4.error("Server does not support IDLE") + + self._command('IDLE') + if self._get_response() is None and self.continuation_response == b'idling': + self.state = 'IDLE' + while self.state == 'IDLE': + # XXX: better than this? + yield self._get_line() + else: + raise self.error("Failed to IDLE") + def list(self, directory='""', pattern='*'): """List mailbox names in directory matching pattern. -- 2.24.1