[Patchew-devel] [PATCH 2/3] rest: POST for message endpoint

Shubham Jain posted 3 patches 6 years, 4 months ago
[Patchew-devel] [PATCH 2/3] rest: POST for message endpoint
Posted by Shubham Jain 6 years, 4 months ago
- Add "create" method to MessageManager so that it calls save_mbox()
- Fix nested writable serializer issue
- Add test for the create
---
 api/models.py      |  19 +++++++
 api/rest.py        |  20 ++++---
 tests/test_rest.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+), 7 deletions(-)

diff --git a/api/models.py b/api/models.py
index e161325..e043f09 100644
--- a/api/models.py
+++ b/api/models.py
@@ -247,6 +247,25 @@ class MessageManager(models.Manager):
             self.delete_subthread(r)
         msg.delete()
 
+    def create(self, project, **validated_data):
+        mbox = validated_data.pop('mbox')
+        m = MboxMessage(mbox)
+        msg = Message(**validated_data)
+        if 'in_reply_to' not in validated_data:
+            msg.in_reply_to = m.get_in_reply_to() or ""
+        msg.stripped_subject = m.get_subject(strip_tags=True)
+        msg.version = m.get_version()
+        msg.prefixes = m.get_prefixes()
+        msg.is_series_head = m.is_series_head()
+        msg.is_patch = m.is_patch()
+        msg.patch_num = m.get_num()[0]
+        msg.project = project
+        msg.mbox = mbox
+        msg.save_mbox(mbox)
+        msg.save()
+        emit_event("MessageAdded", message=msg)
+        return msg
+
     def add_message_from_mbox(self, mbox, user, project_name=None):
 
         def find_message_projects(m):
diff --git a/api/rest.py b/api/rest.py
index fc10b46..ed40a10 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -121,6 +121,7 @@ class HyperlinkedMessageField(HyperlinkedIdentityField):
 class AddressSerializer(serializers.Serializer):
     name = CharField(required=False)
     address = EmailField()
+    
     def to_representation(self, obj):
         if obj[0] != obj[1]:
             return {"name": obj[0], "address": obj[1]}
@@ -140,9 +141,13 @@ class BaseMessageSerializer(serializers.ModelSerializer):
         fields = ('resource_uri', 'message_id', 'subject', 'date', 'sender', 'recipients')
 
     resource_uri = HyperlinkedMessageField(view_name='messages-detail')
-
     recipients = AddressSerializer(many=True)
     sender = AddressSerializer()
+   
+    def create(self, validated_data):
+        validated_data['recipients'] = self.fields['recipients'].create(validated_data['recipients'])
+        validated_data['sender'] = self.fields['sender'].create(validated_data['sender'])
+        return Message.objects.create(project=self.context['project'], **validated_data)
 
 # a message_id is *not* unique, so we can only list
 class BaseMessageViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
@@ -157,6 +162,11 @@ class ProjectMessagesViewSetMixin(mixins.RetrieveModelMixin):
     def get_queryset(self):
         return self.queryset.filter(project=self.kwargs['projects_pk'])
 
+    def get_serializer_context(self):
+        try:
+            return {'project': Project.objects.get(id=self.kwargs['projects_pk']), 'request': self.request}
+        except: 
+            return Http404
 # Series
 
 class ReplySerializer(BaseMessageSerializer):
@@ -287,10 +297,7 @@ class MessageSerializer(BaseMessageSerializer):
     class Meta:
         model = Message
         fields = BaseMessageSerializer.Meta.fields + ('mbox', )
-
-    def get_mbox(self, obj):
-        return obj.get_mbox()
-    mbox = SerializerMethodField()
+    mbox = CharField()
 
     def get_fields(self):
         fields = super(MessageSerializer, self).get_fields()
@@ -312,9 +319,8 @@ class StaticTextRenderer(renderers.BaseRenderer):
             return data
 
 class MessagesViewSet(ProjectMessagesViewSetMixin,
-                      BaseMessageViewSet):
+                      BaseMessageViewSet, mixins.CreateModelMixin):
     serializer_class = MessageSerializer
-
     @detail_route(renderer_classes=[StaticTextRenderer])
     def mbox(self, request, *args, **kwargs):
         message = self.get_object()
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 21bc2b9..a002865 100755
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -18,6 +18,7 @@ from patchewtest import PatchewTestCase, main
 from api.models import Message
 from api.rest import AddressSerializer
 from collections import OrderedDict
