Skip to content

Commit 9885633

Browse files
committed
Fix formatting and add checksum comparison
1 parent 8edd529 commit 9885633

File tree

1 file changed

+135
-87
lines changed

1 file changed

+135
-87
lines changed

Diff for: tools/get.py

+135-87
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
import zipfile
2424
import re
2525
import time
26-
from datetime import timedelta
27-
import functools
26+
import argparse
2827

2928
# Initialize start_time globally
3029
start_time = -1
@@ -67,10 +66,12 @@ def mkdir_p(path):
6766
if exc.errno != errno.EEXIST or not os.path.isdir(path):
6867
raise
6968

69+
7070
def format_time(seconds):
7171
minutes, seconds = divmod(seconds, 60)
7272
return "{:02}:{:05.2f}".format(int(minutes), seconds)
7373

74+
7475
def report_progress(block_count, block_size, total_size, start_time):
7576
downloaded_size = block_count * block_size
7677
time_elapsed = time.time() - start_time
@@ -79,137 +80,148 @@ def report_progress(block_count, block_size, total_size, start_time):
7980
if sys.stdout.isatty():
8081
if total_size > 0:
8182
percent_complete = min((downloaded_size / total_size) * 100, 100)
82-
sys.stdout.write(f"\rDownloading... {percent_complete:.2f}% - {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {format_time(time_elapsed)} - Speed: {current_speed / 1024 / 1024:.2f} MB/s")
83+
sys.stdout.write(
84+
f"\rDownloading... {percent_complete:.2f}% - {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {format_time(time_elapsed)} - Speed: {current_speed / 1024 / 1024:.2f} MB/s" # noqa: E501
85+
)
8386
else:
84-
sys.stdout.write(f"\rDownloading... {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {format_time(time_elapsed)} - Speed: {current_speed / 1024 / 1024:.2f} MB/s")
87+
sys.stdout.write(
88+
f"\rDownloading... {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {format_time(time_elapsed)} - Speed: {current_speed / 1024 / 1024:.2f} MB/s" # noqa: E501
89+
)
8590
sys.stdout.flush()
8691

92+
8793
def print_verification_progress(total_files, i, t1):
8894
if sys.stdout.isatty():
89-
sys.stdout.write(f'\rElapsed time {format_time(time.time() - t1)}')
95+
sys.stdout.write(f"\rElapsed time {format_time(time.time() - t1)}")
9096
sys.stdout.flush()
9197

98+
9299
def verify_files(filename, destination, rename_to):
93100
# Set the path of the extracted directory
94101
extracted_dir_path = destination
95102
t1 = time.time()
96103
if filename.endswith(".zip"):
97104
try:
98-
with zipfile.ZipFile(filename, 'r') as archive:
99-
first_dir = archive.namelist()[0].split('/')[0]
105+
with zipfile.ZipFile(filename, "r") as archive:
106+
first_dir = archive.namelist()[0].split("/")[0]
100107
total_files = len(archive.namelist())
101108
for i, zipped_file in enumerate(archive.namelist(), 1):
102109
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
103110
if not os.path.exists(local_path):
104-
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
111+
# print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
105112
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
106113
return False
107-
print_verification_progress(total_files, i , t1)
114+
print_verification_progress(total_files, i, t1)
108115
except zipfile.BadZipFile:
109116
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
110117
return False
111118
elif filename.endswith(".tar.gz"):
112119
try:
113-
with tarfile.open(filename, 'r:gz') as archive:
114-
first_dir = archive.getnames()[0].split('/')[0]
120+
with tarfile.open(filename, "r:gz") as archive:
121+
first_dir = archive.getnames()[0].split("/")[0]
115122
total_files = len(archive.getnames())
116123
for i, zipped_file in enumerate(archive.getnames(), 1):
117124
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
118125
if not os.path.exists(local_path):
119-
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
126+
# print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
120127
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
121128
return False
122-
print_verification_progress(total_files, i , t1)
129+
print_verification_progress(total_files, i, t1)
123130
except tarfile.ReadError:
124131
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
125132
return False
126133
elif filename.endswith(".tar.xz"):
127134
try:
128-
with tarfile.open(filename, 'r:xz') as archive:
129-
first_dir = archive.getnames()[0].split('/')[0]
135+
with tarfile.open(filename, "r:xz") as archive:
136+
first_dir = archive.getnames()[0].split("/")[0]
130137
total_files = len(archive.getnames())
131138
for i, zipped_file in enumerate(archive.getnames(), 1):
132139
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
133140
if not os.path.exists(local_path):
134-
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
141+
print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
135142
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
136143
return False
137-
print_verification_progress(total_files, i , t1)
144+
print_verification_progress(total_files, i, t1)
138145
except tarfile.ReadError:
139146
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
140147
return False
141148
else:
142-
raise NotImplementedError('Unsupported archive type')
149+
raise NotImplementedError("Unsupported archive type")
143150

