Changeset 265:907c5153b355
- Timestamp:
- 19/07/11 13:29:30 (10 months ago)
- Author:
- Menno Smits <menno@…>
- Branch:
- default
- Message:
-
Added normalise_times attribute (#96)
Allows caller to select whether datetimes returned by fetch are native
or aware.
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r264
|
r265
|
|
| 27 | 27 | * interact.py can now read livetest.py INI files (#66) |
| 28 | 28 | * Added "debug" propety and setting of a log file (#90) |
| | 29 | * "normalise_times" attribute allows caller to select whether |
| | 30 | datetimes returned by fetch() are native or not (#96) (Thanks Andrew |
| | 31 | Scheller) |
| 29 | 32 | |
| 30 | 33 | Small Bug Fixes |
-
|
r233
|
r265
|
|
| 25 | 25 | |
| 26 | 26 | Johannes Heckel |
| 27 | | OAUTH and IDLE support. |
| | 27 | OAUTH and IDLE support. |
| | 28 | |
| | 29 | Andrew Scheller |
| | 30 | "normalise_times" support. |
| 28 | 31 | |
| 29 | 32 | Bug Reports |
-
|
r258
|
r265
|
|
| 67 | 67 | ``False``). |
| 68 | 68 | |
| | 69 | The *normalise_times* attribute specifies whether datetimes |
| | 70 | returned by ``fetch()`` are normalised to the local system time |
| | 71 | and include no timezone information (native), or are datetimes |
| | 72 | that include timezone information (aware). By default |
| | 73 | *normalise_times* is True (times are normalised to the local |
| | 74 | system time). This attribute can be changed between ``fetch()`` |
| | 75 | calls if required. |
| | 76 | |
| 69 | 77 | The *debug* property can be used to enable debug logging. It can |
| 70 | 78 | be set to an integer from 0 to 5 where 0 disables debug output and |
| … |
… |
|
| 95 | 103 | self.folder_encode = True |
| 96 | 104 | self.log_file = sys.stderr |
| | 105 | self.normalise_times = True |
| 97 | 106 | |
| 98 | 107 | self._imap = self._create_IMAP4() |
| … |
… |
|
| 654 | 663 | self._checkok('fetch', typ, data) |
| 655 | 664 | typ, data = self._imap._untagged_response(typ, data, 'FETCH') |
| 656 | | return parse_fetch_response(data) |
| | 665 | return parse_fetch_response(data, self.normalise_times) |
| 657 | 666 | |
| 658 | 667 | def append(self, folder, msg, flags=(), msg_time=None): |
-
|
r230
|
r265
|
|
| 52 | 52 | |
| 53 | 53 | |
| 54 | | def parse_fetch_response(text): |
| | 54 | def parse_fetch_response(text, normalise_times=True): |
| 55 | 55 | """Pull apart IMAP FETCH responses as returned by imaplib. |
| 56 | 56 | |
| … |
… |
|
| 89 | 89 | msg_id = _int_or_error(value, 'invalid UID') |
| 90 | 90 | elif word == 'INTERNALDATE': |
| 91 | | msg_data[word] = _convert_INTERNALDATE(value) |
| | 91 | msg_data[word] = _convert_INTERNALDATE(value, normalise_times) |
| 92 | 92 | elif word in ('BODY', 'BODYSTRUCTURE'): |
| 93 | 93 | msg_data[word] = BodyData.create(value) |
| … |
… |
|
| 129 | 129 | |
| 130 | 130 | |
| 131 | | def _convert_INTERNALDATE(date_string): |
| | 131 | def _convert_INTERNALDATE(date_string, normalise_times=True): |
| 132 | 132 | mo = imaplib.InternalDate.match('INTERNALDATE "%s"' % date_string) |
| 133 | 133 | if not mo: |
| … |
… |
|
| 149 | 149 | dt = datetime(year, mon, day, hour, min, sec, 0, tz) |
| 150 | 150 | |
| 151 | | # Normalise to host system's timezone |
| 152 | | return dt.astimezone(FixedOffset.for_system()).replace(tzinfo=None) |
| | 151 | if normalise_times: |
| | 152 | # Normalise to host system's timezone |
| | 153 | return dt.astimezone(FixedOffset.for_system()).replace(tzinfo=None) |
| | 154 | return dt |
| 153 | 155 | |
| 154 | 156 | |
-
|
r234
|
r265
|
|
| 6 | 6 | import socket |
| 7 | 7 | import sys |
| 8 | | import time |
| 9 | 8 | from datetime import datetime |
| 10 | 9 | from StringIO import StringIO |
| … |
… |
|
| 275 | 274 | self.assertIn('one', output) |
| 276 | 275 | self.assertIn('two', output) |
| 277 | | |
| 278 | | |
| | 276 | |
| | 277 | class TestTimeNormalisation(IMAPClientTest): |
| | 278 | |
| | 279 | def test_default(self): |
| | 280 | self.assertTrue(self.client.normalise_times) |
| | 281 | |
| | 282 | @patch('imapclient.imapclient.parse_fetch_response') |
| | 283 | def test_pass_through(self, parse_fetch_response): |
| | 284 | self.client._imap._command_complete.return_value = ('OK', sentinel.data) |
| | 285 | self.client._imap._untagged_response.return_value = ('OK', sentinel.fetch_data) |
| | 286 | |
| | 287 | def check(expected): |
| | 288 | self.client.fetch(22, ['SOMETHING']) |
| | 289 | parse_fetch_response.assert_called_with(sentinel.fetch_data, expected) |
| | 290 | |
| | 291 | self.client.normalise_times = True |
| | 292 | check(True) |
| | 293 | |
| | 294 | self.client.normalise_times = False |
| | 295 | check(False) |
| 279 | 296 | |
| 280 | 297 | if __name__ == '__main__': |
-
|
r230
|
r265
|
|
| 286 | 286 | |
| 287 | 287 | |
| 288 | | def test_INTERNALDATE(self): |
| | 288 | def test_INTERNALDATE_normalised(self): |
| 289 | 289 | def check(date_str, expected_dt): |
| 290 | 290 | output = parse_fetch_response(['3 (INTERNALDATE "%s")' % date_str]) |
| 291 | | self.assertEquals(output.keys(), [3]) |
| 292 | | self.assertEquals(set(output[3].keys()), set(['INTERNALDATE', 'SEQ'])) |
| 293 | 291 | actual_dt = output[3]['INTERNALDATE'] |
| 294 | 292 | self.assert_(actual_dt.tzinfo is None) # Returned date should be in local timezone |
| 295 | 293 | expected_dt = datetime_to_native(expected_dt) |
| 296 | | self.assert_(actual_dt == expected_dt, '%s != %s' % (actual_dt, expected_dt)) |
| | 294 | self.assertEquals(actual_dt, expected_dt) |
| 297 | 295 | |
| 298 | 296 | check(' 9-Feb-2007 17:08:08 -0430', |
| … |
… |
|
| 305 | 303 | datetime(2007, 12, 9, 17, 8, 8, 0, FixedOffset(0))) |
| 306 | 304 | |
| | 305 | def test_INTERNALDATE(self): |
| | 306 | def check(date_str, expected_dt): |
| | 307 | output = parse_fetch_response(['3 (INTERNALDATE "%s")' % date_str], normalise_times=False) |
| | 308 | actual_dt = output[3]['INTERNALDATE'] |
| | 309 | self.assertEquals(actual_dt, expected_dt) |
| | 310 | |
| | 311 | check(' 9-Feb-2007 17:08:08 -0430', |
| | 312 | datetime(2007, 2, 9, 17, 8, 8, 0, FixedOffset(-4*60 - 30))) |
| | 313 | |
| | 314 | check('12-Feb-2007 17:08:08 +0200', |
| | 315 | datetime(2007, 2, 12, 17, 8, 8, 0, FixedOffset(2*60))) |
| | 316 | |
| | 317 | check(' 9-Dec-2007 17:08:08 +0000', |
| | 318 | datetime(2007, 12, 9, 17, 8, 8, 0, FixedOffset(0))) |
| 307 | 319 | |
| 308 | 320 | def test_mixed_types(self): |