From: Stephen Finucane Date: Mon, 6 Feb 2017 20:04:37 +0000 (+0000) Subject: REST: Expose events X-Git-Tag: v2.0.0-rc1~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7538f19657c9dec47b62b2f5a61d08bd8f84cff;p=thirdparty%2Fpatchwork.git REST: Expose events 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 Tested-by: Daniel Axtens --- diff --git a/patchwork/api/event.py b/patchwork/api/event.py new file mode 100644 index 00000000..0087ef7b --- /dev/null +++ b/patchwork/api/event.py @@ -0,0 +1,100 @@ +# Patchwork - automated patch tracking system +# Copyright (C) 2017 Stephen Finucane +# +# 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') diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py index ecef304c..0f2e6e95 100644 --- a/patchwork/api/filters.py +++ b/patchwork/api/filters.py @@ -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') diff --git a/patchwork/api/index.py b/patchwork/api/index.py index 58aeb87a..210c32e6 100644 --- a/patchwork/api/index.py +++ b/patchwork/api/index.py @@ -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')), }) diff --git a/patchwork/urls.py b/patchwork/urls.py index 2b2f5a52..09b8b31e 100644 --- a/patchwork/urls.py +++ b/patchwork/urls.py @@ -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[^/]+)/$', api_project_views.ProjectDetail.as_view(), name='api-project-detail'), + url(r'^events/$', + api_event_views.EventList.as_view(), + name='api-event-list'), ] urlpatterns += [