Skip to content

Commit 3670c8b

Browse files
PilnyTomasme-no-dev
authored andcommitted
Updates
1 parent 96d13bb commit 3670c8b

File tree

1 file changed

+122
-56
lines changed

1 file changed

+122
-56
lines changed

tools/get.py

Lines changed: 122 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
import zipfile
2424
import re
2525
import time
26+
from datetime import timedelta
27+
import functools
28+
29+
# Initialize start_time globally
30+
start_time = -1
2631

2732
if sys.version_info[0] == 3:
2833
from urllib.request import urlretrieve
@@ -60,26 +65,38 @@ def mkdir_p(path):
6065
raise
6166

6267
def report_progress(block_count, block_size, total_size):
68+
global start_time
6369
downloaded_size = block_count * block_size
64-
current_speed = downloaded_size / (time.time() - start_time)
6570
time_elapsed = time.time() - start_time
71+
current_speed = downloaded_size / (time_elapsed)
72+
elapsed = timedelta(seconds=time_elapsed)
73+
74+
hours, remainder = divmod(time_elapsed, 3600) # 3600 seconds in an hour
75+
minutes, remainder = divmod(remainder, 60)
76+
seconds, milliseconds = divmod(remainder, 1)
77+
formatted_time = "{:02}:{:02}:{:02}.{:03}".format(int(hours), int(minutes), int(seconds), int(milliseconds*1000))
6678

6779
if sys.stdout.isatty():
6880
if total_size > 0:
6981
percent_complete = min((downloaded_size / total_size) * 100, 100)
70-
sys.stdout.write(f"\rDownloading... {percent_complete:.2f}% - {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {time_elapsed:.2f} seconds - Speed: {current_speed / 1024 / 1024:.2f} MB/s")
82+
sys.stdout.write(f"\rDownloading... {percent_complete:.2f}% - {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {formatted_time} - Speed: {current_speed / 1024 / 1024:.2f} MB/s")
83+
else:
84+
sys.stdout.write(f"\rDownloading... {downloaded_size / 1024 / 1024:.2f} MB downloaded - Elapsed Time: {formatted_time} - Speed: {current_speed / 1024 / 1024:.2f} MB/s")
7185
sys.stdout.flush()
7286

7387
def format_time(seconds):
7488
minutes, seconds = divmod(seconds, 60)
7589
return "{:02}:{:05.2f}".format(int(minutes), seconds)
7690

91+
def print_verification_progress(total_files, i, t1):
92+
if sys.stdout.isatty():
93+
sys.stdout.write(f'\rElapsed time {format_time(time.time() - t1)}')
94+
sys.stdout.flush()
95+
7796
def verify_files(filename, destination, rename_to):
7897
# Set the path of the extracted directory
7998
extracted_dir_path = destination
80-
8199
t1 = time.time()
82-
83100
if filename.endswith(".zip"):
84101
try:
85102
with zipfile.ZipFile(filename, 'r') as archive:
@@ -88,15 +105,12 @@ def verify_files(filename, destination, rename_to):
88105
for i, zipped_file in enumerate(archive.namelist(), 1):
89106
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
90107
if not os.path.exists(local_path):
91-
print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
108+
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
92109
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
93110
return False
94-
#print(f'\rVerification progress: {i/total_files*100:.2f}%', end='')
95-
if sys.stdout.isatty():
96-
sys.stdout.write(f'\rVerification progress: {i/total_files*100:.2f}%')
97-
sys.stdout.flush()
111+
print_verification_progress(total_files, i , t1)
98112
except zipfile.BadZipFile:
99-
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
113+
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
100114
return False
101115
elif filename.endswith(".tar.gz"):
102116
try:
@@ -106,15 +120,12 @@ def verify_files(filename, destination, rename_to):
106120
for i, zipped_file in enumerate(archive.getnames(), 1):
107121
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
108122
if not os.path.exists(local_path):
109-
print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
110-
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
123+
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
124+
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
111125
return False
112-
#print(f'\rVerification progress: {i/total_files*100:.2f}%', end='')
113-
if sys.stdout.isatty():
114-
sys.stdout.write(f'\rVerification progress: {i/total_files*100:.2f}%')
115-
sys.stdout.flush()
126+
print_verification_progress(total_files, i , t1)
116127
except tarfile.ReadError:
117-
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
128+
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
118129
return False
119130
elif filename.endswith(".tar.xz"):
120131
try:
@@ -124,63 +135,86 @@ def verify_files(filename, destination, rename_to):
124135
for i, zipped_file in enumerate(archive.getnames(), 1):
125136
local_path = os.path.join(extracted_dir_path, zipped_file.replace(first_dir, rename_to, 1))
126137
if not os.path.exists(local_path):
127-
print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
128-
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
138+
#print(f'\nMissing {zipped_file} on location: {extracted_dir_path}')
139+
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
129140
return False
130-
#print(f'\rVerification progress: {i/total_files*100:.2f}%', end='')
131-
if sys.stdout.isatty():
132-
sys.stdout.write(f'\rVerification progress: {i/total_files*100:.2f}%')
133-
sys.stdout.flush()
141+
print_verification_progress(total_files, i , t1)
134142
except tarfile.ReadError:
135-
print(f"\nVerification failed; aborted in {format_time(time.time() - t1)}")
143+
print(f"Verification failed; aborted in {format_time(time.time() - t1)}")
136144
return False
137145
else:
138146
raise NotImplementedError('Unsupported archive type')
139147

