| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | #!/usr/bin/env python | 
					
						
							| 
									
										
										
										
											2018-03-04 21:01:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | """Script to download and extract tools
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This script will download and extract required tools into the current directory. | 
					
						
							|  |  |  | Tools list is obtained from package/package_esp8266com_index.template.json file. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | from __future__ import print_function | 
					
						
							| 
									
										
										
										
											2018-03-04 21:01:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | __author__ = "Ivan Grokhotkov" | 
					
						
							|  |  |  | __version__ = "2015" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | import os | 
					
						
							|  |  |  | import shutil | 
					
						
							|  |  |  | import errno | 
					
						
							|  |  |  | import os.path | 
					
						
							|  |  |  | import hashlib | 
					
						
							|  |  |  | import json | 
					
						
							|  |  |  | import platform | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import tarfile | 
					
						
							|  |  |  | import zipfile | 
					
						
							|  |  |  | import re | 
					
						
							| 
									
										
										
										
											2018-03-04 21:01:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | if sys.version_info[0] == 3: | 
					
						
							|  |  |  |     from urllib.request import urlretrieve | 
					
						
							| 
									
										
										
										
											2018-03-05 06:49:09 +11:00
										 |  |  |     unicode = lambda s: str(s) | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | else: | 
					
						
							|  |  |  |     # Not Python 3 - today, it is most likely to be Python 2 | 
					
						
							|  |  |  |     from urllib import urlretrieve | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  | if 'Windows' in platform.system(): | 
					
						
							|  |  |  |     import requests | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 10:43:08 +01:00
										 |  |  | current_dir = os.path.dirname(os.path.realpath(unicode(__file__))) | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  | dist_dir = current_dir + '/dist/' | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | def sha256sum(filename, blocksize=65536): | 
					
						
							|  |  |  |     hash = hashlib.sha256() | 
					
						
							|  |  |  |     with open(filename, "rb") as f: | 
					
						
							|  |  |  |         for block in iter(lambda: f.read(blocksize), b""): | 
					
						
							|  |  |  |             hash.update(block) | 
					
						
							|  |  |  |     return hash.hexdigest() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def mkdir_p(path): | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         os.makedirs(path) | 
					
						
							|  |  |  |     except OSError as exc: | 
					
						
							|  |  |  |         if exc.errno != errno.EEXIST or not os.path.isdir(path): | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def report_progress(count, blockSize, totalSize): | 
					
						
							|  |  |  |     percent = int(count*blockSize*100/totalSize) | 
					
						
							|  |  |  |     percent = min(100, percent) | 
					
						
							|  |  |  |     sys.stdout.write("\r%d%%" % percent) | 
					
						
							|  |  |  |     sys.stdout.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def unpack(filename, destination): | 
					
						
							|  |  |  |     dirname = '' | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |     print('Extracting {0}'.format(os.path.basename(filename))) | 
					
						
							|  |  |  |     sys.stdout.flush() | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     if filename.endswith('tar.gz'): | 
					
						
							|  |  |  |         tfile = tarfile.open(filename, 'r:gz') | 
					
						
							|  |  |  |         tfile.extractall(destination) | 
					
						
							| 
									
										
										
										
											2018-03-04 21:01:17 +01:00
										 |  |  |         dirname = tfile.getnames()[0] | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     elif filename.endswith('zip'): | 
					
						
							|  |  |  |         zfile = zipfile.ZipFile(filename) | 
					
						
							|  |  |  |         zfile.extractall(destination) | 
					
						
							|  |  |  |         dirname = zfile.namelist()[0] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise NotImplementedError('Unsupported archive type') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # a little trick to rename tool directories so they don't contain version number | 
					
						
							|  |  |  |     rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).strip('-') | 
					
						
							|  |  |  |     if rename_to != dirname: | 
					
						
							|  |  |  |         print('Renaming {0} to {1}'.format(dirname, rename_to)) | 
					
						
							|  |  |  |         if os.path.isdir(rename_to): | 
					
						
							|  |  |  |             shutil.rmtree(rename_to) | 
					
						
							|  |  |  |         shutil.move(dirname, rename_to) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_tool(tool): | 
					
						
							| 
									
										
										
										
											2016-10-17 17:08:57 +03:00
										 |  |  |     sys_name = platform.system() | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     archive_name = tool['archiveFileName'] | 
					
						
							|  |  |  |     local_path = dist_dir + archive_name | 
					
						
							|  |  |  |     url = tool['url'] | 
					
						
							|  |  |  |     #real_hash = tool['checksum'].split(':')[1] | 
					
						
							|  |  |  |     if not os.path.isfile(local_path): | 
					
						
							| 
									
										
										
										
											2018-03-04 21:01:17 +01:00
										 |  |  |         print('Downloading ' + archive_name) | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |         sys.stdout.flush() | 
					
						
							| 
									
										
										
										
											2016-10-17 17:08:57 +03:00
										 |  |  |         if 'CYGWIN_NT' in sys_name: | 
					
						
							| 
									
										
										
										
											2017-11-28 11:20:50 +01:00
										 |  |  |             import ssl | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |             ctx = ssl.create_default_context() | 
					
						
							|  |  |  |             ctx.check_hostname = False | 
					
						
							|  |  |  |             ctx.verify_mode = ssl.CERT_NONE | 
					
						
							|  |  |  |             urlretrieve(url, local_path, report_progress, context=ctx) | 
					
						
							|  |  |  |         elif 'Windows' in sys_name: | 
					
						
							|  |  |  |             r = requests.get(url) | 
					
						
							|  |  |  |             f = open(local_path, 'wb') | 
					
						
							|  |  |  |             f.write(r.content) | 
					
						
							|  |  |  |             f.close() | 
					
						
							| 
									
										
										
										
											2016-10-17 17:08:57 +03:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |             urlretrieve(url, local_path, report_progress) | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         sys.stdout.write("\rDone\n") | 
					
						
							|  |  |  |         sys.stdout.flush() | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         print('Tool {0} already downloaded'.format(archive_name)) | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |         sys.stdout.flush() | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     #local_hash = sha256sum(local_path) | 
					
						
							|  |  |  |     #if local_hash != real_hash: | 
					
						
							|  |  |  |     #    print('Hash mismatch for {0}, delete the file and try again'.format(local_path)) | 
					
						
							|  |  |  |     #    raise RuntimeError() | 
					
						
							|  |  |  |     unpack(local_path, '.') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def load_tools_list(filename, platform): | 
					
						
							|  |  |  |     tools_info = json.load(open(filename))['packages'][0]['tools'] | 
					
						
							|  |  |  |     tools_to_download = [] | 
					
						
							|  |  |  |     for t in tools_info: | 
					
						
							|  |  |  |         tool_platform = [p for p in t['systems'] if p['host'] == platform] | 
					
						
							|  |  |  |         if len(tool_platform) == 0: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         tools_to_download.append(tool_platform[0]) | 
					
						
							|  |  |  |     return tools_to_download | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def identify_platform(): | 
					
						
							|  |  |  |     arduino_platform_names = {'Darwin'  : {32 : 'i386-apple-darwin',   64 : 'x86_64-apple-darwin'}, | 
					
						
							|  |  |  |                               'Linux'   : {32 : 'i686-pc-linux-gnu',   64 : 'x86_64-pc-linux-gnu'}, | 
					
						
							|  |  |  |                               'LinuxARM': {32 : 'arm-linux-gnueabihf', 64 : 'aarch64-linux-gnu'}, | 
					
						
							|  |  |  |                               'Windows' : {32 : 'i686-mingw32',        64 : 'i686-mingw32'}} | 
					
						
							|  |  |  |     bits = 32 | 
					
						
							|  |  |  |     if sys.maxsize > 2**32: | 
					
						
							|  |  |  |         bits = 64 | 
					
						
							|  |  |  |     sys_name = platform.system() | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |     sys_platform = platform.platform() | 
					
						
							|  |  |  |     print('System: %s, Info: %s' % (sys_name, sys_platform)) | 
					
						
							|  |  |  |     if 'Linux' in sys_name and sys_platform.find('arm') > 0: | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         sys_name = 'LinuxARM' | 
					
						
							|  |  |  |     if 'CYGWIN_NT' in sys_name: | 
					
						
							|  |  |  |         sys_name = 'Windows' | 
					
						
							|  |  |  |     return arduino_platform_names[sys_name][bits] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |     identified_platform = identify_platform() | 
					
						
							|  |  |  |     print('Platform: {0}'.format(identified_platform)) | 
					
						
							|  |  |  |     tools_to_download = load_tools_list(current_dir + '/../package/package_esp32_index.template.json', identified_platform) | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     mkdir_p(dist_dir) | 
					
						
							|  |  |  |     for tool in tools_to_download: | 
					
						
							|  |  |  |         get_tool(tool) | 
					
						
							| 
									
										
										
										
											2017-01-19 04:48:42 +02:00
										 |  |  |     print('Done') |