Skip to content

Commit 5645eff

Browse files
authored
Sort emails in web deployment by newest first (#457)
1 parent d47fc52 commit 5645eff

File tree

6 files changed

+76
-6
lines changed

6 files changed

+76
-6
lines changed

opwen_email_server/actions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from opwen_email_server.services.storage import AzureObjectStorage
1919
from opwen_email_server.services.storage import AzureTextStorage
2020
from opwen_email_server.utils.email_parser import MimeEmailParser
21+
from opwen_email_server.utils.email_parser import descending_timestamp
2122
from opwen_email_server.utils.email_parser import ensure_has_sent_at
2223
from opwen_email_server.utils.email_parser import get_domain
2324
from opwen_email_server.utils.email_parser import get_domains
@@ -122,8 +123,9 @@ def _action(self, resource_id): # type: ignore
122123

123124
for email_address in self._get_pivot(email):
124125
domain = get_domain(email_address)
126+
desc_prefix = descending_timestamp(email['sent_at'])
125127
if domain.endswith(mailbox.MAILBOX_DOMAIN):
126-
index = f"{domain}/{email_address}/{self._folder}/{email['sent_at']}/{resource_id}"
128+
index = f"{domain}/{email_address}/{self._folder}/{desc_prefix}/{resource_id}"
127129
self._mailbox_storage.store_text(index, 'indexed')
128130

129131
self.log_event(events.MAILBOX_EMAIL_INDEXED, {'folder': self._folder}) # noqa: E501 # yapf: disable

opwen_email_server/constants/mailbox.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
MAILBOX_DOMAIN = 'lokole.ca' # type: Final
44
RECEIVED_FOLDER = 'received' # type: Final
55
SENT_FOLDER = 'sent' # type: Final
6+
FUTURE_TIMESTAMP = 2100000000 # type: Final

opwen_email_server/integration/webapp.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from opwen_email_server.services.storage import AzureObjectStorage
2525
from opwen_email_server.services.storage import AzureTextStorage
2626
from opwen_email_server.utils.collections import chunks
27+
from opwen_email_server.utils.email_parser import descending_timestamp
2728
from opwen_email_server.utils.email_parser import ensure_has_sent_at
2829
from opwen_email_server.utils.email_parser import get_domain
2930
from opwen_email_server.utils.email_parser import get_recipients
@@ -226,7 +227,9 @@ def _delete(self, email_address: str, uids: Iterable[str]):
226227
else:
227228
continue
228229

229-
self._mailbox_storage.delete(f"{domain}/{email_address}/{folder}/{email['sent_at']}/{uid}")
230+
desc_prefix = descending_timestamp(email['sent_at'])
231+
232+
self._mailbox_storage.delete(f"{domain}/{email_address}/{folder}/{desc_prefix}/{uid}")
230233

231234
def _mark_sent(self, uids: Iterable[str]):
232235
pass

opwen_email_server/utils/email_parser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from opwen_email_server.config import MAX_HEIGHT_IMAGES
2323
from opwen_email_server.config import MAX_WIDTH_IMAGES
24+
from opwen_email_server.constants import mailbox
2425
from opwen_email_server.utils.log import LogMixin
2526
from opwen_email_server.utils.serialization import to_base64
2627

@@ -225,6 +226,10 @@ def format_inline_images(email: dict, on_error: Callable) -> dict:
225226
return new_email
226227

227228

229+
def descending_timestamp(email_sent_at: str) -> str:
230+
return str(mailbox.FUTURE_TIMESTAMP - int(datetime.fromisoformat(email_sent_at).timestamp()))
231+
232+
228233
class MimeEmailParser(LogMixin):
229234
def __call__(self, mime_email: str) -> dict:
230235
email = parse_mime_email(mime_email)

tests/opwen_email_server/test_actions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ def test_200(self):
152152

153153
self.assertEqual(status, 200)
154154
self.email_storage.fetch_object.assert_called_once_with(email_id)
155-
self.mailbox_storage.store_text.assert_any_call('bar.lokole.ca/[email protected]/received/2019-10-26 22:47/123',
155+
self.mailbox_storage.store_text.assert_any_call('bar.lokole.ca/[email protected]/received/527869980/123',
156156
'indexed')
157-
self.mailbox_storage.store_text.assert_any_call('baz.lokole.ca/[email protected]/received/2019-10-26 22:47/123',
157+
self.mailbox_storage.store_text.assert_any_call('baz.lokole.ca/[email protected]/received/527869980/123',
158158
'indexed')
159159
self.assertEqual(self.mailbox_storage.store_text.call_count, 2)
160160

@@ -185,8 +185,8 @@ def test_200(self):
185185

186186
self.assertEqual(status, 200)
187187
self.email_storage.fetch_object.assert_called_once_with(email_id)
188-
self.mailbox_storage.store_text.assert_called_once_with(
189-
'foo.lokole.ca/[email protected]/sent/2019-10-26 22:47/123', 'indexed')
188+
self.mailbox_storage.store_text.assert_called_once_with('foo.lokole.ca/[email protected]/sent/527869980/123',
189+
'indexed')
190190

191191
def _execute_action(self, *args, **kwargs):
192192
action = actions.IndexSentEmailForMailbox(

tests/opwen_email_server/utils/test_email_parser.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,62 @@ def test_format_attachments_with_image(self):
289289

290290
self.assertNotEqual(input_content, output_content)
291291
self.assertEqual(input_filename, output_filename)
292+
293+
294+
class DescendingTimestampTests(TestCase):
295+
def test_descending_timestamp_correct(self):
296+
sent_at = '2020-02-01 21:09'
297+
298+
sent_at_timestamp = email_parser.descending_timestamp(sent_at)
299+
300+
self.assertEqual(sent_at_timestamp, '519408660')
301+
302+
def test_descending_timestamp_order_by_year(self):
303+
january_2020 = '2020-01-01 22:09'
304+
january_2021 = '2021-01-01 22:09'
305+
306+
january_2020_timestamp = email_parser.descending_timestamp(january_2020)
307+
january_2021_timestamp = email_parser.descending_timestamp(january_2021)
308+
309+
timestamp_ordering = sorted([january_2020_timestamp, january_2021_timestamp])
310+
self.assertEqual(timestamp_ordering, [january_2021_timestamp, january_2020_timestamp])
311+
312+
def test_descending_timestamp_order_by_month(self):
313+
january = '2020-01-01 22:09'
314+
february = '2020-02-02 22:09'
315+
316+
january_timestamp = email_parser.descending_timestamp(january)
317+
february_timestamp = email_parser.descending_timestamp(february)
318+
319+
timestamp_ordering = sorted([january_timestamp, february_timestamp])
320+
self.assertEqual(timestamp_ordering, [february_timestamp, january_timestamp])
321+
322+
def test_descending_timestamp_order_by_day(self):
323+
january_1st = '2020-01-01 22:09'
324+
january_2nd = '2020-01-02 22:09'
325+
326+
january_1_timestamp = email_parser.descending_timestamp(january_1st)
327+
january_2_timestamp = email_parser.descending_timestamp(january_2nd)
328+
329+
timestamp_ordering = sorted([january_1_timestamp, january_2_timestamp])
330+
self.assertEqual(timestamp_ordering, [january_2_timestamp, january_1_timestamp])
331+
332+
def test_descending_timestamp_order_by_hour(self):
333+
january_1st_22h09m = '2020-01-01 22:09'
334+
january_1st_23h09m = '2020-01-01 23:09'
335+
336+
january_22h09m_timestamp = email_parser.descending_timestamp(january_1st_22h09m)
337+
january_23h09m_timestamp = email_parser.descending_timestamp(january_1st_23h09m)
338+
339+
timestamp_ordering = sorted([january_22h09m_timestamp, january_23h09m_timestamp])
340+
self.assertEqual(timestamp_ordering, [january_23h09m_timestamp, january_22h09m_timestamp])
341+
342+
def test_descending_timestamp_order_by_minute(self):
343+
january_1st_22h09m = '2020-01-01 22:09'
344+
january_1st_22h11m = '2020-01-01 22:11'
345+
346+
january_22h09m_timestamp = email_parser.descending_timestamp(january_1st_22h09m)
347+
january_22h11m_timestamp = email_parser.descending_timestamp(january_1st_22h11m)
348+
349+
timestamp_ordering = sorted([january_22h09m_timestamp, january_22h11m_timestamp])
350+
self.assertEqual(timestamp_ordering, [january_22h11m_timestamp, january_22h09m_timestamp])

0 commit comments

Comments
 (0)