]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
REST: Expose events
authorStephen Finucane <stephen@that.guru>
Mon, 6 Feb 2017 20:04:37 +0000 (20:04 +0000)
committerStephen Finucane <stephen@that.guru>
Wed, 1 Mar 2017 22:17:17 +0000 (22:17 +0000)
This is a list only endpoint as it's expected that we would kill events
after a certain duration and would have no reason to allow indexing of
past events.

Signed-off-by: Stephen Finucane <stephen@that.guru>
Tested-by: Daniel Axtens <dja@axtens.net>
patchwork/api/event.py [new file with mode: 0644]
patchwork/api/filters.py
patchwork/api/index.py
patchwork/urls.py

diff --git a/patchwork/api/event.py b/patchwork/api/event.py
new file mode 100644 (file)
index 0000000..0087ef7
--- /dev/null
@@ -0,0 +1,100 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2017 Stephen Finucane <stephen@that.guru>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from django.core.urlresolvers import reverse
+from rest_framework.generics import ListAPIView
+from rest_framework.serializers import HyperlinkedModelSerializer
+from rest_framework.serializers import SerializerMethodField
+
+from patchwork.api.filters import EventFilter
+from patchwork.api.patch import StateField
+from patchwork.models import Event
+
+
+class EventSerializer(HyperlinkedModelSerializer):
+
+    previous_state = StateField()
+    current_state = StateField()
+    created_check = SerializerMethodField()
+
+    _category_map = {
+        Event.CATEGORY_COVER_CREATED: ['cover'],
+        Event.CATEGORY_PATCH_CREATED: ['patch'],
+        Event.CATEGORY_PATCH_COMPLETED: ['patch', 'series'],
+        Event.CATEGORY_PATCH_STATE_CHANGED: ['patch', 'previous_state',
+                                             'current_state'],
+        Event.CATEGORY_PATCH_DELEGATED: ['patch', 'previous_delegate',
+                                         'current_delegate'],
+        Event.CATEGORY_CHECK_CREATED: ['patch', 'created_check'],
+        Event.CATEGORY_SERIES_CREATED: ['series'],
+        Event.CATEGORY_SERIES_COMPLETED: ['series'],
+    }
+
+    def get_created_check(self, instance):
+        if not instance.patch or not instance.created_check:
+            return
+
+        return self.context.get('request').build_absolute_uri(
+            reverse('api-check-detail', kwargs={
+                'patch_id': instance.patch.id,
+                'check_id': instance.created_check.id}))
+
+    def to_representation(self, instance):
+        data = super(EventSerializer, self).to_representation(instance)
+
+        kept_fields = self._category_map[instance.category] + [
+            'id', 'category', 'project', 'date']
+        for field in [x for x in data if x not in kept_fields]:
+            del data[field]
+
+        return data
+
+    class Meta:
+        model = Event
+        fields = ('id', 'category', 'project', 'date', 'patch', 'series',
+                  'cover', 'previous_state', 'current_state',
+                  'previous_delegate', 'current_delegate', 'created_check')
+        read_only_fields = fields
+        extra_kwargs = {
+            'project': {'view_name': 'api-project-detail'},
+            'patch': {'view_name': 'api-patch-detail'},
+            'series': {'view_name': 'api-series-detail'},
+            'cover': {'view_name': 'api-cover-detail'},
+            'previous_delegate': {'view_name': 'api-user-detail'},
+            'current_delegate': {'view_name': 'api-user-detail'},
+            'created_check': {'view_name': 'api-check-detail'},
+        }
+
+
+class EventList(ListAPIView):
+    """List events."""
+
+    serializer_class = EventSerializer
+    filter_class = EventFilter
+    page_size_query_param = None  # fixed page size
+    ordering = '-date'
+    ordering_fields = ()
+
+    def get_queryset(self):
+        return Event.objects.all()\
+            .select_related('project', 'patch', 'series', 'cover',
+                            'previous_state', 'current_state',
+                            'previous_delegate', 'current_delegate',
+                            'created_check')\
+            .order_by('-date')
index ecef304ce8352407b03ba011833e6546e22dcb60..0f2e6e956f61b008c3b09d77c12cd9d2acfc06cb 100644 (file)
@@ -22,6 +22,7 @@ from django_filters import IsoDateTimeFilter
 
 from patchwork.models import Check
 from patchwork.models import CoverLetter
+from patchwork.models import Event
 from patchwork.models import Patch
 from patchwork.models import Series
 
@@ -60,3 +61,10 @@ class CheckFilter(TimestampMixin, FilterSet):
     class Meta:
         model = Check
         fields = ('user', 'state', 'context')
+
+
+class EventFilter(FilterSet):
+
+    class Meta:
+        model = Event
+        fields = ('project', 'series', 'patch', 'cover')
index 58aeb87a469b22bf577289fdffde5fe9577ec927..210c32e60e2fd9f16f0e2764446782b6ea32d5c6 100644 (file)
@@ -33,4 +33,5 @@ class IndexView(APIView):
             'patches': request.build_absolute_uri(reverse('api-patch-list')),
             'covers': request.build_absolute_uri(reverse('api-cover-list')),
             'series': request.build_absolute_uri(reverse('api-series-list')),
+            'events': request.build_absolute_uri(reverse('api-event-list')),
         })
index 2b2f5a52db8cd40a2631bbb3230644cc5c1260bd..09b8b31e0883333c4ed6521b046922416424f5c8 100644 (file)
@@ -159,8 +159,9 @@ if settings.ENABLE_REST_API:
             'djangorestframework must be installed to enable the REST API.')
 
     from patchwork.api import check as api_check_views
-    from patchwork.api import index as api_index_views
     from patchwork.api import cover as api_cover_views
+    from patchwork.api import event as api_event_views
+    from patchwork.api import index as api_index_views
     from patchwork.api import patch as api_patch_views
     from patchwork.api import person as api_person_views
     from patchwork.api import project as api_project_views
@@ -213,6 +214,9 @@ if settings.ENABLE_REST_API:
         url(r'^projects/(?P<pk>[^/]+)/$',
             api_project_views.ProjectDetail.as_view(),
             name='api-project-detail'),
+        url(r'^events/$',
+            api_event_views.EventList.as_view(),
+            name='api-event-list'),
     ]
 
     urlpatterns += [