144-
#if(verbose):
145-
#print(f"\nVerification passed; completed in {format_time(time.time() - t1)}")
151+
# if(verbose):
152+
# print(f"\nVerification passed; completed in {format_time(time.time() - t1)}")
146153
return True
147154

148155

149156
def unpack(filename, destination, force_extract):
150-
dirname = ''
151-
file_is_corrupted=False
152-
if(not force_extract):
153-
print(f' > Verify archive... ', end="", flush=True)
157+
dirname = ""
158+
cfile = None # Compressed file
159+
file_is_corrupted = False
160+
if not force_extract:
161+
print(" > Verify archive... ", end="", flush=True)
154162

155163
try:
156-
if filename.endswith('tar.gz'):
164+
if filename.endswith("tar.gz"):
157165
if tarfile.is_tarfile(filename):
158-
tfile = tarfile.open(filename, 'r:gz')
159-
dirname = tfile.getnames()[0]
166+
cfile = tarfile.open(filename, "r:gz")
167+
dirname = cfile.getnames()[0]
160168
else:
161-
print('File corrupted!')
162-
file_is_corrupted=True
163-
elif filename.endswith('tar.xz'):
169+
print("File corrupted!")
170+
file_is_corrupted = True
171+
elif filename.endswith("tar.xz"):
164172
if tarfile.is_tarfile(filename):
165-
tfile = tarfile.open(filename, 'r:xz')
166-
dirname = tfile.getnames()[0]
173+
cfile = tarfile.open(filename, "r:xz")
174+
dirname = cfile.getnames()[0]
167175
else:
168-
print('File corrupted!')
169-
file_is_corrupted=True
170-
elif filename.endswith('zip'):
176+
print("File corrupted!")
177+
file_is_corrupted = True
178+
elif filename.endswith("zip"):
171179
if zipfile.is_zipfile(filename):
172-
zfile = zipfile.ZipFile(filename)
173-
dirname = zfile.namelist()[0]
180+
cfile = zipfile.ZipFile(filename)
181+
dirname = cfile.namelist()[0]
174182
else:
175-
print('File corrupted!')
176-
file_is_corrupted=True
183+
print("File corrupted!")
184+
file_is_corrupted = True
177185
else:
178-
raise NotImplementedError('Unsupported archive type')
186+
raise NotImplementedError("Unsupported archive type")
179187
except EOFError:
180-
print(f'File corrupted or incomplete!')
181-
file_is_corrupted=True
188+
print("File corrupted or incomplete!")
189+
cfile = None
190+
file_is_corrupted = True
182191

183-
if(file_is_corrupted):
192+
if file_is_corrupted:
184193
corrupted_filename = filename + ".corrupted"
185194
os.rename(filename, corrupted_filename)
186-
if(verbose):
187-
print(f'Renaming corrupted archive to {corrupted_filename}')
195+
if verbose:
196+
print(f"Renaming corrupted archive to {corrupted_filename}")
188197
return False
189198