+import json
 
 class RestTest(PatchewTestCase):
     def setUp(self):
@@ -256,6 +257,158 @@ class RestTest(PatchewTestCase):
         self.assertEqual(resp_after.status_code, 404)
         self.assertEqual(resp_reply_after.status_code, 404)
 
+    def test_create_message(self):
+        data = {
+                "message_id": "20171023201055.21973-11-andrew.smirnov@gmail.com",
+                "subject": "[Qemu-devel] [PATCH v2 10/27] imx_fec: Reserve full 4K "
+                           "page for the register file",
+                "date": "2017-10-23T20:10:38",
+                "sender": {
+                    "name": "Andrey Smirnov",
+                    "address": "andrew.smirnov@gmail.com"
+                },
+                "recipients": [
+                    {
+                    "address": "qemu-arm@nongnu.org"
+                    },
+                    {
+                    "name": "Peter Maydell",
+                    "address": "peter.maydell@linaro.org"
+                    },
+                    {
+                    "name": "Andrey Smirnov",
+                    "address": "andrew.smirnov@gmail.com"
+                    },
+                    {
+                    "name": "Jason Wang",
+                    "address": "jasowang@redhat.com"
+                    },
+                    {
+                    "name": "Philippe Mathieu-Daudé",
+                    "address": "f4bug@amsat.org"
+                    },
+                    {
+                    "address": "qemu-devel@nongnu.org"
+                    },
+                    {
+                    "address": "yurovsky@gmail.com"
+                    }
+                ],
+                "mbox": "From andrew.smirnov@gmail.com Mon Oct 23 20:10:38 2017\nDelivered"
+                        "-To: importer@patchew.org\nReceived-SPF: temperror (zoho.com: Err"
+                        "or in retrieving data from DNS) client-ip=208.118.235.17; envelop"
+                        "e-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=l"
+                        "ists.gnu.org;\nAuthentication-Results: mx.zohomail.com;\n\tdkim=f"
+                        "ail;\n\tspf=temperror (zoho.com: Error in retrieving data from DN"
+                        "S)  smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu."
+                        "org\nReturn-Path: <qemu-devel-bounces+importer=patchew.org@nongnu"
+                        ".org>\nReceived: from lists.gnu.org (208.118.235.17 [208.118.235."
+                        "17]) by mx.zohomail.com\n\twith SMTPS id 1508790023478635.2925706"
+                        "919272; Mon, 23 Oct 2017 13:20:23 -0700 (PDT)\nReceived: from loc"
+                        "alhost ([::1]:40414 helo=lists.gnu.org)\n\tby lists.gnu.org with "
+                        "esmtp (Exim 4.71)\n\t(envelope-from <qemu-devel-bounces+importer="
+                        "patchew.org@nongnu.org>)\n\tid 1e6jCo-0007Cr-Ed\n\tfor importer@p"
+                        "atchew.org; Mon, 23 Oct 2017 16:20:14 -0400\nReceived: from eggs."
+                        "gnu.org ([2001:4830:134:3::10]:46254)\n\tby lists.gnu.org with es"
+                        "mtp (Exim 4.71)\n\t(envelope-from <andrew.smirnov@gmail.com>) id "
+                        "1e6j4M-0000Ia-AF\n\tfor qemu-devel@nongnu.org; Mon, 23 Oct 2017 1"
+                        "6:11:32 -0400\nReceived: from Debian-exim by eggs.gnu.org with sp"
+                        "am-scanned (Exim 4.71)\n\t(envelope-from <andrew.smirnov@gmail.co"
+                        "m>) id 1e6j4L-0002WU-ES\n\tfor qemu-devel@nongnu.org; Mon, 23 Oct"
+                        " 2017 16:11:30 -0400\nReceived: from mail-pf0-x241.google.com ([2"
+                        "607:f8b0:400e:c00::241]:47361)\n\tby eggs.gnu.org with esmtps (TL"
+                        "S1.0:RSA_AES_128_CBC_SHA1:16)\n\t(Exim 4.71) (envelope-from <andr"
+                        "ew.smirnov@gmail.com>)\n\tid 1e6j4J-0002VQ-5h; Mon, 23 Oct 2017 1"
+                        "6:11:27 -0400\nReceived: by mail-pf0-x241.google.com with SMTP id"
+                        " z11so17896780pfk.4;\n\tMon, 23 Oct 2017 13:11:27 -0700 (PDT)\nRe"
+                        "ceived: from squirtle.westlake.spaceflightindustries.com ([173.22"
+                        "6.206.194])\n\tby smtp.gmail.com with ESMTPSA id\n\tj1sm15181623p"
+                        "fj.108.2017.10.23.13.11.24\n\t(version=TLS1_2 cipher=ECDHE-RSA-CH"
+                        "ACHA20-POLY1305 bits=256/256);\n\tMon, 23 Oct 2017 13:11:25 -0700"
+                        " (PDT)\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=g"
+                        "mail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-"
+                        "reply-to:references\n\t:mime-version:content-transfer-encoding;\n"
+                        "\tbh=zmFol33kPLVHCkj7Ro+lVg1LTAQod/G9dNqJXtckibI=;\n\tb=D49+KCtse"
+                        "bdshdA2kxqNqCWLEOTSRXI61CbfBrS3YYbGspt/3vTIRCLSKNhICr2UOc\n\t7BhL"
+                        "XRtMKhn2gomHPqqSHOSp+hB5XtMmBNpBpkQyXMHoGkgmjg0IIF02Vzn4i2QzP8C9"
+                        "\n\t0SDZb6VYnz70J5HY0KZwVfQ+Rc5qgJEfcTHzuzZ4qHcbXxPHYCGYo1yDG6bEU"
+                        "LNp2sRB\n\tGekoCKine5V1Uc+8aKmIeQA3zTXj2BLYqIQFi3UdiEemj94Gs3UFkE"
+                        "kV3kTtCBwBVYep\n\tCvtbjBMI4Kb2Rcyb7taNS1PwjoXo4nzyPqSftf5CtxE3FYQ"
+                        "6pSHkU8H1cqi4os4RgACQ\n\t6rrA==\nX-Google-DKIM-Signature: v=1; a="
+                        "rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x"
+                        "-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to"
+                        "\n\t:references:mime-version:content-transfer-encoding;\n\tbh=zmF"
+                        "ol33kPLVHCkj7Ro+lVg1LTAQod/G9dNqJXtckibI=;\n\tb=kG94Z4+JpBMpVNtWI"
+                        "ASASHAaqcxeUgqF149vlfmPjsUsUZoE69zK/Xq8lz25p+TskP\n\tu+sFtsuT//gI"
+                        "M/gFEeFYPBUEECFh+cSu6vYqjvy7W+o1dt0CkQS0K4sG2a6PDeXTc7Dw\n\tYOmEE"
+                        "gzEW+JtEp27yE8L5Yiur7k9cMnq6AGsLtrNa4leHN8KfnBLpZDJ1w2BTVAST/Mt\n"
+                        "\tp5OmcBALM2s2PfVxV2AqFIC03+BUkFo78Yl0dJkT95uUWQvXOrYnhrJGikBOpxf"
+                        "e2GEl\n\tdX/N0knNvw1ILQigiiD7mTg2pWBXXdi9ncxWFbWGav3NFgMuMj9Le7dh"
+                        "Merg+f0Pqzqq\n\tuMRw==\nX-Gm-Message-State: AMCzsaVtdnaUNbjj5huOS"
+                        "I8ibhSVAiVnF57PiIS4oVle1IVoBcH6i/W4\n\tsAtvFi/nF5bYIYfQxgZMU93rvm"
+                        "Mn\nX-Google-Smtp-Source: ABhQp+Tw1GtSPaSw51tZkI3AfiuyluStPI8C5/3"
+                        "esBqFkirOMfsjtlRNoBcr8lgEf/55RwhQLiI5mQ==\nX-Received: by 10.98.6"
+                        "5.218 with SMTP id g87mr14269292pfd.105.1508789486104;\n\tMon, 23"
+                        " Oct 2017 13:11:26 -0700 (PDT)\nFrom: Andrey Smirnov <andrew.smir"
+                        "nov@gmail.com>\nTo: qemu-arm@nongnu.org\nDate: Mon, 23 Oct 2017 1"
+                        "3:10:38 -0700\nMessage-Id: <20171023201055.21973-11-andrew.smirno"
+                        "v@gmail.com>\nX-Mailer: git-send-email 2.13.5\nIn-Reply-To: <2017"
+                        "1023201055.21973-1-andrew.smirnov@gmail.com>\nReferences: <201710"
+                        "23201055.21973-1-andrew.smirnov@gmail.com>\nMIME-Version: 1.0\nCo"
+                        "ntent-Type: text/plain; charset=\"utf-8\"\nContent-Transfer-Encod"
+                        "ing: base64\nX-detected-operating-system: by eggs.gnu.org: Genre "
+                        "and OS details not\n\trecognized.\nX-Received-From: 2607:f8b0:400"
+                        "e:c00::241\nSubject: [Qemu-devel] [PATCH v2 10/27] imx_fec: Reser"
+                        "ve full 4K page for the\n register file\nX-BeenThere: qemu-devel@"
+                        "nongnu.org\nX-Mailman-Version: 2.1.21\nPrecedence: list\nList-Id:"
+                        " <qemu-devel.nongnu.org>\nList-Unsubscribe: <https://lists.nongnu"
+                        ".org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@n"
+                        "ongnu.org?subject=unsubscribe>\nList-Archive: <http://lists.nongn"
+                        "u.org/archive/html/qemu-devel/>\nList-Post: <mailto:qemu-devel@no"
+                        "ngnu.org>\nList-Help: <mailto:qemu-devel-request@nongnu.org?subje"
+                        "ct=help>\nList-Subscribe: <https://lists.nongnu.org/mailman/listi"
+                        "nfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject"
+                        "=subscribe>\nCc: Peter Maydell <peter.maydell@linaro.org>,\n\tAnd"
+                        "rey Smirnov <andrew.smirnov@gmail.com>,\n\tJason Wang <jasowang@r"
+                        "edhat.com>,\n\t=?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <f4bug@a"
+                        "msat.org>,\n\tqemu-devel@nongnu.org, yurovsky@gmail.com\nErrors-T"
+                        "o: qemu-devel-bounces+importer=patchew.org@nongnu.org\nSender: \""
+                        "Qemu-devel\" <qemu-devel-bounces+importer=patchew.org@nongnu.org>"
+                        "\nX-ZohoMail-DKIM: fail (Header signature does not verify)\nX-Zoh"
+                        "oMail: RDKM_2  RSF_6  Z_629925259 SPT_0\n\nU29tZSBpLk1YIFNvQ3MgKG"
+                        "UuZy4gaS5NWDcpIGhhdmUgRkVDIHJlZ2lzdGVycyBnb2luZyBhcyBm\nYXIgYXMgb"
+                        "2Zmc2V0CjB4NjE0LCBzbyB0byBhdm9pZCBnZXR0aW5nIGFib3J0cyB3aGVuIGFjY2"
+                        "Vz\nc2luZyB0aG9zZSBvbiBRRU1VLCBleHRlbmQKdGhlIHJlZ2lzdGVyIGZpbGUgd"
+                        "G8gY292ZXIgNEtC\nIG9mIGFkZHJlc3Mgc3BhY2UgaW5zdGVhZCBvZiBqdXN0IDFL"
+                        "LgoKQ2M6IFBldGVyIE1heWRlbGwg\nPHBldGVyLm1heWRlbGxAbGluYXJvLm9yZz4"
+                        "KQ2M6IEphc29uIFdhbmcgPGphc293YW5nQHJlZGhh\ndC5jb20+CkNjOiBQaGlsaX"
+                        "BwZSBNYXRoaWV1LURhdWTDqSA8ZjRidWdAYW1zYXQub3JnPgpDYzog\ncWVtdS1kZ"
+                        "XZlbEBub25nbnUub3JnCkNjOiBxZW11LWFybUBub25nbnUub3JnCkNjOiB5dXJvdn"
+                        "Nr\neUBnbWFpbC5jb20KU2lnbmVkLW9mZi1ieTogQW5kcmV5IFNtaXJub3YgPGFuZ"
+                        "HJldy5zbWlybm92\nQGdtYWlsLmNvbT4KLS0tCiBody9uZXQvaW14X2ZlYy5jIHwg"
+                        "MiArLQogMSBmaWxlIGNoYW5nZWQs\nIDEgaW5zZXJ0aW9uKCspLCAxIGRlbGV0aW9"
+                        "uKC0pCgpkaWZmIC0tZ2l0IGEvaHcvbmV0L2lteF9m\nZWMuYyBiL2h3L25ldC9pbX"
+                        "hfZmVjLmMKaW5kZXggNDhkMDEyY2FkNi4uZTIzNmJjOTMzYyAxMDA2\nNDQKLS0tI"
+                        "GEvaHcvbmV0L2lteF9mZWMuYworKysgYi9ody9uZXQvaW14X2ZlYy5jCkBAIC0xMj"
+                        "Uy\nLDcgKzEyNTIsNyBAQCBzdGF0aWMgdm9pZCBpbXhfZXRoX3JlYWxpemUoRGV2a"
+                        "WNlU3RhdGUgKmRl\ndiwgRXJyb3IgKiplcnJwKQogICAgIFN5c0J1c0RldmljZSAq"
+                        "c2JkID0gU1lTX0JVU19ERVZJQ0Uo\nZGV2KTsKIAogICAgIG1lbW9yeV9yZWdpb25"
+                        "faW5pdF9pbygmcy0+aW9tZW0sIE9CSkVDVChkZXYp\nLCAmaW14X2V0aF9vcHMsIH"
+                        "MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVfSU1YX0ZF\nQywgMHg0M"
+                        "DApOworICAgICAgICAgICAgICAgICAgICAgICAgICBUWVBFX0lNWF9GRUMsIDB4MT"
+                        "Aw\nMCk7CiAgICAgc3lzYnVzX2luaXRfbW1pbyhzYmQsICZzLT5pb21lbSk7CiAgI"
+                        "CAgc3lzYnVzX2lu\naXRfaXJxKHNiZCwgJnMtPmlycVswXSk7CiAgICAgc3lzYnVz"
+                        "X2luaXRfaXJxKHNiZCwgJnMtPmly\ncVsxXSk7Ci0tIAoyLjEzLjUKCgo=\n\n"
+                }
+             
+        resp = self.api_client.post(self.PROJECT_BASE + "messages/", json.dumps(data), content_type='application/json')
+        self.assertEqual(resp.status_code, 201)
+        resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20171023201055.21973-11-andrew.smirnov@gmail.com/")
+        self.assertEqual(resp_get.status_code, 200)
+        self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH v2 10/27] imx_fec: Reserve full 4K "
+                         "page for the register file")
+
+
     def test_message(self):
         series = self.apply_and_retrieve('0001-simple-patch.mbox.gz',
                                          self.p.id, '20160628014747.20971-1-famz@redhat.com')
