diff --git a/component_catalog/tests/test_views.py b/component_catalog/tests/test_views.py index 776c82ac..df01c583 100644 --- a/component_catalog/tests/test_views.py +++ b/component_catalog/tests/test_views.py @@ -2888,8 +2888,10 @@ def test_delete_scan_view(self, mock_fetch_scan_list, mock_delete_scan): response = self.client.get(delete_url) self.assertEqual(404, response.status_code) - @mock.patch("dejacode_toolkit.scancodeio.ScanCodeIO.stream_scan_data") - def test_send_scan_data_as_file_view(self, mock_stream_scan_data): + @mock.patch("dejacode_toolkit.scancodeio.ScanCodeIO.fetch_scan_data") + def test_send_scan_data_as_file_view(self, mock_fetch_scan_data): + mock_fetch_scan_data.return_value = {} + project_uuid = "348df847-f48f-4ac7-b864-5785b44c65e2" url = reverse( "component_catalog:scan_data_as_file", args=[project_uuid, self.package1.filename] @@ -2906,9 +2908,9 @@ def test_send_scan_data_as_file_view(self, mock_stream_scan_data): self.dataspace.save() response = self.client.get(url) self.assertEqual(200, response.status_code) - self.assertEqual("application/json", response["content-type"]) + self.assertEqual("application/zip", response["content-type"]) self.assertEqual( - 'attachment; filename="package1_scan.json"', response["content-disposition"] + 'attachment; filename="package1_scan.zip"', response["content-disposition"] ) @mock.patch("requests.head") diff --git a/component_catalog/views.py b/component_catalog/views.py index 2ababbd0..b2df46a6 100644 --- a/component_catalog/views.py +++ b/component_catalog/views.py @@ -6,7 +6,9 @@ # See https://aboutcode.org for more information about AboutCode FOSS projects. # +import io import json +import zipfile from collections import Counter from operator import itemgetter from urllib.parse import quote_plus @@ -1651,10 +1653,18 @@ def send_scan_data_as_file_view(request, project_uuid, filename): scancodeio = ScanCodeIO(request.user) scan_results_url = scancodeio.get_scan_results_url(project_uuid) - data_stream = scancodeio.stream_scan_data(scan_results_url) - - response = FileResponse(data_stream.iter_lines(), content_type="application/json") - response["Content-Disposition"] = f'attachment; filename="{filename}_scan.json"' + scan_results = scancodeio.fetch_scan_data(scan_results_url) + scan_summary_url = scancodeio.get_scan_summary_url(project_uuid) + scan_summary = scancodeio.fetch_scan_data(scan_summary_url) + + in_memory_zip = io.BytesIO() + with zipfile.ZipFile(in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) as zipf: + zipf.writestr(f"{filename}_scan.json", json.dumps(scan_results, indent=2)) + zipf.writestr(f"{filename}_summary.json", json.dumps(scan_summary, indent=2)) + + in_memory_zip.seek(0) + response = FileResponse(in_memory_zip, content_type="application/zip") + response["Content-Disposition"] = f'attachment; filename="{filename}_scan.zip"' return response diff --git a/dejacode_toolkit/scancodeio.py b/dejacode_toolkit/scancodeio.py index 19c23a0a..0fcd6e7e 100644 --- a/dejacode_toolkit/scancodeio.py +++ b/dejacode_toolkit/scancodeio.py @@ -39,6 +39,10 @@ def get_scan_results_url(self, project_uuid): detail_url = self.get_scan_detail_url(project_uuid) return f"{detail_url}results/" + def get_scan_summary_url(self, project_uuid): + detail_url = self.get_scan_detail_url(project_uuid) + return f"{detail_url}summary/" + def get_project_packages_url(self, project_uuid): return f"{self.project_api_url}{project_uuid}/packages/"