Skip to content

Commit

Permalink
Add sort parameter to /api/collect/ endpoint #508
Browse files Browse the repository at this point in the history
    * Create CommaListField

Signed-off-by: Jono Yang <[email protected]>
  • Loading branch information
JonoYang committed Aug 2, 2024
1 parent 6c1a901 commit 2bbdbc2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 27 deletions.
31 changes: 17 additions & 14 deletions packagedb/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,20 @@ def filter(self, qs, value):
return qs.distinct() if self.distinct else qs


PACKAGE_FILTER_SORT_FIELDS = [
'type',
'namespace',
'name',
'version',
'qualifiers',
'subpath',
'download_url',
'filename',
'size',
'release_date',
]


class PackageFilterSet(FilterSet):
type = django_filters.CharFilter(
lookup_expr='iexact',
Expand Down Expand Up @@ -331,18 +345,7 @@ class PackageFilterSet(FilterSet):
lookup_expr='icontains',
)

sort = OrderingFilter(fields=[
'type',
'namespace',
'name',
'version',
'qualifiers',
'subpath',
'download_url',
'filename',
'size',
'release_date'
])
sort = OrderingFilter(fields=PACKAGE_FILTER_SORT_FIELDS)

class Meta:
model = Package
Expand Down Expand Up @@ -828,7 +831,6 @@ def list(self, request, format=None):
if addon_pipelines := validated_data.get('addon_pipelines', []):
kwargs["addon_pipelines"] = addon_pipelines

lookups = purl_to_lookups(purl)
packages = Package.objects.filter(**lookups)
if packages.count() == 0:
try:
Expand All @@ -840,7 +842,8 @@ def list(self, request, format=None):
return Response(message, status=status.HTTP_400_BAD_REQUEST)

lookups = purl_to_lookups(purl)
packages = Package.objects.filter(**lookups).order_by('-version')
sort = validated_data.get('sort', [])
packages = Package.objects.filter(**lookups).order_by(*sort)
if packages.count() == 0:
message = {}
if errors:
Expand Down
53 changes: 40 additions & 13 deletions packagedb/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@
# See https://aboutcode.org for more information about nexB OSS projects.
#

from django.http import HttpRequest
from django.urls import reverse_lazy
from packagedb.models import DependentPackage
from packagedb.models import Package
from packagedb.models import PackageSet
from packagedb.models import PackageWatch
from packagedb.models import Party
from packagedb.models import Resource

from packageurl import PackageURL
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import BooleanField
Expand All @@ -29,6 +23,13 @@
from rest_framework.serializers import Serializer
from rest_framework.serializers import SerializerMethodField

from packagedb.models import DependentPackage
from packagedb.models import Package
from packagedb.models import PackageSet
from packagedb.models import PackageWatch
from packagedb.models import Party
from packagedb.models import Resource


class ResourceAPISerializer(HyperlinkedModelSerializer):
package = HyperlinkedRelatedField(view_name='api:package-detail', lookup_field='uuid', read_only=True)
Expand Down Expand Up @@ -373,27 +374,42 @@ class Meta:
fields = ['depth', 'watch_interval', 'is_active']


class CommaListField(ListField):
"""ListField that allows also a str of comma-separated values as value."""

def to_internal_value(self, data):
if isinstance(data, str):
split_data = []
for datum in data:
split_data.extend(datum.split(','))
data = split_data
return super().to_internal_value(data)


class CollectPackageSerializer(Serializer):
purl = CharField(help_text="PackageURL strings in canonical form.")
source_purl = CharField(
required=False,
required=False,
help_text="Source PackageURL.",
)

)
addon_pipelines = ListField(
child = CharField(),
required=False,
allow_empty=True,
help_text="Addon pipelines to run on the package.",
)

)
sort = CommaListField(
required=False,
help_text="Fields to sort Package results by.",
)

def validate_purl(self, value):
try:
PackageURL.from_string(value)
except ValueError as e:
raise ValidationError(f'purl validation error: {e}')
return value

def validate_source_purl(self, value):
if value:
try:
Expand All @@ -409,6 +425,12 @@ def validate_addon_pipelines(self, value):

return value

def validate_sort(self, value):
invalid_sort_fields = [field for field in value if not is_supported_sort_field(field)]
if invalid_sort_fields:
raise ValidationError(f'Error unsupported sort fields: {",".join(invalid_sort_fields)}')

return value

class PackageVersSerializer(Serializer):
purl = CharField()
Expand Down Expand Up @@ -502,3 +524,8 @@ class PurltoGitRepoResponseSerializer(Serializer):
def is_supported_addon_pipeline(addon_pipeline):
from minecode.model_utils import SUPPORTED_ADDON_PIPELINES
return addon_pipeline in SUPPORTED_ADDON_PIPELINES


def is_supported_sort_field(field):
from packagedb.api import PACKAGE_FILTER_SORT_FIELDS
return field in PACKAGE_FILTER_SORT_FIELDS

0 comments on commit 2bbdbc2

Please sign in to comment.