Show
Ignore:
Timestamp:
08/11/11 20:32:59 (7 months ago)
Author:
Menno Smits <menno@…>
Branch:
default
Message:

NOOP support (#74)

Untagged response handling shared with IDLE.

Location:
imapclient
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • imapclient/imapclient.py

    r267 r268  
    316316            out[key] = value 
    317317        return out 
     318 
     319    def noop(self): 
     320        """Execute the NOOP command. 
     321 
     322        This command returns immediately, returning any server side 
     323        status updates. It can also be used to reset any auto-logout 
     324        timers. 
     325 
     326        The return value is the server command response message 
     327        followed by a list of status responses. For example:: 
     328 
     329            ('NOOP completed.', 
     330             [(4, 'EXISTS'), 
     331              (3, 'FETCH', ('FLAGS', ('bar', 'sne'))), 
     332              (6, 'FETCH', ('FLAGS', ('sne',)))]) 
     333 
     334        """ 
     335        tag = self._imap._command('NOOP') 
     336        return self._consume_until_tagged_response(tag, 'NOOP') 
    318337 
    319338    def idle(self): 
     
    373392                        break 
    374393                    else: 
    375                         resps.append(_parse_idle_response(line)) 
     394                        resps.append(_parse_untagged_response(line)) 
    376395            return resps 
    377396        finally: 
     
    393412        """ 
    394413        self._imap.send('DONE\r\n') 
    395         # Slurp up any remaining IDLE responses until the IDLE is done 
    396         tag = self._idle_tag 
    397         tagged_commands = self._imap.tagged_commands 
    398         resps = [] 
    399         while True: 
    400             line = self._imap._get_response() 
    401             if tagged_commands[tag]: 
    402                 break 
    403             resps.append(_parse_idle_response(line)) 
    404         self._idle_tag = None 
    405         typ, data = tagged_commands.pop(tag) 
    406         self._checkok('idle', typ, data) 
    407         return data[0], resps 
     414        return self._consume_until_tagged_response(self._idle_tag, 'IDLE') 
    408415 
    409416    def folder_status(self, folder, what=None): 
     
    753760        if typ != expected: 
    754761            raise self.Error('%s failed: %r' % (command, data[0])) 
     762 
     763    def _consume_until_tagged_response(self, tag, command): 
     764        tagged_commands = self._imap.tagged_commands 
     765        resps = [] 
     766        while True: 
     767            line = self._imap._get_response() 
     768            if tagged_commands[tag]: 
     769                break 
     770            resps.append(_parse_untagged_response(line)) 
     771        typ, data = tagged_commands.pop(tag) 
     772        self._checkok(command, typ, data) 
     773        return data[0], resps 
    755774 
    756775    def _checkok(self, command, typ, data): 
     
    859878 
    860879 
    861 def _parse_idle_response(text): 
     880def _parse_untagged_response(text): 
    862881    assert text.startswith('* ') 
    863882    text = text[2:] 
  • imapclient/test/test_IMAPClient.py

    r265 r268  
    169169 
    170170 
    171 class TestIdle(IMAPClientTest): 
     171class TestIdleAndNoop(IMAPClientTest): 
    172172 
    173173    def test_idle(self): 
     
    242242    def test_idle_done(self): 
    243243        self.client._idle_tag = sentinel.tag 
    244         self.client._imap.tagged_commands = {sentinel.tag: None} 
     244 
     245        mockSend = Mock() 
     246        self.client._imap.send = mockSend 
     247        mockConsume = Mock(return_value=sentinel.out) 
     248        self.client._consume_until_tagged_response = mockConsume 
     249 
     250        result = self.client.idle_done() 
     251 
     252        mockSend.assert_called_with('DONE\r\n') 
     253        mockConsume.assert_called_with(sentinel.tag, 'IDLE') 
     254        self.assertEquals(result, sentinel.out) 
     255 
     256    def test_noop(self): 
     257        mockCommand = Mock(return_value=sentinel.tag) 
     258        self.client._imap._command = mockCommand 
     259        mockConsume = Mock(return_value=sentinel.out) 
     260        self.client._consume_until_tagged_response = mockConsume 
     261 
     262        result = self.client.noop() 
     263 
     264        mockCommand.assert_called_with('NOOP') 
     265        mockConsume.assert_called_with(sentinel.tag, 'NOOP') 
     266        self.assertEquals(result, sentinel.out) 
     267 
     268    def test_consume_until_tagged_response(self): 
     269        client = self.client 
     270        client._imap.tagged_commands = {sentinel.tag: None} 
    245271 
    246272        counter = itertools.count() 
     
    249275            if count == 0: 
    250276                return '* 99 EXISTS' 
    251             self.client._imap.tagged_commands[sentinel.tag] = ('OK', ['Idle done']) 
    252         self.client._imap._get_response = fake_get_response 
     277            client._imap.tagged_commands[sentinel.tag] = ('OK', ['Idle done']) 
     278        client._imap._get_response = fake_get_response 
    253279             
    254         text, responses = self.client.idle_done() 
    255  
    256         self.assertEqual(self.client._imap.tagged_commands, {}) 
     280        text, responses = client._consume_until_tagged_response(sentinel.tag, 
     281                                                                'IDLE') 
     282        self.assertEqual(client._imap.tagged_commands, {}) 
    257283        self.assertEqual(text, 'Idle done') 
    258284        self.assertListEqual([(99, 'EXISTS')], responses) 
    259285 
    260286 
     287                          
    261288class TestDebugLogging(IMAPClientTest): 
    262289