Browse Source

add mailboxes to GET /api/v2/aliases

Son NK 5 năm trước cách đây
mục cha
commit
165d986561
4 tập tin đã thay đổi với 56 bổ sung30 xóa
  1. 14 26
      README.md
  2. 34 3
      app/api/serializer.py
  3. 3 1
      app/api/views/alias.py
  4. 5 0
      tests/api/test_alias.py

+ 14 - 26
README.md

@@ -881,7 +881,10 @@ If success, 200 with the list of aliases. Each alias has the following fields:
 - nb_block
 - nb_block
 - nb_forward
 - nb_forward
 - nb_reply
 - nb_reply
-- mailbox
+- mailbox: obsolete, should use `mailboxes` instead.
+    - id
+    - email
+- mailboxes: list of mailbox, contains at least 1 mailbox.
     - id
     - id
     - email
     - email
 - (optional) latest_activity:
 - (optional) latest_activity:
@@ -908,6 +911,16 @@ Here's an example:
         "email": "a@b.c",
         "email": "a@b.c",
         "id": 1
         "id": 1
       },
       },
+      "mailboxes": [
+        {
+          "email": "m1@cd.ef",
+          "id": 2
+        },
+        {
+          "email": "john@wick.com",
+          "id": 1
+        }
+      ],
       "latest_activity": {
       "latest_activity": {
         "action": "forward",
         "action": "forward",
         "contact": {
         "contact": {
@@ -921,31 +934,6 @@ Here's an example:
       "nb_forward": 1,
       "nb_forward": 1,
       "nb_reply": 0,
       "nb_reply": 0,
       "note": null
       "note": null
-    },
-    {
-      "creation_date": "2020-04-06 17:57:14+00:00",
-      "creation_timestamp": 1586195834,
-      "email": "prefix0.hey@sl.local",
-      "name": null,
-      "enabled": true,
-      "id": 2,
-      "mailbox": {
-        "email": "a@b.c",
-        "id": 1
-      },
-      "latest_activity": {
-        "action": "forward",
-        "contact": {
-          "email": "c0@example.com",
-          "name": null,
-          "reverse_alias": "\"c0 at example.com\" <re0@SL>"
-        },
-        "timestamp": 1586195834
-      },
-      "nb_block": 0,
-      "nb_forward": 1,
-      "nb_reply": 0,
-      "note": null
     }
     }
   ]
   ]
 }
 }

+ 34 - 3
app/api/serializer.py

@@ -13,6 +13,7 @@ from app.models import Alias, Contact, EmailLog, Mailbox
 class AliasInfo:
 class AliasInfo:
     alias: Alias
     alias: Alias
     mailbox: Mailbox
     mailbox: Mailbox
+    mailboxes: [Mailbox]
 
 
     nb_forward: int
     nb_forward: int
     nb_blocked: int
     nb_blocked: int
@@ -21,6 +22,9 @@ class AliasInfo:
     latest_email_log: EmailLog = None
     latest_email_log: EmailLog = None
     latest_contact: Contact = None
     latest_contact: Contact = None
 
 
+    def contain_mailbox(self, mailbox_id: int) -> bool:
+        return mailbox_id in [m.id for m in self.mailboxes]
+
 
 
 def serialize_alias_info(alias_info: AliasInfo) -> dict:
 def serialize_alias_info(alias_info: AliasInfo) -> dict:
     return {
     return {
@@ -54,6 +58,10 @@ def serialize_alias_info_v2(alias_info: AliasInfo) -> dict:
         "nb_reply": alias_info.nb_reply,
         "nb_reply": alias_info.nb_reply,
         # mailbox
         # mailbox
         "mailbox": {"id": alias_info.mailbox.id, "email": alias_info.mailbox.email},
         "mailbox": {"id": alias_info.mailbox.id, "email": alias_info.mailbox.email},
+        "mailboxes": [
+            {"id": mailbox.id, "email": mailbox.email}
+            for mailbox in alias_info.mailboxes
+        ],
     }
     }
     if alias_info.latest_email_log:
     if alias_info.latest_email_log:
         email_log = alias_info.latest_email_log
         email_log = alias_info.latest_email_log
