From 761d85a8d8e1d89d93e5c96a0aec397e669473cb Mon Sep 17 00:00:00 2001 From: Om Santosh Suneri <142336291+omsuneri@users.noreply.github.com> Date: Sun, 12 Oct 2025 00:29:21 +0530 Subject: [PATCH] feat: setting PURL in project settings if input is package URL Signed-off-by: Om Santosh Suneri <142336291+omsuneri@users.noreply.github.com> --- scanpipe/api/views.py | 2 ++ scanpipe/forms.py | 2 ++ scanpipe/management/commands/__init__.py | 2 ++ scanpipe/models.py | 38 +++++++++++++++++++++++- 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/scanpipe/api/views.py b/scanpipe/api/views.py index c46eaebbdf..fb080ebfb0 100644 --- a/scanpipe/api/views.py +++ b/scanpipe/api/views.py @@ -373,6 +373,8 @@ def add_input(self, request, *args, **kwargs): for url in input_urls: project.add_input_source(download_url=url) + project.auto_populate_purl_if_single_package_url() + return Response({"status": "Input(s) added."}, status=status.HTTP_201_CREATED) @action( diff --git a/scanpipe/forms.py b/scanpipe/forms.py index f9f46da67c..8999671673 100644 --- a/scanpipe/forms.py +++ b/scanpipe/forms.py @@ -124,6 +124,8 @@ def handle_inputs(self, project): for url in input_urls: project.add_input_source(download_url=url) + project.auto_populate_purl_if_single_package_url() + class CheckboxChoiceField(forms.MultipleChoiceField): widget = forms.CheckboxSelectMultiple diff --git a/scanpipe/management/commands/__init__.py b/scanpipe/management/commands/__init__.py index 57b74e1394..6f59147732 100644 --- a/scanpipe/management/commands/__init__.py +++ b/scanpipe/management/commands/__init__.py @@ -357,6 +357,8 @@ def handle_input_urls(project, input_urls, command=None): for url in input_urls: project.add_input_source(download_url=url) + project.auto_populate_purl_if_single_package_url() + if input_urls and command and command.verbosity > 0: msg = "URL(s) added as project input sources:" command.stdout.write(msg, command.style.SUCCESS) diff --git a/scanpipe/models.py b/scanpipe/models.py index 26d74303cb..100cff11b6 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -1222,7 +1222,7 @@ def add_input_source(self, download_url="", filename="", is_uploaded=False, tag= if not tag and parsed_url.fragment: tag = parsed_url.fragment[:50] - return InputSource.objects.create( + input_source = InputSource.objects.create( project=self, download_url=download_url, filename=filename, @@ -1230,6 +1230,42 @@ def add_input_source(self, download_url="", filename="", is_uploaded=False, tag= tag=tag, ) + self._auto_populate_purl_from_inputs() + + return input_source + + def _auto_populate_purl_from_inputs(self): + """ + Auto-populate the project's PURL field if the project has a single input + that is a valid package URL and the PURL field is currently empty. + """ + if self.purl: + return + + input_sources = self.inputsources.all() + + if input_sources.count() != 1: + return + + input_source = input_sources.first() + download_url = input_source.download_url + + if download_url and download_url.startswith('pkg:'): + try: + PackageURL.from_string(download_url) + self.purl = download_url + self.save(update_fields=['purl']) + except ValueError: + # Ignore + pass + + def auto_populate_purl_if_single_package_url(self): + """ + Public method to auto-populate PURL field if project has a single package URL input. + This can be called after all inputs have been added to a project. + """ + self._auto_populate_purl_from_inputs() + def add_downloads(self, downloads): """ Move the given `downloads` to the current project's input/ directory and