Changeset 218:ae8dacf52b3d
- 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:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r216
|
r218
|
|
| 10 | 10 | try: |
| 11 | 11 | import imaplib2 as imaplib |
| 12 | | imaplib2 = True |
| | 12 | using_imaplib2 = True |
| 13 | 13 | except ImportError: |
| 14 | | imaplib2 = False |
| | 14 | using_imaplib2 = False |
| 15 | 15 | import imaplib |
| 16 | 16 | |
| … |
… |
|
| 27 | 27 | |
| 28 | 28 | __all__ = ['IMAPClient', 'DELETED', 'SEEN', 'ANSWERED', 'FLAGGED', 'DRAFT', |
| 29 | | 'RECENT'] |
| | 29 | 'RECENT', 'using_imaplib2'] |
| 30 | 30 | |
| 31 | 31 | from response_parser import parse_response, parse_fetch_response |
| … |
… |
|
| 295 | 295 | typ, data = self._imap.select(self._encode_folder_name(folder), readonly) |
| 296 | 296 | self._checkok('select', typ, data) |
| 297 | | if imaplib2: |
| | 297 | if using_imaplib2: |
| 298 | 298 | untagged_responses = self._response_to_dict(self._imap.untagged_responses) |
| 299 | 299 | else: |
| … |
… |
|
| 326 | 326 | return out |
| 327 | 327 | |
| 328 | | def idle(self, timeout=None, **kwargs): |
| | 328 | def idle(self, timeout=None, callback=None, **kwargs): |
| 329 | 329 | """Put server into IDLE mode. |
| 330 | 330 | |
| 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 |
| 332 | 332 | reaches the timeout, or another IMAP4 command is scheduled. |
| 333 | 333 | |
| … |
… |
|
| 337 | 337 | @param cb_arg: An optional argument that will be passed to the callback function. |
| 338 | 338 | @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 |
| 344 | 351 | 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: |
| 347 | 357 | 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] |
| 359 | 366 | |
| 360 | 367 | def folder_status(self, folder, what=None): |
| … |
… |
|
| 585 | 592 | else: |
| 586 | 593 | tag = self._imap._command('FETCH', msg_list, parts_list, modifiers_list) |
| 587 | | if imaplib2: |
| | 594 | if using_imaplib2: |
| 588 | 595 | typ, data = self._imap._command_complete(tag, 'FETCH') |
| 589 | 596 | else: |
-
|
r214
|
r218
|
|
| 9 | 9 | import os |
| 10 | 10 | import sys |
| | 11 | import time |
| | 12 | import threading |
| 11 | 13 | from datetime import datetime |
| 12 | 14 | from ConfigParser import SafeConfigParser, NoOptionError |
| … |
… |
|
| 449 | 451 | e = lower_if_str(e) |
| 450 | 452 | 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 | |
| 451 | 486 | return LiveTest |
| 452 | 487 | |