Changeset 268:e61ddf6f2d41
- 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.
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r267
|
r268
|
|
| 316 | 316 | out[key] = value |
| 317 | 317 | 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') |
| 318 | 337 | |
| 319 | 338 | def idle(self): |
| … |
… |
|
| 373 | 392 | break |
| 374 | 393 | else: |
| 375 | | resps.append(_parse_idle_response(line)) |
| | 394 | resps.append(_parse_untagged_response(line)) |
| 376 | 395 | return resps |
| 377 | 396 | finally: |
| … |
… |
|
| 393 | 412 | """ |
| 394 | 413 | 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') |
| 408 | 415 | |
| 409 | 416 | def folder_status(self, folder, what=None): |
| … |
… |
|
| 753 | 760 | if typ != expected: |
| 754 | 761 | 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 |
| 755 | 774 | |
| 756 | 775 | def _checkok(self, command, typ, data): |
| … |
… |
|
| 859 | 878 | |
| 860 | 879 | |
| 861 | | def _parse_idle_response(text): |
| | 880 | def _parse_untagged_response(text): |
| 862 | 881 | assert text.startswith('* ') |
| 863 | 882 | text = text[2:] |
-
|
r265
|
r268
|
|
| 169 | 169 | |
| 170 | 170 | |
| 171 | | class TestIdle(IMAPClientTest): |
| | 171 | class TestIdleAndNoop(IMAPClientTest): |
| 172 | 172 | |
| 173 | 173 | def test_idle(self): |
| … |
… |
|
| 242 | 242 | def test_idle_done(self): |
| 243 | 243 | 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} |
| 245 | 271 | |
| 246 | 272 | counter = itertools.count() |
| … |
… |
|
| 249 | 275 | if count == 0: |
| 250 | 276 | 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 |
| 253 | 279 | |
| 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, {}) |
| 257 | 283 | self.assertEqual(text, 'Idle done') |
| 258 | 284 | self.assertListEqual([(99, 'EXISTS')], responses) |
| 259 | 285 | |
| 260 | 286 | |
| | 287 | |
| 261 | 288 | class TestDebugLogging(IMAPClientTest): |
| 262 | 289 | |
-
|
r267
|
r268
|
|
| 507 | 507 | self.assertGreater(len(text), 0) |
| 508 | 508 | |
| | 509 | def test_noop(self): |
| | 510 | self.client.select_folder('INBOX') |
| | 511 | |
| | 512 | # Initially there should be no responses |
| | 513 | text, resps = self.client.noop() |
| | 514 | self.assertTrue(isinstance(text, str)) |
| | 515 | self.assertGreater(len(text), 0) |
| | 516 | self.assertEquals(resps, []) |
| | 517 | |
| | 518 | # Start a new connection and upload a new message |
| | 519 | client2 = create_client_from_config(conf) |
| | 520 | client2.select_folder('INBOX') |
| | 521 | client2.append('INBOX', SIMPLE_MESSAGE) |
| | 522 | |
| | 523 | # Check for this addition in the NOOP data |
| | 524 | msg, resps = self.client.noop() |
| | 525 | self.assertTrue(isinstance(text, str)) |
| | 526 | self.assertGreater(len(text), 0) |
| | 527 | self.assertTrue(isinstance(resps, list)) |
| | 528 | self.assertIn((1, 'EXISTS'), resps) |
| 509 | 529 | |
| 510 | 530 | return LiveTest |