8
8
#
9
9
10
10
import logging
11
+
12
+ import django_filters
11
13
from django .core .exceptions import ValidationError
12
- from django .db .models import OuterRef
13
- from django .db .models import Q
14
- from django .db .models import Subquery
14
+ from django .db .models import OuterRef , Q , Subquery
15
+ from django_filters .filters import Filter , OrderingFilter
15
16
from django_filters .rest_framework import FilterSet
16
- from django_filters .filters import Filter
17
- from django_filters .filters import OrderingFilter
18
- import django_filters
19
-
20
17
from packageurl import PackageURL
21
18
from packageurl .contrib .django .utils import purl_to_lookups
22
- from rest_framework import status
23
- from rest_framework import viewsets
19
+ from rest_framework import status , viewsets
24
20
from rest_framework .decorators import action
25
21
from rest_framework .response import Response
22
+ from univers .version_constraint import InvalidConstraintsError
23
+ from univers .version_range import RANGE_CLASS_BY_SCHEMES , VersionRange
24
+ from univers .versions import InvalidVersion
26
25
27
- from matchcode .api import MultipleCharFilter
28
- from matchcode .api import MultipleCharInFilter
26
+ from matchcode .api import MultipleCharFilter , MultipleCharInFilter
29
27
# UnusedImport here!
30
28
# But importing the mappers and visitors module triggers routes registration
31
29
from minecode import visitors # NOQA
32
30
from minecode import priority_router
33
- from minecode .models import PriorityResourceURI
34
- from minecode .models import ScannableURI
31
+ from minecode .models import PriorityResourceURI , ScannableURI
35
32
from minecode .route import NoRouteAvailable
36
- from packagedb .models import Package
37
- from packagedb .models import PackageContentType
38
- from packagedb .models import PackageSet
39
- from packagedb .models import Resource
40
- from packagedb .serializers import DependentPackageSerializer
41
- from packagedb .serializers import ResourceAPISerializer
42
- from packagedb .serializers import PackageAPISerializer
43
- from packagedb .serializers import PackageSetAPISerializer
44
- from packagedb .serializers import PartySerializer
45
- from packagedb .package_managers import get_api_package_name
46
- from packagedb .package_managers import get_version_fetcher
47
- from packagedb .package_managers import VERSION_API_CLASSES_BY_PACKAGE_TYPE
48
-
49
- from univers import versions
50
- from univers .version_range import RANGE_CLASS_BY_SCHEMES
51
- from univers .versions import InvalidVersion
52
- from univers .version_range import VersionRange
53
- from univers .version_constraint import InvalidConstraintsError
33
+ from packagedb .filters import PackageSearchFilter
34
+ from packagedb .models import Package , PackageContentType , PackageSet , Resource
35
+ from packagedb .package_managers import (VERSION_API_CLASSES_BY_PACKAGE_TYPE ,
36
+ get_api_package_name ,
37
+ get_version_fetcher )
38
+ from packagedb .serializers import (DependentPackageSerializer ,
39
+ PackageAPISerializer ,
40
+ PackageSetAPISerializer , PartySerializer ,
41
+ ResourceAPISerializer )
54
42
55
43
logger = logging .getLogger (__name__ )
56
44
@@ -84,21 +72,21 @@ def filter(self, qs, value):
84
72
return qs .filter (package = package )
85
73
86
74
87
- class ResourceFilter (FilterSet ):
75
+ class ResourceFilterSet (FilterSet ):
88
76
package = PackageResourceUUIDFilter (label = 'Package UUID' )
89
77
purl = PackageResourcePurlFilter (label = 'Package pURL' )
90
78
md5 = MultipleCharInFilter (
91
- help_text = " Exact MD5. Multi-value supported." ,
79
+ help_text = ' Exact MD5. Multi-value supported.' ,
92
80
)
93
81
sha1 = MultipleCharInFilter (
94
- help_text = " Exact SHA1. Multi-value supported." ,
82
+ help_text = ' Exact SHA1. Multi-value supported.' ,
95
83
)
96
84
97
85
98
86
class ResourceViewSet (viewsets .ReadOnlyModelViewSet ):
99
87
queryset = Resource .objects .select_related ('package' )
100
88
serializer_class = ResourceAPISerializer
101
- filterset_class = ResourceFilter
89
+ filterset_class = ResourceFilterSet
102
90
lookup_field = 'sha1'
103
91
104
92
@action (detail = False , methods = ['post' ])
@@ -169,70 +157,63 @@ def filter_by_checksums(self, request, *args, **kwargs):
169
157
return self .get_paginated_response (serializer .data )
170
158
171
159
172
- class MultiplePackageURLFilter (Filter ):
160
+ class MultiplePackageURLFilter (MultipleCharFilter ):
173
161
def filter (self , qs , value ):
174
- try :
175
- request = self .parent .request
176
- except AttributeError :
177
- return None
162
+ if not value :
163
+ # Even though not a noop, no point filtering if empty.
164
+ return qs
178
165
179
- values = request .GET .getlist (self .field_name )
180
- if all (v == '' for v in values ):
166
+ if self .is_noop (qs , value ):
181
167
return qs
182
168
183
- values = {item for item in values }
169
+ if all (v == '' for v in value ):
170
+ return qs
184
171
185
172
q = Q ()
186
- for val in values :
173
+ for val in value :
187
174
lookups = purl_to_lookups (val )
188
175
if not lookups :
189
176
continue
190
-
191
177
q .add (Q (** lookups ), Q .OR )
192
178
193
- if not q :
194
- return qs .none ()
195
-
196
- return qs .filter (q )
197
-
198
-
199
- class PackageSearchFilter (Filter ):
200
- def filter (self , qs , value ):
201
- try :
202
- request = self .parent .request
203
- except AttributeError :
204
- return None
205
-
206
- if not value :
207
- return qs
179
+ if q :
180
+ qs = self .get_method (qs )(q )
181
+ else :
182
+ qs = qs .none ()
208
183
209
- return Package . objects . filter ( search_vector = value )
184
+ return qs . distinct () if self . distinct else qs
210
185
211
186
212
- class PackageFilter (FilterSet ):
187
+ class PackageFilterSet (FilterSet ):
213
188
type = django_filters .CharFilter (
214
- lookup_expr = " iexact" ,
215
- help_text = " Exact type. (case-insensitive)" ,
189
+ lookup_expr = ' iexact' ,
190
+ help_text = ' Exact type. (case-insensitive)' ,
216
191
)
217
192
namespace = django_filters .CharFilter (
218
- lookup_expr = " iexact" ,
219
- help_text = " Exact namespace. (case-insensitive)" ,
193
+ lookup_expr = ' iexact' ,
194
+ help_text = ' Exact namespace. (case-insensitive)' ,
220
195
)
221
196
name = MultipleCharFilter (
222
- lookup_expr = " iexact" ,
223
- help_text = " Exact name. Multi-value supported. (case-insensitive)" ,
197
+ lookup_expr = ' iexact' ,
198
+ help_text = ' Exact name. Multi-value supported. (case-insensitive)' ,
224
199
)
225
200
version = MultipleCharFilter (
226
- help_text = " Exact version. Multi-value supported." ,
201
+ help_text = ' Exact version. Multi-value supported.' ,
227
202
)
228
203
md5 = MultipleCharInFilter (
229
- help_text = " Exact MD5. Multi-value supported." ,
204
+ help_text = ' Exact MD5. Multi-value supported.' ,
230
205
)
231
206
sha1 = MultipleCharInFilter (
232
- help_text = "Exact SHA1. Multi-value supported." ,
207
+ help_text = 'Exact SHA1. Multi-value supported.' ,
208
+ )
209
+ purl = MultiplePackageURLFilter (
210
+ label = 'Package URL' ,
211
+ )
212
+ search = PackageSearchFilter (
213
+ label = 'Search' ,
214
+ field_name = 'name' ,
215
+ lookup_expr = 'icontains' ,
233
216
)
234
- purl = MultiplePackageURLFilter (label = 'Package URL' )
235
- search = PackageSearchFilter (label = 'Search' )
236
217
237
218
sort = OrderingFilter (fields = [
238
219
'type' ,
@@ -250,6 +231,7 @@ class PackageFilter(FilterSet):
250
231
class Meta :
251
232
model = Package
252
233
fields = (
234
+ 'search' ,
253
235
'type' ,
254
236
'namespace' ,
255
237
'name' ,
@@ -270,7 +252,7 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
270
252
queryset = Package .objects .prefetch_related ('dependencies' , 'parties' )
271
253
serializer_class = PackageAPISerializer
272
254
lookup_field = 'uuid'
273
- filterset_class = PackageFilter
255
+ filterset_class = PackageFilterSet
274
256
275
257
@action (detail = True , methods = ['get' ])
276
258
def latest_version (self , request , * args , ** kwargs ):
@@ -429,7 +411,7 @@ def index_packages(self, request, *args, **kwargs):
429
411
packages = request .data .get ('packages' ) or []
430
412
queued_packages = []
431
413
unqueued_packages = []
432
- supported_ecosystems = [" maven" , " npm" ]
414
+ supported_ecosystems = [' maven' , ' npm' ]
433
415
434
416
unique_purls , unsupported_packages , unsupported_vers = get_resolved_purls (packages , supported_ecosystems )
435
417
0 commit comments