-
-
Imports
+
+
Actions
{{ scancode_projects|length }}
diff --git a/product_portfolio/tests/test_views.py b/product_portfolio/tests/test_views.py
index 750e7000..2842dd16 100644
--- a/product_portfolio/tests/test_views.py
+++ b/product_portfolio/tests/test_views.py
@@ -205,7 +205,7 @@ def test_product_portfolio_detail_view_tab_activit_view(self):
url = self.product1.get_url("tab_activity")
response = self.client.get(url)
- self.assertContains(response, "No imports yet")
+ self.assertContains(response, "No actions yet")
self.assertContains(response, "No requests yet")
self.assertContains(response, "No changes yet")
@@ -220,7 +220,7 @@ def test_product_portfolio_detail_view_tab_activit_view(self):
self.assertTrue(response.context["has_projects_in_progress"])
htmx_refresh = 'hx-trigger="load delay:10s" hx-swap="outerHTML"'
self.assertContains(response, htmx_refresh)
- self.assertContains(response, "Imports are currently in progress.")
+ self.assertContains(response, "Actions are currently in progress.")
self.assertContains(response, "Import SBOM")
project.status = ScanCodeProject.Status.SUCCESS
@@ -229,7 +229,7 @@ def test_product_portfolio_detail_view_tab_activit_view(self):
self.assertFalse(response.context["has_projects_in_progress"])
self.assertContains(response, "Import SBOM")
self.assertNotContains(response, "hx-trigger")
- self.assertNotContains(response, "Imports are currently in progress.")
+ self.assertNotContains(response, "Actions are currently in progress.")
expected = "File:"
download_url = reverse(
@@ -243,6 +243,28 @@ def test_product_portfolio_detail_view_tab_activit_view(self):
self.assertContains(response, expected)
self.assertContains(response, download_url)
+ def test_product_portfolio_detail_view_tab_activity_in_progress_any_type(self):
+ """has_projects_in_progress is not limited to the ScanCode.io submitted types."""
+ self.client.login(username="nexb_user", password="secret")
+ url = self.product1.get_url("tab_activity")
+
+ project = ScanCodeProject.objects.create(
+ product=self.product1,
+ dataspace=self.product1.dataspace,
+ type=ScanCodeProject.ProjectType.IMPROVE_FROM_PURLDB,
+ status=ScanCodeProject.Status.IMPORT_STARTED,
+ )
+
+ response = self.client.get(url)
+ self.assertTrue(response.context["has_projects_in_progress"])
+ self.assertContains(response, "Actions are currently in progress.")
+
+ project.status = ScanCodeProject.Status.SUCCESS
+ project.save()
+ response = self.client.get(url)
+ self.assertFalse(response.context["has_projects_in_progress"])
+ self.assertNotContains(response, "Actions are currently in progress.")
+
def test_product_portfolio_detail_view_tab_dependency_view(self):
self.client.login(username="nexb_user", password="secret")
url = self.product1.get_url("tab_dependencies")
diff --git a/product_portfolio/views.py b/product_portfolio/views.py
index d837504d..9f92650f 100644
--- a/product_portfolio/views.py
+++ b/product_portfolio/views.py
@@ -1492,13 +1492,7 @@ class ProductTabActivityView(
def get_context_data(self, **kwargs):
context_data = super().get_context_data(**kwargs)
scancode_projects = self.object.scancodeprojects.all()
- submitted_projects = self.get_submitted_projects(scancode_projects)
-
- # Check the status of the "submitted" projects on ScanCode.io and update the
- # local ScanCodeProject instances accordingly.
- scancodeio = ScanCodeIO(self.request.user.dataspace)
- for submitted_project in submitted_projects:
- self.synchronize(scancodeio=scancodeio, project=submitted_project)
+ self.synchronize_scancodeio_projects(scancode_projects)
history_entries = (
History.objects.get_for_object(self.object)
@@ -1509,9 +1503,9 @@ def get_context_data(self, **kwargs):
context_data.update(
{
"tab_view_url": self.object.get_url("tab_activity"),
- # Imports
+ # Actions
"scancode_projects": scancode_projects,
- "has_projects_in_progress": bool(submitted_projects),
+ "has_projects_in_progress": scancode_projects.in_progress().exists(),
# Requests
"requests": self.object.get_requests(self.request.user),
# History
@@ -1521,20 +1515,32 @@ def get_context_data(self, **kwargs):
return context_data
- @staticmethod
- def get_submitted_projects(scancode_projects):
- submitted_types = [
+ def synchronize_scancodeio_projects(self, scancode_projects):
+ """
+ Poll ScanCode.io for the run status of the projects submitted to it as
+ external pipeline runs (SBOM and manifest imports), and update the
+ local ScanCodeProject status accordingly.
+ Other action types are handled entirely by local RQ tasks and have no
+ external run to poll.
+ """
+ scancodeio_project_types = [
ScanCodeProject.ProjectType.LOAD_SBOMS,
ScanCodeProject.ProjectType.IMPORT_FROM_MANIFEST,
]
- return [
+ pending_scancodeio_projects = [
project
for project in scancode_projects
if project.status == ScanCodeProject.Status.SUBMITTED
- and project.type in submitted_types
+ and project.type in scancodeio_project_types
]
+ if not pending_scancodeio_projects:
+ return
+
+ scancodeio = ScanCodeIO(self.request.user.dataspace)
+ for project in pending_scancodeio_projects:
+ self.synchronize_scancodeio_project_status(scancodeio, project)
- def synchronize(self, scancodeio, project):
+ def synchronize_scancodeio_project_status(self, scancodeio, project):
scan_detail_url = scancodeio.get_scan_detail_url(project.project_uuid)
scan_data = scancodeio.fetch_scan_data(scan_detail_url)
if not scan_data:
@@ -2899,7 +2905,7 @@ def improve_packages_from_purldb_view(request, dataspace, name, version=""):
messages.error(request, "Improve Packages already in progress...")
else:
transaction.on_commit(
- lambda: improve_packages_from_purldb_task(
+ lambda: improve_packages_from_purldb_task.delay(
product_uuid=product.uuid,
user_uuid=user.uuid,
)