4343@dataclasses .dataclass
4444class UbuntuConfiguration (DataSourceConfiguration ):
4545 releases : list
46+ etags : dict
4647
4748
4849class UbuntuDataSource (OvalDataSource ):
@@ -62,15 +63,32 @@ def _fetch(self):
6263 file_name = 'com.ubuntu.{}.cve.oval.xml.bz2'
6364 releases = self .config .releases
6465 for release in releases :
65- print ("getting " , release )
66- resp = requests .get (base_url + file_name .format (release ))
66+ file_url = base_url + file_name .format (release )
67+ if not self .create_etag (file_url ):
68+ continue
69+ resp = requests .get (file_url )
6770 extracted = bz2 .decompress (resp .content )
68- print ("done " )
69- yield ({'type' : 'deb' }, ET .ElementTree (ET .fromstring (extracted .decode ('utf-8' ))))
71+ yield (
72+ {'type' : 'deb' , 'namespace' : 'ubuntu' },
73+ ET .ElementTree (ET .fromstring (extracted .decode ('utf-8' )))
74+ )
7075
7176 def set_api (self , packages ):
7277 asyncio .run (self .pkg_manager_api .load_api (packages ))
7378
79+ def create_etag (self , url ):
80+
81+ etag = requests .head (url ).headers .get ('ETag' )
82+ if not etag :
83+ # Kind of inaccurate to return True since etag is
84+ # not created
85+ return True
86+ elif url in self .config .etags :
87+ if self .config .etags [url ] == etag :
88+ return False
89+ self .config .etags [url ] = etag
90+ return True
91+
7492
7593class VersionAPI :
7694 def __init__ (self , cache : Mapping [str , Set [str ]] = None ):
@@ -80,13 +98,13 @@ def get(self, package_name: str) -> Set[str]:
8098 return self .cache [package_name ]
8199
82100 async def load_api (self , pkg_set ):
83- # This is debatable
84- timeout = ClientTimeout (total = None )
85- async with ClientSession (raise_for_status = True , timeout = timeout ) as session :
101+ async with ClientSession (raise_for_status = True ) as session :
86102 await asyncio .gather (* [self .set_api (pkg , session )
87103 for pkg in pkg_set if pkg not in self .cache ])
88104
89105 async def set_api (self , pkg , session ):
106+ if pkg in self .cache :
107+ return
90108 url = ('https://api.launchpad.net/1.0/ubuntu/+archive/'
91109 'primary?ws.op=getPublishedSources&'
92110 'source_name={}&exact_match=true' .format (pkg ))
@@ -105,5 +123,5 @@ async def set_api(self, pkg, session):
105123 else :
106124 break
107125 self .cache [pkg ] = all_versions
108- except ClientResponseError :
126+ except ( ClientResponseError , asyncio . exceptions . TimeoutError ) :
109127 self .cache [pkg ] = {}
0 commit comments