11"""Parse metadata from .dist-info directories in a wheelhouse."""
22
3+ import aiohttp
4+ import asyncio
35import click
46import glob
7+ import hashlib
58import json
69import os .path
7- import aiohttp
8- import asyncio
910
1011from pypi2nix .utils import TO_IGNORE , safe
1112
@@ -92,7 +93,7 @@ async def fetch_metadata(session, url):
9293 return await response .json ()
9394
9495
95- def fetch_all_metadata (packages , index = INDEX_URL ):
96+ def fetch_all_metadata (cache_dir , packages , index = INDEX_URL ):
9697 """Yield JSON information obtained from PyPI index given an iterable of
9798 package names.
9899 """
@@ -101,18 +102,26 @@ def fetch_all_metadata(packages, index=INDEX_URL):
101102 with aiohttp .ClientSession (loop = loop , connector = conn ) as session :
102103 for package in packages :
103104 url = "{}/{}/json" .format (index , package ['name' ])
104- yield combine_metadata (package , loop .run_until_complete (fetch_metadata (session , url )))
105+ yield combine_metadata (cache_dir , session , loop , package , loop .run_until_complete (fetch_metadata (session , url )))
105106 loop .close ()
106107
107108
108- def combine_metadata (old , new ):
109+ async def download_file (session , url , filename , chunk_size = 1024 ):
110+ async with session .get (url ) as resp :
111+ with open (filename , 'wb' ) as f :
112+ while True :
113+ chunk = await resp .content .read (chunk_size )
114+ if not chunk :
115+ break
116+ f .write (chunk )
117+
118+
119+ def combine_metadata (cache_dir , session , loop , old , new ):
109120 if not new .get ('releases' ):
110121 raise click .ClickException (
111122 "Unable to find releases for packge {name}" .format (** old ))
112123
113124 if not new ['releases' ].get (old ['version' ]):
114- import pdb
115- pdb .set_trace ()
116125 raise click .ClickException (
117126 "Unable to find releases for package {name} of version "
118127 "{version}" .format (** old ))
@@ -125,12 +134,20 @@ def combine_metadata(old, new):
125134 release = dict ()
126135 release ['url' ] = possible_release ['url' ]
127136 digests = possible_release .get ('digests' )
137+ release ['hash_type' ] = 'sha256'
128138 if digests :
129- release ['hash_type' ] = 'sha256'
130139 release ['hash_value' ] = possible_release ['digests' ]['sha256' ] # noqa
131140 else :
132- release ['hash_type' ] = 'md5'
133- release ['hash_value' ] = possible_release ['md5_digest' ]
141+ # download file if it doens not already exists
142+ filename = os .path .join (
143+ cache_dir , possible_release ['filename' ])
144+ if not os .path .exists (filename ):
145+ loop .run_until_complete (download_file (session , possible_release ['url' ], filename ))
146+
147+ # calculate sha256
148+ with open (filename , 'rb' ) as f :
149+ release ['hash_value' ] = hashlib .sha256 (f .read ()).hexdigest ()
150+
134151 if release :
135152 break
136153 if release :
@@ -146,7 +163,7 @@ def combine_metadata(old, new):
146163 return old
147164
148165
149- def main (wheels ):
166+ def main (wheels , cache_dir ):
150167 """Extract packages metadata from wheels dist-info folders.
151168 """
152169
@@ -157,4 +174,4 @@ def main(wheels):
157174 if wheel_metadata :
158175 wheels_metadata .append (wheel_metadata )
159176
160- return list (fetch_all_metadata (wheels_metadata ))
177+ return list (fetch_all_metadata (cache_dir , wheels_metadata ))
0 commit comments