| 
16 | 16 | from functools import cached_property  | 
17 | 17 | from itertools import groupby  | 
18 | 18 | from operator import attrgetter  | 
 | 19 | +from traceback import format_exc as traceback_format_exc  | 
 | 20 | +from typing import List  | 
19 | 21 | from typing import Union  | 
20 | 22 | from urllib.parse import urljoin  | 
21 | 23 | 
 
  | 
@@ -3067,6 +3069,41 @@ def get_or_create_from_purl(self, purl: Union[PackageURL, str]):  | 
3067 | 3069 | 
 
  | 
3068 | 3070 |         return package, is_created  | 
3069 | 3071 | 
 
  | 
 | 3072 | +    def bulk_get_or_create_from_purls(self, purls: List[Union[PackageURL, str]]):  | 
 | 3073 | +        """  | 
 | 3074 | +        Return new or existing Packages given ``purls`` list of PackageURL object or PURL string.  | 
 | 3075 | +        """  | 
 | 3076 | +        purl_strings = [str(p) for p in purls]  | 
 | 3077 | +        existing_packages = PackageV2.objects.filter(package_url__in=purl_strings)  | 
 | 3078 | +        existing_purls = set(existing_packages.values_list("package_url", flat=True))  | 
 | 3079 | + | 
 | 3080 | +        all_packages = list(existing_packages)  | 
 | 3081 | +        packages_to_create = []  | 
 | 3082 | +        for purl in purls:  | 
 | 3083 | +            if str(purl) in existing_purls:  | 
 | 3084 | +                continue  | 
 | 3085 | + | 
 | 3086 | +            purl_dict = purl_to_dict(purl)  | 
 | 3087 | +            purl = PackageURL(**purl_dict)  | 
 | 3088 | + | 
 | 3089 | +            normalized = normalize_purl(purl=purl)  | 
 | 3090 | +            for name, value in purl_to_dict(normalized).items():  | 
 | 3091 | +                setattr(self, name, value)  | 
 | 3092 | + | 
 | 3093 | +            purl_dict["package_url"] = str(normalized)  | 
 | 3094 | +            purl_dict["plain_package_url"] = str(utils.plain_purl(normalized))  | 
 | 3095 | + | 
 | 3096 | +            packages_to_create.append(PackageV2(**purl_dict))  | 
 | 3097 | + | 
 | 3098 | +        try:  | 
 | 3099 | +            new_packages = PackageV2.objects.bulk_create(packages_to_create)  | 
 | 3100 | +        except Exception as e:  | 
 | 3101 | +            logging.error(f"Error creating PackageV2: {e} \n {traceback_format_exc()}")  | 
 | 3102 | +            return []  | 
 | 3103 | + | 
 | 3104 | +        all_packages.extend(new_packages)  | 
 | 3105 | +        return all_packages  | 
 | 3106 | + | 
3070 | 3107 |     def only_vulnerable(self):  | 
3071 | 3108 |         return self._vulnerable(True)  | 
3072 | 3109 | 
 
  | 
 | 
0 commit comments