@@ -158,7 +166,13 @@ def get_alias_infos_with_pagination_v2(
 
 
     q = q.group_by(Alias.id, Mailbox.id)
     q = q.group_by(Alias.id, Mailbox.id)
 
 
-    q = q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT)
+    q = list(q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT))
+
+    # preload alias.mailboxes to speed up
+    alias_ids = [alias.id for alias, _, _ in q]
+    Alias.query.options(joinedload(Alias._mailboxes)).filter(
+        Alias.id.in_(alias_ids)
+    ).all()
 
 
     for alias, mailbox, latest_activity in q:
     for alias, mailbox, latest_activity in q:
         ret.append(get_alias_info_v2(alias, mailbox))
         ret.append(get_alias_info_v2(alias, mailbox))
@@ -174,7 +188,12 @@ def get_alias_info(alias: Alias) -> AliasInfo:
     )
     )
 
 
     alias_info = AliasInfo(
     alias_info = AliasInfo(
-        alias=alias, nb_blocked=0, nb_forward=0, nb_reply=0, mailbox=alias.mailbox
+        alias=alias,
+        nb_blocked=0,
+        nb_forward=0,
+        nb_reply=0,
+        mailbox=alias.mailbox,
+        mailboxes=[alias.mailbox],
     )
     )
 
 
     for _, el in q:
     for _, el in q:
@@ -200,9 +219,21 @@ def get_alias_info_v2(alias: Alias, mailbox) -> AliasInfo:
     latest_contact = None
     latest_contact = None
 
 
     alias_info = AliasInfo(
     alias_info = AliasInfo(
-        alias=alias, nb_blocked=0, nb_forward=0, nb_reply=0, mailbox=mailbox
+        alias=alias,
+        nb_blocked=0,
+        nb_forward=0,
+        nb_reply=0,
+        mailbox=mailbox,
+        mailboxes=[mailbox],
     )
     )
 
 
+    for m in alias._mailboxes:
+        alias_info.mailboxes.append(m)
+
+    # remove duplicates
+    # can happen that alias.mailbox_id also appears in AliasMailbox table
+    alias_info.mailboxes = list(set(alias_info.mailboxes))
+
     for contact, email_log in q:
     for contact, email_log in q:
         if email_log.is_reply:
         if email_log.is_reply:
             alias_info.nb_reply += 1
             alias_info.nb_reply += 1

+ 3 - 1
app/api/views/alias.py

@@ -20,7 +20,7 @@ from app.dashboard.views.alias_log import get_alias_log
 from app.email_utils import parseaddr_unicode
 from app.email_utils import parseaddr_unicode
 from app.extensions import db
 from app.extensions import db
 from app.log import LOG
 from app.log import LOG
-from app.models import Alias, Contact, Mailbox
+from app.models import Alias, Contact, Mailbox, AliasMailbox
 from app.utils import random_string
 from app.utils import random_string
 
 
 
 
@@ -85,6 +85,8 @@ def get_aliases_v2():
             - nb_block
             - nb_block
             - nb_reply
             - nb_reply
             - note
             - note
+            - mailbox
+            - mailboxes
             - (optional) latest_activity:
             - (optional) latest_activity:
                 - timestamp
                 - timestamp
                 - action: forward|reply|block|bounced
                 - action: forward|reply|block|bounced

+ 5 - 0
tests/api/test_alias.py

@@ -184,6 +184,11 @@ def test_get_aliases_v2(flask_client):
     assert "id" in r0["mailbox"]
     assert "id" in r0["mailbox"]
     assert "email" in r0["mailbox"]
     assert "email" in r0["mailbox"]
 
 
+    assert r0["mailboxes"]
+    for mailbox in r0["mailboxes"]:
+        assert "id" in mailbox
+        assert "email" in mailbox
+
 
 
 def test_delete_alias(flask_client):
 def test_delete_alias(flask_client):
     user = User.create(
     user = User.create(