Skip to content

Commit

Permalink
api: allow filtering patches and covers by msgid
Browse files Browse the repository at this point in the history
In the process of fixing the previous bug, I realised that:

 a) /api/patches/msgid is a perfectly reasonable thing to attempt
 b) We have no way of finding a patch by message id in the API

We can't actualy make /api/patches/msgid work because it may not
be unique, but we can add a filter.

I'm shoehorning this into stable/2.2, even though it's technically
an API change: it's minor, not incompatible and in hindsight a
glaring hole.

Cc: Michael Ellerman <[email protected]>
Tested-by: Jeremy Kerr <[email protected]>
Reviewed-by: Andrew Donnellan <[email protected]>
Reviewed-by: Stephen Finucane <[email protected]>
Signed-off-by: Daniel Axtens <[email protected]>
(cherry picked from commit d08b6c7)
  • Loading branch information
daxtens committed Apr 14, 2020
1 parent 40f1fa9 commit 0a7a74a
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 4 deletions.
16 changes: 16 additions & 0 deletions docs/api/schemas/latest/patchwork.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ paths:
schema:
title: ''
type: string
- in: query
name: msgid
description: >
The cover message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
responses:
'200':
description: ''
Expand Down Expand Up @@ -474,6 +482,14 @@ paths:
schema:
title: ''
type: string
- in: query
name: msgid
description: >
The patch message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
responses:
'200':
description: ''
Expand Down
18 changes: 18 additions & 0 deletions docs/api/schemas/patchwork.j2
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,16 @@ paths:
schema:
title: ''
type: string
{% if version >= (1, 2) %}
- in: query
name: msgid
description: >
The cover message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
{% endif %}
responses:
'200':
description: ''
Expand Down Expand Up @@ -488,6 +498,14 @@ paths:
schema:
title: ''
type: string
- in: query
name: msgid
description: >
The patch message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
{% endif %}
responses:
'200':
Expand Down
16 changes: 16 additions & 0 deletions docs/api/schemas/v1.2/patchwork.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ paths:
schema:
title: ''
type: string
- in: query
name: msgid
description: >
The cover message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
responses:
'200':
description: ''
Expand Down Expand Up @@ -474,6 +482,14 @@ paths:
schema:
title: ''
type: string
- in: query
name: msgid
description: >
The patch message-id as a case-sensitive string, without leading or
trailing angle brackets, to filter by.
schema:
title: ''
type: string
responses:
'200':
description: ''
Expand Down
14 changes: 10 additions & 4 deletions patchwork/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ class Meta:
fields = ('submitter', 'project')


def msgid_filter(queryset, name, value):
return queryset.filter(**{name: '<' + value + '>'})


class CoverLetterFilterSet(TimestampMixin, BaseFilterSet):

project = ProjectFilter(queryset=Project.objects.all(), distinct=False)
Expand All @@ -180,6 +184,7 @@ class CoverLetterFilterSet(TimestampMixin, BaseFilterSet):
series = BaseFilter(queryset=Project.objects.all(),
widget=MultipleHiddenInput, distinct=False)
submitter = PersonFilter(queryset=Person.objects.all(), distinct=False)
msgid = CharFilter(method=msgid_filter)

class Meta:
model = CoverLetter
Expand All @@ -198,17 +203,18 @@ class PatchFilterSet(TimestampMixin, BaseFilterSet):
delegate = UserFilter(queryset=User.objects.all(), distinct=False)
state = StateFilter(queryset=State.objects.all(), distinct=False)
hash = CharFilter(lookup_expr='iexact')
msgid = CharFilter(method=msgid_filter)

class Meta:
model = Patch
# NOTE(dja): ideally we want to version the hash field, but I cannot
# find a way to do that which is reliable and not extremely ugly.
# NOTE(dja): ideally we want to version the hash/msgid field, but I
# can't find a way to do that which is reliable and not extremely ugly.
# The best I can come up with is manually working with request.GET
# which seems to rather defeat the point of using django-filters.
fields = ('project', 'series', 'submitter', 'delegate',
'state', 'archived', 'hash')
'state', 'archived', 'hash', 'msgid')
versioned_fields = {
'1.2': ('hash', ),
'1.2': ('hash', 'msgid'),
}


Expand Down
12 changes: 12 additions & 0 deletions patchwork/tests/api/test_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ def test_list_filter_submitter(self):
'submitter': '[email protected]'})
self.assertEqual(0, len(resp.data))

def test_list_filter_msgid(self):
"""Filter covers by msgid."""
cover = create_cover()

resp = self.client.get(self.api_url(), {'msgid': cover.url_msgid})
self.assertEqual([cover.id], [x['id'] for x in resp.data])

# empty response if nothing matches
resp = self.client.get(self.api_url(), {
'msgid': '[email protected]'})
self.assertEqual(0, len(resp.data))

@utils.store_samples('cover-list-1-0')
def test_list_version_1_0(self):
create_cover()
Expand Down
12 changes: 12 additions & 0 deletions patchwork/tests/api/test_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ def test_list_filter_hash_version_1_1(self):
{'hash': 'garbagevalue'})
self.assertEqual(1, len(resp.data))

def test_list_filter_msgid(self):
"""Filter patches by msgid."""
patch = self._create_patch()

resp = self.client.get(self.api_url(), {'msgid': patch.url_msgid})
self.assertEqual([patch.id], [x['id'] for x in resp.data])

# empty response if nothing matches
resp = self.client.get(self.api_url(), {
'msgid': '[email protected]'})
self.assertEqual(0, len(resp.data))

@utils.store_samples('patch-list-1-0')
def test_list_version_1_0(self):
"""List patches using API v1.0."""
Expand Down
6 changes: 6 additions & 0 deletions releasenotes/notes/rest-filter-msgid-41f693cd4e53cf93.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
api:
- |
The REST API now supports filtering patches and cover letters by message
ID, using the ``msgid`` query parameter. Don't include leading or trailing
angle brackets.

0 comments on commit 0a7a74a

Please sign in to comment.