190199
# A little trick to rename tool directories so they don't contain version number
191-
rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).strip('-')
192-
if rename_to == dirname and dirname.startswith('esp32-arduino-libs-'):
193-
rename_to = 'esp32-arduino-libs'
200+
rename_to = re.match(r"^([a-z][^\-]*\-*)+", dirname).group(0).strip("-")
201+
if rename_to == dirname and dirname.startswith("esp32-arduino-libs-"):
202+
rename_to = "esp32-arduino-libs"
194203

195204
if not force_extract:
196-
if(verify_files(filename, destination, rename_to)):
205+
if verify_files(filename, destination, rename_to):
197206
print(" Files ok. Skipping Extraction")
198207
return True
199208
else:
200209
print(" Extracting archive...")
201210
else:
202211
print(" Forcing extraction")
203212

204-
if filename.endswith('tar.gz'):
205-
tfile = tarfile.open(filename, 'r:gz')
206-
tfile.extractall(destination)
207-
elif filename.endswith('tar.xz'):
208-
tfile = tarfile.open(filename, 'r:xz')
209-
tfile.extractall(destination)
210-
elif filename.endswith('zip'):
211-
zfile = zipfile.ZipFile(filename)
212-
zfile.extractall(destination)
213+
if filename.endswith("tar.gz"):
214+
if not cfile:
215+
cfile = tarfile.open(filename, "r:gz")
216+
cfile.extractall(destination)
217+
elif filename.endswith("tar.xz"):
218+
if not cfile:
219+
cfile = tarfile.open(filename, "r:xz")
220+
cfile.extractall(destination)
221+
elif filename.endswith("zip"):
222+
if not cfile:
223+
cfile = zipfile.ZipFile(filename)
224+
cfile.extractall(destination)
213225
else:
214226
raise NotImplementedError("Unsupported archive type")
215227

@@ -221,7 +233,8 @@ def unpack(filename, destination, force_extract):
221233

222234
return True
223235

224-
def download_file_with_progress(url,filename, start_time):
236+
237+
def download_file_with_progress(url, filename, start_time):
225238
import ssl
226239
import contextlib
227240

@@ -246,7 +259,7 @@ def download_file_with_progress(url,filename, start_time):
246259
block_count += 1
247260
report_progress(block_count, block_size, total_size, start_time)
248261
else:
249-
raise Exception('Non-existing file or connection error')
262+
raise Exception("Non-existing file or connection error")
250263

251264

252265
def download_file(url, filename):
@@ -268,19 +281,21 @@ def download_file(url, filename):
268281
break
269282
out_file.write(block)
270283
else:
271-
raise Exception ('Non-existing file or connection error')
284+
raise Exception("Non-existing file or connection error")
285+
272286

273287
def get_tool(tool, force_download, force_extract):
274288
sys_name = platform.system()
275289
archive_name = tool["archiveFileName"]
290+
checksum = tool["checksum"][8:]
276291
local_path = dist_dir + archive_name
277-
url = tool['url']
292+
url = tool["url"]
278293
start_time = time.time()
279294
if not os.path.isfile(local_path) or force_download:
280295
if verbose:
281-
print('Downloading \'' + archive_name + '\' to \'' + local_path + '\'')
296+
print("Downloading '" + archive_name + "' to '" + local_path + "'")
282297
else:
283-
print('Downloading \'' + archive_name + '\' ...')
298+
print("Downloading '" + archive_name + "' ...")
284299
sys.stdout.flush()
285300
if "CYGWIN_NT" in sys_name:
286301
import ssl
@@ -301,14 +316,19 @@ def get_tool(tool, force_download, force_extract):
301316
else:
302317
try:
303318
urlretrieve(url, local_path, report_progress)
304-
except:
319+
except: # noqa: E722
305320
download_file_with_progress(url, local_path, start_time)
306321
sys.stdout.write(" - Done\n")
307322
sys.stdout.flush()
308323
else:
309324
print("Tool {0} already downloaded".format(archive_name))
310325
sys.stdout.flush()
311-
return unpack(local_path, '.', force_extract)
326+
327+
if sha256sum(local_path) != checksum:
328+
print("Checksum mismatch for {0}".format(archive_name))
329+
return False
330+
331+
return unpack(local_path, ".", force_extract)
312332

