66# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77# See https://aboutcode.org for more information about nexB OSS projects.
88#
9+ import itertools
910import logging
1011from itertools import groupby
1112from pathlib import Path
13+ from timeit import default_timer as timer
14+ from traceback import format_exc as traceback_format_exc
1215
1316import saneyaml
17+ from aboutcode .pipeline import LoopProgress
18+ from aboutcode .pipeline import humanize_time
1419from django .core .management .base import BaseCommand
1520from django .core .management .base import CommandError
1621from packageurl import PackageURL
@@ -26,7 +31,7 @@ def serialize_severity(sev):
2631 "score" : sev .value ,
2732 "scoring_system" : sev .scoring_system ,
2833 "scoring_elements" : sev .scoring_elements ,
29- "published_at" : sev .published_at ,
34+ "published_at" : str ( sev .published_at ) ,
3035 "url" : sev .url ,
3136 }
3237
@@ -88,8 +93,22 @@ def export_data(self, base_path: Path):
8893 """
8994 i = 0
9095 seen_vcid = set ()
96+ export_start_time = timer ()
9197
92- for i , (purl_without_version , package_versions ) in enumerate (packages_by_type_ns_name (), 1 ):
98+ distinct_packages_count = (
99+ Package .objects .values ("type" , "namespace" , "name" )
100+ .distinct ("type" , "namespace" , "name" )
101+ .count ()
102+ )
103+
104+ progress = LoopProgress (
105+ total_iterations = distinct_packages_count ,
106+ progress_step = 1 ,
107+ logger = self .stdout .write ,
108+ )
109+ for i , (purl_without_version , package_versions ) in enumerate (
110+ progress .iter (packages_by_type_ns_name ()), 1
111+ ):
93112 pkg_version = None
94113 try :
95114 package_urls = []
@@ -108,7 +127,11 @@ def export_data(self, base_path: Path):
108127 }
109128 package_vulnerabilities .append (package_data )
110129
111- for vuln in pkg_version .vulnerabilities :
130+ vulnerabilities = itertools .chain (
131+ pkg_version .affected_by_vulnerabilities .all (),
132+ pkg_version .fixing_vulnerabilities .all (),
133+ )
134+ for vuln in vulnerabilities :
112135 vcid = vuln .vulnerability_id
113136 # do not write twice the same file
114137 if vcid in seen_vcid :
@@ -131,9 +154,15 @@ def export_data(self, base_path: Path):
131154 self .stdout .write (f"Processed { i } package. Last PURL: { purl_without_version } " )
132155
133156 except Exception as e :
134- raise Exception (f"Failed to process Package: { pkg_version } " ) from e
157+ self .stdout .write (
158+ self .style .ERROR (
159+ f"Failed to process Package { pkg_version } : { e !r} \n { traceback_format_exc ()} "
160+ )
161+ )
135162
136163 self .stdout .write (f"Exported data for: { i } package and { len (seen_vcid )} vulnerabilities." )
164+ export_run_time = timer () - export_start_time
165+ self .stdout .write (f"Export completed in { humanize_time (export_run_time )} " )
137166
138167
139168def by_purl_type_ns_name (package ):
@@ -159,7 +188,7 @@ def packages_by_type_ns_name():
159188 "fixing_vulnerabilities__weaknesses" ,
160189 "fixing_vulnerabilities__severities" ,
161190 )
162- .paginated ()
191+ .iterator ()
163192 )
164193
165194 for tp_ns_name , packages in groupby (qs , key = by_purl_type_ns_name ):
0 commit comments