140-
if(verobse):
141-
print(f"\nVerification passed; completed in {format_time(time.time() - t1)}")
142-
148+
#if(verbose):
149+
#print(f"\nVerification passed; completed in {format_time(time.time() - t1)}")
143150
return True
144151

145-
def unpack(filename, destination):
152+
153+
def unpack(filename, destination, force_extract):
146154
dirname = ''
147-
print(' > Verify... ')
155+
file_is_corrupted=False
156+
if(not force_extract):
157+
print(f' > Verify... ', end="", flush=True)
148158

149-
if filename.endswith('tar.gz'):
150-
tfile = tarfile.open(filename, 'r:gz')
151-
dirname = tfile.getnames()[0]
152-
elif filename.endswith('tar.xz'):
153-
tfile = tarfile.open(filename, 'r:xz')
154-
dirname = tfile.getnames()[0]
155-
elif filename.endswith('zip'):
156-
zfile = zipfile.ZipFile(filename)
157-
dirname = zfile.namelist()[0]
158-
else:
159-
raise NotImplementedError('Unsupported archive type')
159+
try:
160+
if filename.endswith('tar.gz'):
161+
if tarfile.is_tarfile(filename):
162+
tfile = tarfile.open(filename, 'r:gz')
163+
dirname = tfile.getnames()[0]
164+
else:
165+
print('File corrupted!')
166+
file_is_corrupted=True
167+
elif filename.endswith('tar.xz'):
168+
if tarfile.is_tarfile(filename):
169+
tfile = tarfile.open(filename, 'r:xz')
170+
dirname = tfile.getnames()[0]
171+
else:
172+
print('File corrupted!')
173+
file_is_corrupted=True
174+
elif filename.endswith('zip'):
175+
if zipfile.is_zipfile(filename):
176+
zfile = zipfile.ZipFile(filename)
177+
dirname = zfile.namelist()[0]
178+
else:
179+
print('File corrupted!')
180+
file_is_corrupted=True
181+
else:
182+
raise NotImplementedError('Unsupported archive type')
183+
except EOFError:
184+
print(f'File corrupted or incomplete!')
185+
file_is_corrupted=True
186+
187+
if(file_is_corrupted):
188+
corrupted_filename = filename + ".corrupted"
189+
os.rename(filename, corrupted_filename)
190+
if(verbose):
191+
print(f'Renaming corrupted archive to {corrupted_filename}')
192+
return False
160193

161194
# A little trick to rename tool directories so they don't contain version number
162195
rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).strip('-')
163196
if rename_to == dirname and dirname.startswith('esp32-arduino-libs-'):
164197
rename_to = 'esp32-arduino-libs'
165198

166-
if(verify_files(filename, destination, rename_to)):
167-
print(" Files ok. Skipping Extraction")
168-
return
199+
if not force_extract:
200+
now = time.time()
201+
if(verify_files(filename, destination, rename_to, now)):
202+
print(" Files ok. Skipping Extraction")
203+
return True
204+
else:
205+
print(" Failed. extracting")
169206
else:
170-
print(" Failed. extracting")
207+
print(" Forcing extraction")
171208

