Skip to content

Commit

Permalink
Added the ability to export the current filtered QuerySet of a 'Filte…
Browse files Browse the repository at this point in the history
…rView' into the JSON format, Solves issue #1319

Signed-off-by: Aayush Kumar <[email protected]>
  • Loading branch information
aayushkdev committed Feb 1, 2025
1 parent d9f50b1 commit 62b3ddb
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
10 changes: 10 additions & 0 deletions scanpipe/pipes/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ def get_relations(self, project):
)


JSON_EXCLUDE_FIELDS = [
"extra_data",
"package_data",
"license_detections",
"other_license_detections",
"license_clues",
"affected_by_vulnerabilities",
]


def to_json(project):
"""
Generate output for the provided `project` in JSON format.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
<div class="dropdown-menu" id="dropdown-menu-action" role="menu">
<div class="dropdown-content">
<a href="?{{ export_xlsx_url_query }}" class="dropdown-item">
<i class="fa-solid fa-download mr-2"></i>Export results as XLSX
<i class="fa-solid fa-file-excel mr-2"></i>Export results as XLSX
</a>
<a href="?{{ export_json_url_query }}" class="dropdown-item">
<i class="fa-solid fa-file-pdf mr-2"></i>Export results as JSON
</a>
</div>
</div>
Expand Down
68 changes: 68 additions & 0 deletions scanpipe/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,69 @@ def get(self, request, *args, **kwargs):
return response


class ExportJSONMixin:
"""
Add the ability to export the current filtered QuerySet of a `FilterView`
into JSON format.
"""

export_json_query_param = "export_json"

def get_export_json_queryset(self):
return self.filterset.qs

def get_export_json_filename(self):
return f"{self.project.name}_{self.model._meta.model_name}.json"

def get_filtered_files(self, queryset):
from scanpipe.api.serializers import CodebaseResourceSerializer
yield from self.encode_queryset(queryset, CodebaseResourceSerializer)

def export_json_file_response(self):
queryset = self.get_export_json_queryset()

output_file = io.BytesIO()

for chunk in self.get_filtered_files(queryset):
output_file.write(chunk.encode("utf-8"))
output_file.seek(0)

return FileResponse(
output_file,
as_attachment=True,
filename=self.get_export_json_filename(),
content_type="application/json",
)

def encode_queryset(self, queryset, serializer_class):
for obj in queryset.iterator(chunk_size=2000):

serialized_obj = serializer_class(obj)
data = serialized_obj.data

for field in output.JSON_EXCLUDE_FIELDS:
data.pop(field, None)

yield json.dumps(data, indent=2)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

query_dict = self.request.GET.copy()
query_dict[self.export_json_query_param] = True
context["export_json_url_query"] = query_dict.urlencode()

return context

def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)

if request.GET.get(self.export_json_query_param):
return self.export_json_file_response()

return response


class FormAjaxMixin:
def is_xhr(self):
return self.request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"
Expand Down Expand Up @@ -1511,6 +1574,7 @@ class CodebaseResourceListView(
ProjectRelatedViewMixin,
TableColumnsMixin,
ExportXLSXMixin,
ExportJSONMixin,
PaginatedFilterView,
):
model = CodebaseResource
Expand Down Expand Up @@ -1584,6 +1648,7 @@ class DiscoveredPackageListView(
ProjectRelatedViewMixin,
TableColumnsMixin,
ExportXLSXMixin,
ExportJSONMixin,
PaginatedFilterView,
):
model = DiscoveredPackage
Expand Down Expand Up @@ -1640,6 +1705,7 @@ class DiscoveredDependencyListView(
ProjectRelatedViewMixin,
TableColumnsMixin,
ExportXLSXMixin,
ExportJSONMixin,
PaginatedFilterView,
):
model = DiscoveredDependency
Expand Down Expand Up @@ -1709,6 +1775,7 @@ class ProjectMessageListView(
ProjectRelatedViewMixin,
TableColumnsMixin,
ExportXLSXMixin,
ExportJSONMixin,
FilterView,
):
model = ProjectMessage
Expand All @@ -1733,6 +1800,7 @@ class CodebaseRelationListView(
PrefetchRelatedViewMixin,
TableColumnsMixin,
ExportXLSXMixin,
ExportJSONMixin,
PaginatedFilterView,
):
model = CodebaseRelation
Expand Down

0 comments on commit 62b3ddb

Please sign in to comment.