Skip to content

Commit 49f211f

Browse files
committed
Add a download_scan_data action in REST API packages endpoint #272
Signed-off-by: tdruez <tdruez@nexb.com>
1 parent 5014ff5 commit 49f211f

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

component_catalog/api.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,51 @@ def about(self, request, uuid):
922922
package = self.get_object()
923923
return Response({"about_data": package.as_about_yaml()})
924924

925+
# TODO: Remove duplication with send_scan_data_as_file_view
926+
@action(detail=True)
927+
def download_scan_data(self, request, uuid):
928+
import io
929+
import json
930+
import zipfile
931+
932+
from django.http import FileResponse
933+
934+
from rest_framework import status
935+
from rest_framework.response import Response
936+
937+
package = self.get_object()
938+
dataspace = request.user.dataspace
939+
940+
scancodeio = ScanCodeIO(dataspace)
941+
if not scancodeio.is_available():
942+
message = {"error": "The ScanCode.io service is not available"}
943+
return Response(message, status=status.HTTP_400_BAD_REQUEST)
944+
945+
scan_infos = scancodeio.get_scan_results(
946+
download_url=package.download_url,
947+
dataspace=dataspace,
948+
)
949+
project_uuid = scan_infos.get("uuid")
950+
951+
scan_results_url = scancodeio.get_scan_action_url(project_uuid, "results")
952+
scan_results = scancodeio.fetch_scan_data(scan_results_url)
953+
scan_summary_url = scancodeio.get_scan_action_url(project_uuid, "summary")
954+
scan_summary = scancodeio.fetch_scan_data(scan_summary_url)
955+
956+
filename = package.filename or package.package_url_filename
957+
in_memory_zip = io.BytesIO()
958+
with zipfile.ZipFile(in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) as zipf:
959+
zipf.writestr(f"{filename}_scan.json", json.dumps(scan_results, indent=2))
960+
zipf.writestr(f"{filename}_summary.json", json.dumps(scan_summary, indent=2))
961+
in_memory_zip.seek(0)
962+
963+
return FileResponse(
964+
in_memory_zip,
965+
filename=filename,
966+
as_attachment=True,
967+
content_type="application/zip",
968+
)
969+
925970
download_url_description = (
926971
"A single, or list of, Download URL(s).<br><br>"
927972
'<b>cURL style</b>: <code>-d "download_url=url1&download_url=url2"</code><br><br>'

component_catalog/views.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,9 @@ def send_scan_data_as_file_view(request, project_uuid, filename):
16421642
raise Http404
16431643

16441644
scancodeio = ScanCodeIO(dataspace)
1645+
if not scancodeio.is_available():
1646+
raise Http404("The ScanCode.io service is not available")
1647+
16451648
scan_results_url = scancodeio.get_scan_action_url(project_uuid, "results")
16461649
scan_results = scancodeio.fetch_scan_data(scan_results_url)
16471650
scan_summary_url = scancodeio.get_scan_action_url(project_uuid, "summary")

dejacode_toolkit/scancodeio.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def get_scan_action_url(self, project_uuid, action_name):
3939
detail_url = self.get_scan_detail_url(project_uuid)
4040
return f"{detail_url}{action_name}/"
4141

42+
# TODO: Rename as get_project_infos
4243
def get_scan_results(self, download_url, dataspace):
4344
scan_info = self.fetch_scan_info(uri=download_url, dataspace=dataspace)
4445

0 commit comments

Comments
 (0)