Raphael Hertzog <hert...@debian.org> writes: Hello,
thx for detailed answers. i'm attaching a new set of patches trying to include what we discussed. > If you contribute regularly, I would certainly welcome if you had > your own repository that I can merge from. That said I like to > have patches by email so that I can review and comment just by > reading and responding. Good. So i mirrored the repo and you can find the specific branch where i'm working atm here: https://gitlab.com/efkin/distro-tracker/commits/api > You could have access to the repository on alioth.debian.org, > but you would need to join the qa project. I'm not opposed to that > but I would rather wait until you have contributed a bit more > and until I know you a bit more as well. I think it's not strictly necessary after the mirror setup. But i'm happy in the future to keep collaborating regularly with this project. Let see how starts next year and i'll know better too. > Cheers, > -- > Raphaël Hertzog ◈ Debian Developer > > Support Debian LTS: http://www.freexian.com/services/debian-lts.html > Learn to master Debian: http://debian-handbook.info/get/ Cheers, -- efkin.
>From 5874f6a104700011f52b1f15f60c4a2be168e90b Mon Sep 17 00:00:00 2001 From: efkin <ef...@riseup.net> Date: Wed, 14 Dec 2016 13:04:52 +0100 Subject: [PATCH 1/3] Include rest_framework dependency --- distro_tracker/project/settings/defaults.py | 1 + docs/setup/setup.rst | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/distro_tracker/project/settings/defaults.py b/distro_tracker/project/settings/defaults.py index ad7defd..0f27309 100644 --- a/distro_tracker/project/settings/defaults.py +++ b/distro_tracker/project/settings/defaults.py @@ -249,6 +249,7 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', 'django.contrib.admin', 'django_email_accounts', + 'rest_framework', 'distro_tracker.html', 'distro_tracker.core', 'distro_tracker.accounts', diff --git a/docs/setup/setup.rst b/docs/setup/setup.rst index dad9ac0..0728dbd 100644 --- a/docs/setup/setup.rst +++ b/docs/setup/setup.rst @@ -15,6 +15,7 @@ Distro Tracker currently depends on the following Debian packages: - python-django-jsonfield (>= 1.0.0) - python-django-debug-toolbar (in development mode only) - python-django-captcha (optional) +- python-djangorestframework - python-debian - python-apt - python-gpgme @@ -35,7 +36,7 @@ For Python2.7, the following additional packages are required: Here is the list of required packages for development on Debian Jessie:: - $ sudo apt install python-django python-requests python-django-jsonfield python-django-debug-toolbar python-debian python-apt python-gpgme python-yaml python-bs4 python-soappy python-ldap python-pyinotify python-tox python-mock python-lzma python-selenium python3-django python3-requests python3-django-jsonfield python3-django-debug-toolbar python3-debian python3-apt python3-gpgme python3-yaml python3-bs4 python3-pyinotify python3-selenium chromium chromedriver + $ sudo apt install python-django python-requests python-django-jsonfield python-django-debug-toolbar python-debian python-apt python-gpgme python-yaml python-bs4 python-soappy python-ldap python-pyinotify python-tox python-mock python-lzma python-selenium python-djangorestframework python3-django python3-requests python3-django-jsonfield python3-djangorestframework python3-django-debug-toolbar python3-debian python3-apt python3-gpgme python3-yaml python3-bs4 python3-pyinotify python3-selenium chromium chromedriver .. _database_setup: -- 2.1.4
>From 5373c50f253922f00502715e8a34e8de7a0b9216 Mon Sep 17 00:00:00 2001 From: efkin <ef...@riseup.net> Date: Wed, 14 Dec 2016 13:14:35 +0100 Subject: [PATCH 2/3] Create distro_tracker submodule for API development --- distro_tracker/api/__init__.py | 0 distro_tracker/api/tests.py | 3 +++ distro_tracker/api/views.py | 3 +++ distro_tracker/project/settings/defaults.py | 1 + 4 files changed, 7 insertions(+) create mode 100644 distro_tracker/api/__init__.py create mode 100644 distro_tracker/api/tests.py create mode 100644 distro_tracker/api/views.py diff --git a/distro_tracker/api/__init__.py b/distro_tracker/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/distro_tracker/api/tests.py b/distro_tracker/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/distro_tracker/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/distro_tracker/api/views.py b/distro_tracker/api/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/distro_tracker/api/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/distro_tracker/project/settings/defaults.py b/distro_tracker/project/settings/defaults.py index 0f27309..0d42a37 100644 --- a/distro_tracker/project/settings/defaults.py +++ b/distro_tracker/project/settings/defaults.py @@ -250,6 +250,7 @@ INSTALLED_APPS = ( 'django.contrib.admin', 'django_email_accounts', 'rest_framework', + 'distro_tracker.api', 'distro_tracker.html', 'distro_tracker.core', 'distro_tracker.accounts', -- 2.1.4
>From e4336cb0549d1aae395de328dafb8f2f209400a5 Mon Sep 17 00:00:00 2001 From: efkin <ef...@riseup.net> Date: Wed, 14 Dec 2016 18:45:09 +0100 Subject: [PATCH 3/3] Create basic API list/detail endpoint for ActionItem model instances Reported_by: p...@debian.org --- distro_tracker/api/tests.py | 95 +++++++++++++++++++++++++++++++++++++++++- distro_tracker/api/views.py | 42 ++++++++++++++++++- distro_tracker/project/urls.py | 8 ++++ 3 files changed, 141 insertions(+), 4 deletions(-) diff --git a/distro_tracker/api/tests.py b/distro_tracker/api/tests.py index 7ce503c..7c53110 100644 --- a/distro_tracker/api/tests.py +++ b/distro_tracker/api/tests.py @@ -1,3 +1,94 @@ -from django.test import TestCase +from django.core.urlresolvers import reverse -# Create your tests here. +from rest_framework import status +from rest_framework.test import APITestCase + +from distro_tracker.core.models import ActionItem +from distro_tracker.core.models import ActionItemType +from distro_tracker.core.models import SourcePackageName + + +class ActionItemListAPIViewTest(APITestCase): + """ + Test for the :class:`distro_tracker.api.views.ActionItemListAPIView`. + """ + + def setUp(self): + self.url = reverse('dtracker-api-v1-action-items') + + def test_empty_list(self): + """ + Test when the queryset is empty. + """ + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual( + 0, + response.data['count'], + ) + + def test_account_item(self): + """ + Test with actual content. + """ + package = SourcePackageName.objects.create(name='dummy-package') + action_type = ActionItemType.objects.create( + type_name='test', + full_description_template='action-item-test.html', + ) + action_item = ActionItem.objects.create( + package=package, + item_type=action_type, + short_description="Short description of item", + ) + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual( + 1, + response.data['count'], + ) + result = response.data['results'][0] + self.assertEqual( + 'dummy-package', + result['package_name'], + ) + + +class ActionItemDetailAPIViewTest(APITestCase): + """ + Test for the :class:`distro_tracker.api.views.ActionItemDetailAPIView`. + """ + + def setUp(self): + self.url = reverse('dtracker-api-v1-action-items', kwargs={'pk':1}) + + def test_404_on_non_existing_pk(self): + """ + Test when the pk does not return any instance. + """ + response = self.client.get(self.url) + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_existing_instance(self): + """ + Test when the pk does return an actual instance. + """ + package = SourcePackageName.objects.create(name='dummy-package') + action_type = ActionItemType.objects.create( + type_name='test', + full_description_template='action-item-test.html', + ) + action_item = ActionItem.objects.create( + package=package, + item_type=action_type, + short_description="Short description of item", + ) + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual( + 'dummy-package', + response.data['package_name'], + ) + + diff --git a/distro_tracker/api/views.py b/distro_tracker/api/views.py index 91ea44a..62b5f37 100644 --- a/distro_tracker/api/views.py +++ b/distro_tracker/api/views.py @@ -1,3 +1,41 @@ -from django.shortcuts import render +from django.http import Http404 -# Create your views here. +from rest_framework import status +from rest_framework import generics +from rest_framework.response import Response + +from distro_tracker.api.serializers import ActionItemSerializer +from distro_tracker.core.models import ActionItem + + +class ActionItemListAPIView(generics.ListAPIView): + """ + List all ActionItem instances. + """ + + serializer_class = ActionItemSerializer + + # this next block assume DRF 2.X (as in debian stable) + # and assume pagination will break with DRF 3.X + paginate_by = 100 + paginate_by_param = 'page_size' + max_paginate_by = 500 + + def get_queryset(self): + queryset = ActionItem.objects.all() + package_name = self.request.GET.get('package_name', None) + if package_name is not None: + queryset = queryset.filter(package__name=package_name) + return queryset + + +class ActionItemDetailAPIView(generics.RetrieveAPIView): + """ + Retrieve an ActionItem instance. + """ + + queryset = ActionItem.objects.all() + serializer_class = ActionItemSerializer + + + diff --git a/distro_tracker/project/urls.py b/distro_tracker/project/urls.py index 5a5b091..3a29e10 100644 --- a/distro_tracker/project/urls.py +++ b/distro_tracker/project/urls.py @@ -67,6 +67,7 @@ from distro_tracker.accounts.views import PasswordChangeView from distro_tracker.accounts.views import ModifyKeywordsView from distro_tracker.accounts.views import AccountMergeConfirmView from distro_tracker.accounts.views import AccountMergeConfirmedView +from distro_tracker.api import views as api_views from django.contrib import admin admin.autodiscover() @@ -229,6 +230,13 @@ urlpatterns = [ url(r'^pkg/(?P<package_name>.+)/rss$', PackageNewsFeed(), name='dtracker-package-rss-news-feed'), + # API v1 + url(r'^api/v1/action-items/?$', + api_views.ActionItemListAPIView.as_view(), + name='dtracker-api-v1-action-items'), + url(r'^api/v1/action-items/(?P<pk>[0-9]+)/?$', + api_views.ActionItemDetailAPIView.as_view(), + name='dtracker-api-v1-action-items'), # Uncomment the admin/doc line below to enable admin documentation: # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), ] -- 2.1.4