172209
if filename.endswith('tar.gz'):
173210
tfile = tarfile.open(filename, 'r:gz')
174211
tfile.extractall(destination)
175-
dirname = tfile.getnames()[0]
176212
elif filename.endswith('tar.xz'):
177213
tfile = tarfile.open(filename, 'r:xz')
178214
tfile.extractall(destination)
179-
dirname = tfile.getnames()[0]
180215
elif filename.endswith('zip'):
181216
zfile = zipfile.ZipFile(filename)
182217
zfile.extractall(destination)
183-
dirname = zfile.namelist()[0]
184218
else:
185219
raise NotImplementedError('Unsupported archive type')
186220

@@ -214,7 +248,7 @@ def download_file_with_progress(url,filename):
214248
block_count += 1
215249
report_progress(block_count, block_size, total_size)
216250
else:
217-
raise Exception ('nonexisting file or connection error')
251+
raise Exception('Non-existing file or connection error')
218252

219253
def download_file(url,filename):
220254
import ssl
@@ -234,15 +268,20 @@ def download_file(url,filename):
234268
break
235269
out_file.write(block)
236270
else:
237-
raise Exception ('nonexisting file or connection error')
271+
raise Exception ('Non-existing file or connection error')
238272

239-
def get_tool(tool):
273+
def get_tool(tool, force_download, force_extract):
274+
global start_time
240275
sys_name = platform.system()
241276
archive_name = tool['archiveFileName']
242277
local_path = dist_dir + archive_name
243278
url = tool['url']
244-
if not os.path.isfile(local_path):
245-
print('Downloading ' + archive_name + ' ...')
279+
start_time = time.time()
280+
if not os.path.isfile(local_path) or force_download:
281+
if verbose:
282+
print('Downloading \'' + archive_name + '\' to \'' + local_path + '\'')
283+
else:
284+
print('Downloading \'' + archive_name + '\' ...')
246285
sys.stdout.flush()
247286
if 'CYGWIN_NT' in sys_name:
248287
import ssl
@@ -264,12 +303,12 @@ def get_tool(tool):
264303
urlretrieve(url, local_path, report_progress)
265304
except:
266305
download_file_with_progress(url, local_path)
267-
sys.stdout.write("\rDone \n")
306+
sys.stdout.write(" - Done\n")
268307
sys.stdout.flush()
269308
else:
270309
print('Tool {0} already downloaded'.format(archive_name))
271310
sys.stdout.flush()
272-
unpack(local_path, '.')
311+
return unpack(local_path, '.', force_extract)
273312

274313
def load_tools_list(filename, platform):
275314
tools_info = json.load(open(filename))['packages'][0]['tools']
@@ -312,11 +351,34 @@ def identify_platform():
312351
print('System: %s, Bits: %d, Info: %s' % (sys_name, bits, sys_platform))
313352
return arduino_platform_names[sys_name][bits]
314353

354+
def print_help():
355+
print("TODO help")
356+
315357
if __name__ == '__main__':
358+
option_print_help = "-h" in sys.argv
316359
verbose = "-v" in sys.argv
317-
is_test = (len(sys.argv) > 1 and sys.argv[1] == '-h')
360+
force_download = "-d" in sys.argv
361+
force_extract = "-e" in sys.argv
362+
force_all = "-f" in sys.argv
363+
is_test = "-t" in sys.argv
364+
365+
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};')
366+
if option_print_help:
367+
print_help()
368+
sys.exit()
369+
370+
if is_test and (force_download or force_extract or force_all):
371+
print('Cannot combine test (-t) and forced execution (-d | -e | -f)')
372+
print_help()
373+
sys.exit()
374+
318375
if is_test:
319376
print('Test run!')
377+
378+
if force_all:
379+
force_download = True
380+
force_extract = True
381+
320382
identified_platform = identify_platform()
321383
print('Platform: {0}'.format(identified_platform))
322384
tools_to_download = load_tools_list(current_dir + '/../package/package_esp32_index.template.json', identified_platform)
@@ -325,5 +387,9 @@ def identify_platform():
325387
if is_test:
326388
print('Would install: {0}'.format(tool['archiveFileName']))
327389
else:
328-
get_tool(tool)
390+
if(not get_tool(tool, force_download, force_extract)):
391+
if(verbose):
392+
print(f"Tool {tool['archiveFileName']} was corrupted. Re-downloading...\n")
393+
if(not get_tool(tool, force_download, force_extract)): # Corrupted file was renamed, will not be found and will be re-downloaded
394+
print(f"Tool {tool} was corrupted, but re-downloading did not help!\n")
329395
print('Platform Tools Installed')

0 commit comments

Comments
 (0)