Commit d4532ccd authored by Arkadiusz Hiler's avatar Arkadiusz Hiler

API: Add /cover/ endpoint

Complementary to /mbox/ and /mbox_with_cover/.
Signed-off-by: Arkadiusz Hiler's avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent e0992b92
Pipeline #21775 passed with stage
in 1 minute and 17 seconds
......@@ -548,12 +548,17 @@ A series has then ``n`` revisions, ``n`` going from ``1`` to ``version``.
Retrieve an mbox file that will contain all patches of this revision,
including cover letter. Cover letter presence makes this mbox unappliable by
``git am``.
``git am``. If the cover letter is not present the result is the same as
with regular ``/mbox/``
:query link: Add an HTTP link to the Patchwork patch page in each commit
message. This link is preceded by a tag which name is given
as argument of this parameter, eg. ``?link=Patchwork``.
.. http:get:: /api/1.0/series/(int: series_id)/revisions/(int: version)/cover/
Retrieve an mbox file that will contain just the cover letter. 404 if the
series/revisoin does not have one.
.. http:post:: /api/1.0/series/(int: series_id)/revisions/(int: version)/test-results/
......
......@@ -152,6 +152,8 @@ class APITestBase(test_series.Series0010):
content_hash = hashlib.md5()
content_hash.update(content.encode('utf-8'))
if content_hash.hexdigest() != md5sum:
print(content)
self.assertEqual(content_hash.hexdigest(), md5sum)
def _format_url(self, url):
......@@ -253,19 +255,46 @@ class APITest(APITestBase):
self.check_mbox("/series/%s/revisions/1/mbox/" % self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'6d59b59dbf751064408249e18401275f')
else:
self.check_mbox("/series/%s/revisions/1/mbox/" % self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'42e2b2c9eeccf912c998be41683f50d7')
def testMboxWithCoverLetter(self):
# XXX: since Python 3 email module wrap header lines differently
if six.PY3:
self.check_mbox("/series/%s/revisions/1/mbox_with_cover/" %
self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'826f03a224083df013a2b373459527a3')
else:
self.check_mbox("/series/%s/revisions/1/mbox/" % self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'42e2b2c9eeccf912c998be41683f50d7')
self.check_mbox("/series/%s/revisions/1/mbox_with_cover/" %
self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'3921b55a5ac3fb28eea0c4e198406cca')
def testCoverLetterMbox(self):
self.check_mbox("/series/%s/revisions/1/cover/" %
self.series.pk,
'for_each_-intel_-crtc-v2.mbox',
'462a3414aedd2710d3dfed8a651ecd10')
def testMboxAndMboxWithCoverShouldBeIdenticalForSeriesWithNoCL(self):
mbox = self.client.get('/api/1.0' +
"/series/%s/revisions/1/mbox/" % self.series3.pk)
mbox_with_cover = self.client.get('/api/1.0' +
"/series/%s/revisions/1/mbox_with_cover/"
% self.series3.pk)
self.assertEqual(mbox.content, mbox_with_cover.content)
def testCoverLetterMboxWithoutCoverLetter(self):
response = self.client.get('/api/1.0' +
"/series/%s/revisions/1/cover/" % self.series3.pk)
self.assertEquals(response.status_code, 404)
def _check_mbox_link(self, url, n):
response = self.client.get('/api/1.0' + url, {'link': 'Patchwork'})
m = re.findall('^Patchwork:.*http.*$',
......
......@@ -210,6 +210,9 @@ def revision_cover_letter_to_mbox(revision):
else:
body = revision.cover_letter
if body is None:
body = ''
mail = PatchMbox(body + '\n')
if revision.raw_cover_letter_headers:
......
......@@ -23,7 +23,7 @@ from django.core.exceptions import FieldDoesNotExist, PermissionDenied
from django.conf import settings
from django.core import mail
from django.db.models import Q
from django.http import HttpResponse
from django.http import HttpResponse, HttpResponseNotFound
from patchwork.tasks import send_reviewer_notification
from patchwork.models import (Project, Series, SeriesRevision, Patch, EventLog,
State, Test, TestResult, TestState, Person,
......@@ -268,21 +268,33 @@ class SeriesViewSet(mixins.ListModelMixin,
old, new)
def series_mbox(request, revision, with_cover=False):
def series_mbox(request, revision, with_cover=False, cover_only=False):
options = {
'patch-link': request.GET.get('link', None),
'request': request,
}
patches = revision.ordered_patches()
mails = [patch_to_mbox(x, options).as_string(True) for x in patches]
if with_cover and revision.cover_letter:
rev_mail = revision_cover_letter_to_mbox(revision).as_string(True)
mails = [rev_mail] + mails
mails = []
if cover_only and not revision.cover_letter:
return HttpResponseNotFound('no cover letter for this series/revision')
if cover_only or with_cover:
cover_mail = revision_cover_letter_to_mbox(revision).as_string(True)
if (with_cover and revision.cover_letter) or cover_only:
mails = [cover_mail]
if not cover_only:
patches = revision.ordered_patches()
mails += [patch_to_mbox(x, options).as_string(True) for x in patches]
data = '\n'.join(mails)
response = HttpResponse(content_type="text/plain")
response.write(data)
response['Content-Disposition'] = 'attachment; filename=' + \
revision.series.filename()
return response
......@@ -312,6 +324,11 @@ class RevisionViewSet(mixins.ListModelMixin, ListMixin,
rev = get_object_or_404(SeriesRevision, series=series_pk, version=pk)
return series_mbox(request, rev, with_cover=True)
@detail_route(methods=['get'])
def cover(self, request, series_pk=None, pk=None):
rev = get_object_or_404(SeriesRevision, series=series_pk, version=pk)
return series_mbox(request, rev, cover_only=True)
@detail_route(methods=['post'])
def newrevision(self, request, series_pk=None, pk=None):
rev = get_object_or_404(SeriesRevision, series=series_pk, version=pk)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment