Changeset 221:c5912b9d2cf9

Show
Ignore:
Timestamp:
17/04/11 11:33:16 (13 months ago)
Author:
Menno Smits <menno@…>
Branch:
default
Message:

Updated documentation and examples wrt IDLE support

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • NEWS

    r217 r221  
    1111installed. Thanks to Johannes Heckel for contributing the patch to 
    1212this. 
     13 
     14IDLE Support (#50) [NEW] 
     15------------------------ 
     16The IDLE extension is now supported through the new idle(), 
     17idle_check() and idle_done() methods. See the example in 
     18imapclient/examples/idle_example.py. 
    1319 
    1420Small Bug Fixes 
  • imapclient/examples/idle_example.py

    r208 r221  
     1# This example is a lot more interesting if you have an active client 
     2# connected to the same IMAP account! 
     3 
    14from imapclient import IMAPClient 
    2 import time 
    35 
    46HOST = 'imap.host.com' 
     
    810 
    911server = IMAPClient(HOST, use_uid=True, ssl=ssl) 
     12server.login(USERNAME, PASSWORD) 
     13server.select_folder('INBOX') 
    1014 
    11 server.login(USERNAME, PASSWORD) 
     15# Start IDLE mode 
     16server.idle()      
    1217 
    13 select_info = server.select_folder('INBOX') 
    14 print select_info 
    15 print 
     18# Wait for up to 30 seconds for an IDLE response 
     19responses = server.idle_check(timeout=30) 
     20print responses 
    1621 
    17 idling = True 
    18  
    19 def callback(resp, arg): 
    20     global idling 
    21      
    22     print "Something happened, or timeout was reached" 
    23     print 
    24     print "Callback response:" 
    25     print resp 
    26     print 
    27     print "The callback function received arg: ", arg 
    28     print 
    29     idling = False 
    30  
    31 server.idle(timeout=5, callback=callback, cb_arg="Hello future self!") 
    32 print "Began idling" 
    33  
    34 while idling: 
    35     print "..still idling.." 
    36     time.sleep(1) 
     22# Come out of IDLE mode 
     23text, responses = server.idle_done() 
     24print 'IDLE done. Server said %r' % text 
     25print 'Final responses: ', responses 
    3726     
    3827print server.logout() 
  • imapclient/imapclient.py

    r219 r221  
    316316        """Put server into IDLE mode. 
    317317 
    318         IDLE mode will end when the server notifies of a change, the server 
    319         reaches the timeout, or another IMAP4 command is scheduled. 
    320          
    321         @param timeout: timeout for the IDLE command in seconds (default: 29 mins) 
    322         @param callback: Function to be called when IDLE mode ends. If a callback 
    323             is supplied the idle function will be asynchronous, returning immediately. 
    324         @param cb_arg: An optional argument that will be passed to the callback function. 
    325         @return: Server response. (None if callback is specified). 
    326  
    327         #XXX update documentation 
    328         #XXX what about finding out what the IDLE data was? 
     318        In this mode the server will return unsolicited responses 
     319        about changes to the selected mailbox. 
     320 
     321        This method returns immediately. Use idle_check() to check for 
     322        IDLE responses and idle_done() to stop IDLE mode. 
     323 
     324        Note: Any other commmands issued while the server is in IDLE 
     325        mode will fail. 
     326 
     327        See RFC 2177 for more information about the IDLE extension. 
     328        http://tools.ietf.org/html/rfc2177 
    329329        """ 
    330330        self._idle_tag = self._imap._command('IDLE') 
     
    334334 
    335335    def idle_check(self, timeout=None): 
    336         """XXX 
     336        """Check for any IDLE responses sent by the server. 
     337 
     338        This method should only be called if the server is in IDLE 
     339        mode (see idle()). 
     340 
     341        By default, this method will block until an IDLE response is 
     342        received. If timeout is provided, the call will block for at 
     343        most this number of seconds (approximately) while waiting for 
     344        an IDLE response. 
     345 
     346        The return value is a list of received IDLE responses. These 
     347        will be parsed with values converted to appropriate types. For 
     348        example: 
     349 
     350        [(1, 'EXISTS'), 
     351         ('OK', 'Still here'),  
     352         (1, 'FETCH', ('FLAGS', ('\NotJunk',))),  
     353         (0, 'EXPUNGE')] 
     354 
     355        An attempt is made to group responses that were sent together 
     356        by the server by waiting for a little longer after the first 
     357        IDLE response is received. 
    337358        """ 
    338359        timeouts = 0 
    339360        resps = [] 
    340361        start_t = time.time() 
    341         def done(): 
    342             if timeout is None: 
    343                 if resps and timeouts > 1: 
    344                     return True 
    345             else: 
    346                 if time.time() - start_t >= timeout: 
    347                     return True 
    348             return False 
     362 
     363        def blocking_done(): 
     364            # Wait for one timed out read to try group IDLE responses 
     365            # that were sent together 
     366            return resps and timeouts > 1 
     367 
     368        if timeout is None: 
     369            done = blocking_done 
     370        else: 
     371            def done(): 
     372                return blocking_done() or (time.time() - start_t >= timeout) 
    349373         
    350374        # make the socket non-blocking so the timeout can be 
     
    364388 
    365389    def idle_done(self): 
    366         """XXX 
     390        """Take the server out of IDLE mode. 
     391 
     392        This method should only be called if the server is in IDLE mode. 
     393 
     394        The return value is (command_text, idle_responses) where 
     395        command_text is the text sent by the server when the IDLE 
     396        command finished (eg. 'Idle terminated') and idle_responses is 
     397        a list of parsed idle responses received since the last call 
     398        to idle_check() (if any). These are returned in parsed form as 
     399        per idle_check(). 
    367400        """ 
    368401        self._imap.send('DONE\r\n') 
    369         # Slurp up any remaining IDLE data until the IDLE is done 
     402        # Slurp up any remaining IDLE responses until the IDLE is done 
    370403        tag = self._idle_tag 
    371404        tagged_commands = self._imap.tagged_commands