-- 
2.14.3 (Apple Git-98)

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
Re: [Patchew-devel] [PATCH 2/3] rest: POST for message endpoint
Posted by Paolo Bonzini 6 years, 4 months ago
On 08/05/2018 13:50, Shubham Jain wrote:
> - Add "create" method to MessageManager so that it calls save_mbox()
> - Fix nested writable serializer issue
> - Add test for the create

A better commit message could be

"Creation of a message is handled by the new "create" method in
MessageManager, which also takes care of calling save_mbox().  The code
currently has some code duplication with add_message_from_mbox(), which
will be fixed soon.  The "create" name follows Django idioms more
closely and is what DRF expects.

However, due to the nested AddressSerializer, the CreateModelMixin is
not enough, we have to define a "create" method in BaseMessageSerializer
too."

The idea is to describe what you are actually doing and also say why
you're doing.

Paolo

> ---
>  api/models.py      |  19 +++++++
>  api/rest.py        |  20 ++++---
>  tests/test_rest.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 185 insertions(+), 7 deletions(-)

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
Re: [Patchew-devel] [PATCH 2/3] rest: POST for message endpoint
Posted by Shubham Jain 6 years, 4 months ago
Alright. Will keep this in mind from next time. :)

On Tue, May 8, 2018 at 6:50 PM Paolo Bonzini <pbonzini@redhat.com> wrote:

> On 08/05/2018 13:50, Shubham Jain wrote:
> > - Add "create" method to MessageManager so that it calls save_mbox()
> > - Fix nested writable serializer issue
> > - Add test for the create
>
> A better commit message could be
>
> "Creation of a message is handled by the new "create" method in
> MessageManager, which also takes care of calling save_mbox().  The code
> currently has some code duplication with add_message_from_mbox(), which
> will be fixed soon.  The "create" name follows Django idioms more
> closely and is what DRF expects.
>
> However, due to the nested AddressSerializer, the CreateModelMixin is
> not enough, we have to define a "create" method in BaseMessageSerializer
> too."
>
> The idea is to describe what you are actually doing and also say why
> you're doing.
>
> Paolo
>
> > ---
> >  api/models.py      |  19 +++++++
> >  api/rest.py        |  20 ++++---
> >  tests/test_rest.py | 153
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 185 insertions(+), 7 deletions(-)
>
>
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel