Changeset 218:ae8dacf52b3d

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

Added livetest for IDLE support and reworked how the IDLE callback function is called

Files:
2 modified

Legend:

Unmodified
Added
Removed
  • imapclient/imapclient.py

    r216 r218  
    1010try: 
    1111    import imaplib2 as imaplib 
    12     imaplib2 = True 
     12    using_imaplib2 = True 
    1313except ImportError: 
    14     imaplib2 = False 
     14    using_imaplib2 = False 
    1515    import imaplib 
    1616     
     
    2727 
    2828__all__ = ['IMAPClient', 'DELETED', 'SEEN', 'ANSWERED', 'FLAGGED', 'DRAFT', 
    29     'RECENT'] 
     29    'RECENT', 'using_imaplib2'] 
    3030 
    3131from response_parser import parse_response, parse_fetch_response 
     
    295295        typ, data = self._imap.select(self._encode_folder_name(folder), readonly) 
    296296        self._checkok('select', typ, data) 
    297         if imaplib2: 
     297        if using_imaplib2: 
    298298            untagged_responses = self._response_to_dict(self._imap.untagged_responses) 
    299299        else: 
     
    326326        return out 
    327327 
    328     def idle(self, timeout=None, **kwargs): 
     328    def idle(self, timeout=None, callback=None, **kwargs): 
    329329        """Put server into IDLE mode. 
    330330 
    331         IDLE mode will end when the server notifies of a change, the sever 
     331        IDLE mode will end when the server notifies of a change, the server 
    332332        reaches the timeout, or another IMAP4 command is scheduled. 
    333333         
     
    337337        @param cb_arg: An optional argument that will be passed to the callback function. 
    338338        @return: Server response. (None if callback is specified). 
    339         """ 
    340         if imaplib2: 
    341             if 'callback' in kwargs: 
    342                 callback = kwargs.pop('callback') 
    343                 def _wrapped_callback(resp): 
     339 
     340        #XXX update documentation 
     341        #XXX what about finding out what the IDLE data was? 
     342        """ 
     343        if not using_imaplib2: 
     344            raise self.Error('The imaplib2 module is required to use IDLE') 
     345 
     346        if callback: 
     347            cb_arg_was_given = 'cb_arg' in kwargs 
     348            def _wrapped_cb(resp): 
     349                if resp[0]: 
     350                    success = True 
    344351                    typ, data = resp[0] 
    345                     self._checkok('idle', typ, data) 
    346                     # if there's a cb_arg, pass it along 
     352                    response = (typ, data[0]) 
     353                else: 
     354                    success = False 
     355                    response = resp[2] 
     356                if cb_arg_was_given: 
    347357                    cb_arg = resp[1] 
    348                     if cb_arg: 
    349                         callback(data[0], cb_arg) 
    350                     else: 
    351                         callback(data[0]) 
    352                 self._imap.idle(timeout, callback=_wrapped_callback, **kwargs) 
    353             else: 
    354                 typ, data = self._imap.idle(timeout) 
    355                 self._checkok('idle', typ, data) 
    356                 return data[0] 
    357         else: 
    358             raise self.Error('The imaplib2 module is required to use IDLE') 
     358                    callback(success, response, cb_arg) 
     359                else: 
     360                    callback(success, response) 
     361            self._imap.idle(timeout, callback=_wrapped_cb, cb_arg=kwargs.get('cb_arg')) 
     362        else: 
     363            typ, data = self._imap.idle(timeout) 
     364            self._checkok('idle', typ, data) 
     365            return data[0] 
    359366                 
    360367    def folder_status(self, folder, what=None): 
     
    585592        else: 
    586593            tag = self._imap._command('FETCH', msg_list, parts_list, modifiers_list) 
    587         if imaplib2: 
     594        if using_imaplib2: 
    588595            typ, data = self._imap._command_complete(tag, 'FETCH') 
    589596        else: 
  • livetest.py

    r214 r218  
    99import os 
    1010import sys 
     11import time 
     12import threading 
    1113from datetime import datetime 
    1214from ConfigParser import SafeConfigParser, NoOptionError 
     
    449451                        e = lower_if_str(e) 
    450452                        self.assertEqual(a, e) 
     453         
     454        def test_idle(self): 
     455            if not imapclient.using_imaplib2: 
     456                return self.skipTest("imaplib2 is not installed") 
     457             
     458            idle_event = threading.Event() 
     459            cb_data = {} 
     460            def cb(success, response, cb_arg): 
     461                idle_event.set() 
     462                cb_data['success'] = success 
     463                cb_data['idle_response'] = response 
     464                cb_data['cb_arg'] = cb_arg 
     465 
     466            # Start main connection idling 
     467            self.client.select_folder('INBOX') 
     468            self.client.idle(timeout=20, callback=cb, cb_arg='foo') 
     469 
     470            # Start a new connection and upload a new message 
     471            client2 = create_client_from_config(conf) 
     472            client2.select_folder('INBOX') 
     473            client2.append('INBOX', SIMPLE_MESSAGE) 
     474            client2.logout() 
     475 
     476            idle_event.wait(15)    # Wait for IDLE callback to trigger 
     477 
     478            self.assertTrue(idle_event.is_set()) 
     479            self.assertTrue(cb_data['success']) 
     480            idle_status, idle_text = cb_data['idle_response'] 
     481            self.assertEqual(idle_status, 'OK') 
     482            # Can't be too specific as different servers return different text 
     483            self.assertIn('idle', idle_text.lower())      
     484            self.assertEqual(cb_data['cb_arg'], 'foo') 
     485             
    451486    return LiveTest 
    452487