api/rest.py | 22 +++++++++-- api/urls.py | 3 +- tests/data/0023-multiple-project-patch.mbox.gz | Bin 0 -> 2274 bytes tests/data/0024-multiple-project-patch.json.gz | Bin 0 -> 2471 bytes tests/test_rest.py | 51 ++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 tests/data/0023-multiple-project-patch.mbox.gz create mode 100644 tests/data/0024-multiple-project-patch.json.gz
To apply a single message to the project according to the group user is from. For importer user, message is added to all recognised project. For other users, message is added to all the projects recognised and maintained by the user.
---
api/rest.py | 22 +++++++++--
api/urls.py | 3 +-
tests/data/0023-multiple-project-patch.mbox.gz | Bin 0 -> 2274 bytes
tests/data/0024-multiple-project-patch.json.gz | Bin 0 -> 2471 bytes
tests/test_rest.py | 51 ++++++++++++++++++++++++-
5 files changed, 70 insertions(+), 6 deletions(-)
create mode 100644 tests/data/0023-multiple-project-patch.mbox.gz
create mode 100644 tests/data/0024-multiple-project-patch.json.gz
diff --git a/api/rest.py b/api/rest.py
index 1f81fe7..6264085 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -17,7 +17,7 @@ from mod import dispatch_module_hook
from .models import Project, Message
from .search import SearchEngine
from rest_framework import (permissions, serializers, viewsets, filters,
- mixins, generics, renderers)
+ mixins, generics, renderers, status)
from rest_framework.decorators import detail_route
from rest_framework.fields import SerializerMethodField, CharField, JSONField, EmailField
from rest_framework.relations import HyperlinkedIdentityField
@@ -162,7 +162,6 @@ class AddressSerializer(serializers.Serializer):
except:
return [validated_data['address'], validated_data['address']]
-
class BaseMessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
@@ -288,7 +287,6 @@ class SeriesViewSet(BaseMessageViewSet):
filter_backends = (PatchewSearchFilter,)
search_fields = (SEARCH_PARAM,)
-
class ProjectSeriesViewSet(ProjectMessagesViewSetMixin,
SeriesViewSet, mixins.DestroyModelMixin):
def collect_patches(self, series):
@@ -368,7 +366,7 @@ class MessagePlainTextParser(BaseParser):
data = stream.read().decode("utf-8")
return MboxMessage(data).get_json()
-class MessagesViewSet(ProjectMessagesViewSetMixin,
+class ProjectMessagesViewSet(ProjectMessagesViewSetMixin,
BaseMessageViewSet, mixins.CreateModelMixin):
serializer_class = MessageSerializer
parser_classes = (JSONParser, MessagePlainTextParser, )
@@ -388,6 +386,22 @@ class MessagesViewSet(ProjectMessagesViewSetMixin,
context=self.get_serializer_context())
return self.get_paginated_response(serializer.data)
+class MessagesViewSet(BaseMessageViewSet):
+ serializer_class = MessageSerializer
+ parser_classes = (JSONParser, MessagePlainTextParser, )
+
+ def create(self, request, *args, **kwargs):
+ projects = [p for p in Project.objects.all() if p.recognizes(MboxMessage(self.request.data['mbox']))]
+
+ if 'importers' not in self.request.user.groups.all():
+ projects = set(projects) & set([p for p in Project.objects.all() if p.maintained_by(self.request.user)])
+ for project in projects:
+ request.data['project'] = project
+ serializer = MessageSerializer(data=request.data,context={'project': project, 'request': self.request})
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ return Response("Sucess", status=status.HTTP_201_CREATED)
+
# Results
class HyperlinkedResultField(HyperlinkedIdentityField):
diff --git a/api/urls.py b/api/urls.py
index 64e9629..2fd4e0f 100644
--- a/api/urls.py
+++ b/api/urls.py
@@ -31,12 +31,13 @@ router.include_format_suffixes = False
router.register('users', rest.UsersViewSet)
router.register('projects', rest.ProjectsViewSet)
router.register('series', rest.SeriesViewSet, base_name='series')
+router.register('messages', rest.MessagesViewSet)
projects_router = NestedDefaultRouter(router, 'projects', lookup='projects', trailing_slash=True)
projects_router.include_format_suffixes = False
projects_router.register('results', rest.ProjectResultsViewSet, base_name='results')
projects_router.register('series', rest.ProjectSeriesViewSet, base_name='series')
-projects_router.register('messages', rest.MessagesViewSet, base_name='messages')
+projects_router.register('messages', rest.ProjectMessagesViewSet, base_name='messages')
results_router = NestedDefaultRouter(projects_router, 'series', lookup='series', trailing_slash=True)
results_router.include_format_suffixes = False
diff --git a/tests/data/0023-multiple-project-patch.mbox.gz b/tests/data/0023-multiple-project-patch.mbox.gz
new file mode 100644
index 0000000000000000000000000000000000000000..6d63736020c35a523cdef327a3022c759c941436
GIT binary patch
literal 2274
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
literal 0
HcmV?d00001
diff --git a/tests/data/0024-multiple-project-patch.json.gz b/tests/data/0024-multiple-project-patch.json.gz
new file mode 100644
index 0000000000000000000000000000000000000000..2866b7fbac5a2fc5607b723dbd3d125a7dca4b7c
GIT binary patch
literal 2471
zcmV;Y30U?YiwFp?y7^iF18sF|bZKyGWi4=WZ)#;@bS-dUbYo~PYIARH0KHi2Rw79f
z{y$F<$Nixm&7!Vcs-;^5Y?<-G0?zb~csxZ_0@+=aRb3YaXXk<TIrhaiG7AI*X?5nT
z=crT?5gGBtz5W3F`APiQ322fyBYMZY9UFFZRV%ByZfFMnYKmU8EQ{zQaAMctUQ87~
zi>Z?x$J84;sp5vg&S5Sm$p&Akn+hQ}|D-`iJbF+4TexZ0di68V3Z+}<Qa6iPI&FU&
z6?*PSZ&PN27l#qZr|~pluH(03no#c2b2b2vMwEN_G@ak$IVqiMN>rWbMo%+r-LO^b
zNfp5oBher7S)Mr_YM&&6bDJ@e;m?_zn7S-tl&6C2=1JB<>T}7|`=;l1ANwpx6GhdO
zFdpqZG0Y@ymy)D(=<orG;MqjE=QLH=AXupPYC+$h+;Gf8KH}Lsl=<r1Ga3hL7`<9R
z^flx(c|ZSGMjt3wrcQXwcuM_ui1=~zK5=m;kkNI4ETo1!|NRe~OQtv8>C-r&-!_{q
zKi$rPEEt3n!O);SyQfG`dZ7(0h{8Cfv3?vmsXL|*!gYP#p)N%#k96CoHbhR6z}{mx
z4#fqSNnzkH4&e}HzQ*)P*ob4sB%rHhMbpZPZdi&|0w;k8{mRmmdXOi~KDfS!cEY0S
zD)k4T9HS_VC>h3KP+bHT8H5?8YI5+TaCJ%HrLg+|V-!%$(_((s=d~;y<CU29DGNF2
z&?NKI#D-v^2)oc8>2Rd%r%5!d{_Q415~PtL?s>OmLN`yuSapbE_M$3&N5Nx>{D4=C
zse^YZ@`6P`2ydoY%t_lx$2J_j<LZx#h_FG3hZTHbZ}stJ6_DF~7)+ldEsS|!=@_~f
zy>=Iv2b!f-jEZiSE2?FbOS+<}WzDn<OSLTH1DwX}5Of1h=>SAc2Gz3lvaMEtsAW}!
zy>_>^zpiJ9g?=0+DeT?YwsvcqCQ927Bl|)jRCCo5sUa1vgT3a21z;*AO_J`dMC$uc
zm4bxjG-_ORiK?ol(LFga#PKkUHz(&NB+3$rG9qEA>KX=gG+J^MI!D!PvuvogW|+2t
zsHnHLVOmA)uVS#J{(ansnV~;VgrTOTk)k^{bYlZ~!BE3C)E5kG&;fHep+ZSCW5sT1
zMG`pyNl-_QnfbRElS!|2ABg_=K4bLC3&sQ!gT!8@D~o&4dBvill}ngdhEg(aZL3%+
z>3K8<6K#of?#guxq$jbq_0GGRqS}qK=3S>-yQ?+3ce+))tDn^Gx@R@bHuM~p1xoNH
zh?Zje=TxH9iAc|RCrZT^P?A;E4dZA9CT!p&n5d?LA7sIa;?NTh$}>cTHaD7z#Y(YE
z#k|c;&JxB)fB@a&WSXOf1KOCzP;1s3X9TfAs0hLYd-$P%zc65FvY)eGhO-6-E{#(*
z6itUhOuuIoM=o#fnpKBk{lY3WWRv~;!sb(5RBQF}iK!wQHC6V2HH`AP6i*HiW~_wQ
zz53Ql7~V&mXqrwinw%h62{D0&fkCF}O0jr5*L5?@8#ERQ*Q{FUR9AJgUOU;Uu)eDB
zX)HSJmZ0i$F|xcc{PuYRVYb&JNHg=P9WT>F1YP8d2x%cQM{nOluot$(01^39IYDg}
zq5VKahYoQD6K&$X5-wU7P4X*Fe>l(BfT`T)^$-VF4E^3TLLgE)NehvWW6K9{#}1B(
zY4y5yO3Hoyg>>^GNKU3U2uTgG3XDKkN@WN+EK))ce~#%?KyBk<C8il@wc%mRa7bn%
zpbvqEDb7Q_GsUthBAfZxwa943Mob0AfTGNeXF)&DJxjq@drNRHE5&#c;YPUaZupxn
z22r|NZF_eC(5_%^TwT;!m-g<f3y<VFYo1@(yPI-r7fw4@7xwO!5Rei&^>)wR-Cc5h
z?C=Cbi!`|#dRWG6_@0G`4T)k@!x{KgfalRvB1W*7$2b!65lN=#OU%D#O~Z!Im)C`J
zu_9u0=*ol`$^>pkl+&2Gx3Yi^v&YBjt&sb)H{`jz(yjWuo3HM;<Gy)u@AFrz?m~kT
zN_h`UH73Bu79(gb&@%xJ3QyUiE0}d!pQBip3Q@={qNmT#MGVPGv5=;$491e;nkU&H
zabq?>&ZBXP9o8-s^76ExE(H0-g)kCZNK#nH{CFskJQ4(HXfF+uv$nBh!Kc|9kZQKL
zbgoA&cE^bSOovS>I5|aOoCf~V{e`&%QPXW$SLArz=rig^n@G3mjH604=kLA+GVulD
z!|*R+wv1Tawc+J=Acvdd=MdK4R7gG6-ajDahF1!bw)#mH;!oc{J?;P1x>2oFa39X!
z0(`1&AFrgCwcWqZn{gb*iEK>o*hnx%Wr4S$zq3fu{?2=s#xLY|T=_)0+0f~p-l+h;
z-xaNjsvD-ELATwz)5M8hsp!RuIzPE?^zJO^2>NdO7qoOX8axAQ_QGU4P=dP_MGiLG
z)Sn(ghHcLk6F@vwpmrZJF9B?nu>*sQ`QB1B0ThXi6E|l?2&va?ICqjqKZK@$9gf!E
z|Cm#CWlX^djYrrkk6sS3k9pn3aLhz4&T{B`xWk0?FsAVIB^C>)VN0Wdm?~wj@3N8T
z-{Ejb2GjRKLkPjb`mE^A3-A2D;sU_GL5EinV~!%R27*?HA@gY>rVl<6bAlnJ1S)Ia
z9uc!8_t<cVf=4U`r|@G%1~1Z7aX6fl^*KW*C*YJEY8aL|uoT58S>>TybW9D08?|Vf
z()!n2+UExc2U~7lB0N3@qLmLzaDab{fRDemdS_SHJ@~EG>C`TJt!5XlI?!phJI!wM
zvRCW1t}gND6l$0Mf?ryfjYDW63tH3cK=X?rlN_y!_Iaz>z(|CDFz))9N8zZ&y(~%N
zX*Wd|JF!=|rbCA6w0%eHSb;MBxI*8KSmBh#!2@Q)uc4m>w1pM*byT_}BdcWRq5JK5
zOWq`|7X>ZOQs(&Vk$OMAa1%w7dsjomxjlB0oIs#$ngVUp_&=bHvqp?nqi{ikFrL<Y
zu~3On#`EX;&Pj1gz!Hh>NwcILdUPu(&gWe@gUzYPI@Jp^kR-?6AtZYk1Dry;iS@J9
zxa-wF>v!#D3qYM1YFVApy(#ZRPQMiYh}{a|JokpBLD@1*)2k@Tz^!PiYYd#>8*@*}
zdtLTPQV|iB%s(s7KLiAzO=FP_PL7p4+TcTZzQJLrE4(y&&UltRH}}KM=L}oRt*}%c
l;E0LCFpj~>$SNE9phPP}T~xq6-}&j!{{fhr=)@=+004(}!ae{1
literal 0
HcmV?d00001
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 7896e8a..9fd9ed9 100755
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -37,6 +37,8 @@ class RestTest(PatchewTestCase):
self.sp.prefix_tags = "block"
self.sp.save()
self.SUBPROJECT_BASE = '%sprojects/%d/' % (self.REST_BASE, self.sp.id)
+ self.p2 = self.add_project("EDK 2", "edk2-devel@lists.01.org")
+ self.PROJECT_BASE_2 = '%sprojects/%d/' % (self.REST_BASE, self.p2.id)
self.admin = User.objects.get(username='admin')
self.USER_BASE = '%susers/%d/' % (self.REST_BASE, self.admin.id)
@@ -64,7 +66,7 @@ class RestTest(PatchewTestCase):
def test_projects(self):
resp = self.api_client.get(self.REST_BASE + 'projects/')
- self.assertEquals(resp.data['count'], 2)
+ self.assertEquals(resp.data['count'], 3)
self.assertEquals(resp.data['results'][0]['resource_uri'], self.PROJECT_BASE)
self.assertEquals(resp.data['results'][0]['name'], "QEMU")
self.assertEquals(resp.data['results'][0]['mailing_list'], "qemu-devel@nongnu.org")
@@ -295,6 +297,32 @@ class RestTest(PatchewTestCase):
self.assertEqual(resp_get.status_code, 200)
self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH v4 0/2] Report format specific info for LUKS block driver")
+ def test_create_message_without_project_pk(self):
+ dp = self.get_data_path("0024-multiple-project-patch.json.gz")
+ with open(dp, "r") as f:
+ data = f.read()
+ self.api_client.login(username=self.user, password=self.password)
+ resp = self.api_client.post(self.REST_BASE + "messages/", data, content_type='application/json')
+ self.assertEqual(resp.status_code, 201)
+ self.assertEqual(resp.data, "Sucess")
+ resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+ self.assertEqual(resp_get.status_code, 200)
+ self.assertEqual(resp_get.data['subject'], "[Qemu-devel] [PATCH 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency")
+ resp_get2 = self.api_client.get(self.PROJECT_BASE_2 + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+
+ def test_create_text_message_without_project_pk(self):
+ dp = self.get_data_path("0023-multiple-project-patch.mbox.gz")
+ with open(dp, "r") as f:
+ data = f.read()
+ self.api_client.login(username=self.user, password=self.password)
+ resp = self.api_client.post(self.REST_BASE + "messages/", data, content_type='message/rfc822')
+ self.assertEqual(resp.status_code, 201)
+ self.assertEqual(resp.data, "Sucess")
+ resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+ self.assertEqual(resp_get.status_code, 200)
+ self.assertEqual(resp_get.data['subject'], "[Qemu-devel] [PATCH 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency")
+ resp_get2 = self.api_client.get(self.PROJECT_BASE_2 + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+
def test_message(self):
series = self.apply_and_retrieve('0001-simple-patch.mbox.gz',
self.p.id, '20160628014747.20971-1-famz@redhat.com')
@@ -346,5 +374,26 @@ class RestTest(PatchewTestCase):
resp = self.api_client.get(self.REST_BASE + 'schema/')
self.assertEqual(resp.status_code, 200)
+ # def test_create_message_without_project_pk(self):
+ # dp = self.get_data_path("multiple-project-patch.json.gz")
+ # with open(dp, "r") as f:
+ # data = f.read()
+ # self.api_client.login(username=self.user, password=self.password)
+ # resp = self.api_client.post(self.REST_BASE + "messages/", data, content_type='application/json')
+ # print(resp.data)
+ # self.assertEqual(resp.status_code, 201)
+ # resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+ # self.assertEqual(resp_get.status_code, 200)
+ # self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency")
+
+ # def test_create_text_message_without_project_pk(self):
+ # ? print(resp.data)
+
+ # self.assertEqual(resp.status_code, 201)
+ # resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/")
+ # self.assertEqual(resp_get.status_code, 200)
+ # self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency")
+
+
if __name__ == '__main__':
main()
--
2.14.3 (Apple Git-98)
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
Apparently calling only save in loop is leading to update. So overrode the create() and it works. + def test_create_message_without_project_pk(self): > + dp = self.get_data_path("0024-multiple-project-patch.json.gz") > + with open(dp, "r") as f: > + data = f.read() > + self.api_client.login(username=self.user, password=self.password) > + resp = self.api_client.post(self.REST_BASE + "messages/", data, > content_type='application/json') > + self.assertEqual(resp.status_code, 201) > + self.assertEqual(resp.data, "Sucess") > + resp_get = self.api_client.get(self.PROJECT_BASE + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + self.assertEqual(resp_get.status_code, 200) > + self.assertEqual(resp_get.data['subject'], "[Qemu-devel] [PATCH > 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency") > + resp_get2 = self.api_client.get(self.PROJECT_BASE_2 + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + > + def test_create_text_message_without_project_pk(self): > + dp = self.get_data_path("0023-multiple-project-patch.mbox.gz") > + with open(dp, "r") as f: > + data = f.read() > + self.api_client.login(username=self.user, password=self.password) > + resp = self.api_client.post(self.REST_BASE + "messages/", data, > content_type='message/rfc822') > + self.assertEqual(resp.status_code, 201) > + self.assertEqual(resp.data, "Sucess") > + resp_get = self.api_client.get(self.PROJECT_BASE + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + self.assertEqual(resp_get.status_code, 200) > + self.assertEqual(resp_get.data['subject'], "[Qemu-devel] [PATCH > 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency") > + resp_get2 = self.api_client.get(self.PROJECT_BASE_2 + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + > def test_message(self): > series = self.apply_and_retrieve('0001-simple-patch.mbox.gz', > self.p.id, ' > 20160628014747.20971-1-famz@redhat.com') > @@ -346,5 +374,26 @@ class RestTest(PatchewTestCase): > resp = self.api_client.get(self.REST_BASE + 'schema/') > self.assertEqual(resp.status_code, 200) > > + # def test_create_message_without_project_pk(self): > + # dp = self.get_data_path("multiple-project-patch.json.gz") > + # with open(dp, "r") as f: > + # data = f.read() > + # self.api_client.login(username=self.user, > password=self.password) > + # resp = self.api_client.post(self.REST_BASE + "messages/", data, > content_type='application/json') > + # print(resp.data) > + # self.assertEqual(resp.status_code, 201) > + # resp_get = self.api_client.get(self.PROJECT_BASE + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + # self.assertEqual(resp_get.status_code, 200) > + # self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH > 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency") > + > + # def test_create_text_message_without_project_pk(self): > + # ? print(resp.data) > + > + # self.assertEqual(resp.status_code, 201) > + # resp_get = self.api_client.get(self.PROJECT_BASE + "messages/ > 20180223132311.26555-2-marcandre.lureau@redhat.com/") > + # self.assertEqual(resp_get.status_code, 200) > + # self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH > 1/7] SecurityPkg/Tcg2Pei: drop Tcg2PhysicalPresenceLib dependency") > + > + > Ignore this, will correct it. > if __name__ == '__main__': > main() > -- > 2.14.3 (Apple Git-98) > > _______________________________________________ Patchew-devel mailing list Patchew-devel@redhat.com https://www.redhat.com/mailman/listinfo/patchew-devel
On 15/05/2018 11:26, Shubham Jain wrote: > To apply a single message to the project according to the group user is from. For importer user, message is added to all recognised project. For other users, message is added to all the projects recognised and maintained by the user. > --- > api/rest.py | 22 +++++++++-- > api/urls.py | 3 +- > tests/data/0023-multiple-project-patch.mbox.gz | Bin 0 -> 2274 bytes > tests/data/0024-multiple-project-patch.json.gz | Bin 0 -> 2471 bytes > tests/test_rest.py | 51 ++++++++++++++++++++++++- > 5 files changed, 70 insertions(+), 6 deletions(-) > create mode 100644 tests/data/0023-multiple-project-patch.mbox.gz > create mode 100644 tests/data/0024-multiple-project-patch.json.gz > > diff --git a/api/rest.py b/api/rest.py > index 1f81fe7..6264085 100644 > --- a/api/rest.py > +++ b/api/rest.py > @@ -17,7 +17,7 @@ from mod import dispatch_module_hook > from .models import Project, Message > from .search import SearchEngine > from rest_framework import (permissions, serializers, viewsets, filters, > - mixins, generics, renderers) > + mixins, generics, renderers, status) > from rest_framework.decorators import detail_route > from rest_framework.fields import SerializerMethodField, CharField, JSONField, EmailField > from rest_framework.relations import HyperlinkedIdentityField > @@ -162,7 +162,6 @@ class AddressSerializer(serializers.Serializer): > except: > return [validated_data['address'], validated_data['address']] > > - > class BaseMessageSerializer(serializers.ModelSerializer): > class Meta: > model = Message > @@ -288,7 +287,6 @@ class SeriesViewSet(BaseMessageViewSet): > filter_backends = (PatchewSearchFilter,) > search_fields = (SEARCH_PARAM,) > > - > class ProjectSeriesViewSet(ProjectMessagesViewSetMixin, > SeriesViewSet, mixins.DestroyModelMixin): > def collect_patches(self, series): > @@ -368,7 +366,7 @@ class MessagePlainTextParser(BaseParser): > data = stream.read().decode("utf-8") > return MboxMessage(data).get_json() > > -class MessagesViewSet(ProjectMessagesViewSetMixin, > +class ProjectMessagesViewSet(ProjectMessagesViewSetMixin, > BaseMessageViewSet, mixins.CreateModelMixin): > serializer_class = MessageSerializer > parser_classes = (JSONParser, MessagePlainTextParser, ) > @@ -388,6 +386,22 @@ class MessagesViewSet(ProjectMessagesViewSetMixin, > context=self.get_serializer_context()) > return self.get_paginated_response(serializer.data) > > +class MessagesViewSet(BaseMessageViewSet): > + serializer_class = MessageSerializer > + parser_classes = (JSONParser, MessagePlainTextParser, ) > + > + def create(self, request, *args, **kwargs): > + projects = [p for p in Project.objects.all() if p.recognizes(MboxMessage(self.request.data['mbox']))] > + > + if 'importers' not in self.request.user.groups.all(): > + projects = set(projects) & set([p for p in Project.objects.all() if p.maintained_by(self.request.user)]) > + for project in projects: > + request.data['project'] = project Is this line still needed? > + serializer = MessageSerializer(data=request.data,context={'project': project, 'request': self.request}) You can also do serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(project=project) It is a bit longer (you need to keep the older change to support request.data['project']), but perhaps cleaner because you reuse GenericViewSet's code to create the serializer and the context. > + serializer.is_valid(raise_exception=True) > + serializer.save() > + return Response("Sucess", status=status.HTTP_201_CREATED) The response should include all the serializer's data. You can do something similar to ResultsViewSet: results = [] ... for project in projects: ... results.append(serializer.data) return Response(OrderedDict([ ('count', len(results)), ('results', results) ]), status=status.HTTP_201_CREATED) Thanks, Paolo > + > # Results _______________________________________________ Patchew-devel mailing list Patchew-devel@redhat.com https://www.redhat.com/mailman/listinfo/patchew-devel
© 2016 - 2023 Red Hat, Inc.