313333

314334
def load_tools_list(filename, platform):
@@ -355,29 +375,55 @@ def identify_platform():
355375
print("System: %s, Bits: %d, Info: %s" % (sys_name, bits, sys_platform))
356376
return arduino_platform_names[sys_name][bits]
357377

358-
def print_help():
359-
print("TODO help")
360378

361-
if __name__ == '__main__':
362-
option_print_help = "-h" in sys.argv
363-
verbose = "-v" in sys.argv
364-
force_download = "-d" in sys.argv
365-
force_extract = "-e" in sys.argv
366-
force_all = "-f" in sys.argv
367-
is_test = "-t" in sys.argv
379+
if __name__ == "__main__":
380+
parser = argparse.ArgumentParser(description="Download and extract tools")
381+
382+
parser.add_argument("-v", "--verbose",
383+
type=bool,
384+
default=False,
385+
required=False,
386+
help="Print verbose output")
387+
388+
parser.add_argument("-d", "--force_download",
389+
type=bool,
390+
default=False,
391+
required=False,
392+
help="Force download of tools")
393+
394+
parser.add_argument("-e", "--force_extract",
395+
type=bool,
396+
default=False,
397+
required=False,
398+
help="Force extraction of tools")
399+
400+
parser.add_argument("-f", "--force_all",
401+
type=bool,
402+
default=False,
403+
required=False,
404+
help="Force download and extraction of tools")
405+
406+
parser.add_argument("-t", "--test",
407+
type=bool,
408+
default=False,
409+
required=False,
410+
help=argparse.SUPPRESS)
411+
412+
args = parser.parse_args()
368413

369-
print(f'Debug: options values: option_print_help={option_print_help}; verbose={verbose}; force_download={force_download}; force_extract={force_extract}; force_all={force_all}; is_test={is_test};')
370-
if option_print_help:
371-
print_help()
372-
sys.exit()
414+
verbose = args.verbose
415+
force_download = args.force_download
416+
force_extract = args.force_extract
417+
force_all = args.force_all
418+
is_test = args.test
373419

374420
if is_test and (force_download or force_extract or force_all):
375-
print('Cannot combine test (-t) and forced execution (-d | -e | -f)')
376-
print_help()
377-
sys.exit()
421+
print("Cannot combine test (-t) and forced execution (-d | -e | -f)")
422+
parser.print_help(sys.stderr)
423+
sys.exit(1)
378424

379425
if is_test:
380-
print('Test run!')
426+
print("Test run!")
381427

382428
if force_all:
383429
force_download = True
@@ -393,9 +439,11 @@ def print_help():
393439
if is_test:
394440
print("Would install: {0}".format(tool["archiveFileName"]))
395441
else:
396-
if(not get_tool(tool, force_download, force_extract)):
397-
if(verbose):
442+
if not get_tool(tool, force_download, force_extract):
443+
if verbose:
398444
print(f"Tool {tool['archiveFileName']} was corrupted. Re-downloading...\n")
399-
if(not get_tool(tool, True, force_extract)): # Corrupted file was renamed, will not be found and will be re-downloaded
445+
if not get_tool(
446+
tool, True, force_extract
447+
): # Corrupted file was renamed, will not be found and will be re-downloaded
400448
print(f"Tool {tool['archiveFileName']} was corrupted, but re-downloading did not help!\n")
401-
print('Platform Tools Installed')
449+
print("Platform Tools Installed")

0 commit comments

Comments
 (0)