diff --git a/tools/espota.py b/tools/espota.py index b73e19ea6..7cb0f2fee 100755 --- a/tools/espota.py +++ b/tools/espota.py @@ -1,11 +1,14 @@ #!/usr/bin/env python # -# Original espoty.py comes from ...? +# Original espota.py by Ivan Grokhotkov: +# https://gist.github.com/igrr/d35ab8446922179dc58c # # Modified since 2015-09-18 from Pascal Gollor (https://github.com/pgollor) # # This script will push an OTA update to the ESP # use it like: python espota.py -i -p -f +# Or to upload SPIFFS image: +# python espota.py -i -p -s # # Changes # 2015-09-18: @@ -13,7 +16,7 @@ # - Add logging. # - Send command to controller to differ between flashing and transmitting SPIFFS image. # - + from __future__ import print_function import socket import sys @@ -25,7 +28,7 @@ import logging FLASH = 0 SPIFFS = 100 - + def serve(remoteAddr, remotePort, filename, command = FLASH): # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -38,18 +41,18 @@ def serve(remoteAddr, remotePort, filename, command = FLASH): except: logging.error("Listen Failed") return 1 - + content_size = os.path.getsize(filename) logging.info('Upload size: %d', content_size) message = '%d %d %d\n' % (command, serverPort, content_size) - + # Wait for a connection logging.info('Sending invitation to: %s', remoteAddr) sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) remote_address = (remoteAddr, int(remotePort)) sent = sock2.sendto(message, remote_address) sock2.close() - + logging.info('Waiting for device...\n') try: sock.settimeout(10) diff --git a/tools/get.py b/tools/get.py new file mode 100755 index 000000000..84e4bee1e --- /dev/null +++ b/tools/get.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# This script will download and extract required tools into the current directory +# Tools list is obtained from tools.json file +# Written by Ivan Grokhotkov, 2015 +# +from __future__ import print_function +import urllib +import os +import os.path +import hashlib +import json +import platform +import sys +import tarfile +import zipfile +import re + +dist_dir = 'dist/' + +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 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 = '' + print('Extracting {0}'.format(filename)) + if filename.endswith('tar.gz'): + tfile = tarfile.open(filename, 'r:gz') + tfile.extractall(destination) + dirname= tfile.getnames()[0] + 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).encode('ascii').strip('-') + if rename_to != dirname: + print('Renaming {0} to {1}'.format(dirname, rename_to)) + os.rename(dirname, rename_to) + +def get_tool(tool): + 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): + print('Downloading ' + archive_name); + urllib.urlretrieve(url, local_path, report_progress) + sys.stdout.write("\rDone\n") + sys.stdout.flush() + else: + print('Tool {0} already downloaded'.format(archive_name)) + 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)) + 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'}, + 'Windows' : {32 : 'i686-mingw32', 64 : 'i686-mingw32'}} + bits = 32 + if sys.maxsize > 2**32: + bits = 64 + return arduino_platform_names[platform.system()][bits] + +if __name__ == '__main__': + print('Platform: {0}'.format(identify_platform())) + tools_to_download = load_tools_list('tools.json', identify_platform()) + for tool in tools_to_download: + get_tool(tool) diff --git a/tools/tools.json b/tools/tools.json new file mode 100644 index 000000000..a708f4e3e --- /dev/null +++ b/tools/tools.json @@ -0,0 +1,123 @@ +[ { + "name":"esptool", + "version":"0.4.6", + "systems": [ + { + "host":"i686-mingw32", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.6/esptool-0.4.6-win32.zip", + "archiveFileName":"esptool-0.4.6-win32.zip", + "checksum":"SHA-256:0248bf78514a3195f583e29218ca7828a66e13c6e5545a078f1c1257033e4927", + "size":"17481" + }, + { + "host":"x86_64-apple-darwin", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.6/esptool-0.4.6-osx.tar.gz", + "archiveFileName":"esptool-0.4.6-osx.tar.gz", + "checksum":"SHA-256:0fe87ba7e29ee90a9fc72492aada8c0796f9e8f8a1c594b6b26cee2610d09bb3", + "size":"20926" + }, + { + "host":"i386-apple-darwin", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.6/esptool-0.4.6-osx.tar.gz", + "archiveFileName":"esptool-0.4.6-osx.tar.gz", + "checksum":"SHA-256:0fe87ba7e29ee90a9fc72492aada8c0796f9e8f8a1c594b6b26cee2610d09bb3", + "size":"20926" + }, + { + "host":"x86_64-pc-linux-gnu", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.6/esptool-0.4.6-linux64.tar.gz", + "archiveFileName":"esptool-0.4.6-linux64.tar.gz", + "checksum":"SHA-256:f9f456e9a42bb2597126c513cb8865f923fb978865d4838b9623d322216b74d0", + "size":"12885" + }, + { + "host":"i686-pc-linux-gnu", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.6/esptool-0.4.6-linux32.tar.gz", + "archiveFileName":"esptool-0.4.6-linux32.tar.gz", + "checksum":"SHA-256:85275ca03a82bfc456f5a84e86962ca1e470ea2e168829c38ca29ee668831d93", + "size":"13417" + } + ] +}, +{ + "name":"xtensa-lx106-elf-gcc", + "version":"1.20.0-26-gb404fb9-2", + "systems": [ + { + "host":"i686-mingw32", + "url":"http://arduino.esp8266.com/win32-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "archiveFileName":"win32-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "checksum":"SHA-256:10476b9c11a7a90f40883413ddfb409f505b20692e316c4e597c4c175b4be09c", + "size":"153527527" + }, + { + "host":"x86_64-apple-darwin", + "url":"http://arduino.esp8266.com/osx-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "archiveFileName":"osx-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "checksum":"SHA-256:0cf150193997bd1355e0f49d3d49711730035257bc1aee1eaaad619e56b9e4e6", + "size":"35385382" + }, + { + "host":"i386-apple-darwin", + "url":"http://arduino.esp8266.com/osx-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "archiveFileName":"osx-xtensa-lx106-elf-gb404fb9-2.tar.gz", + "checksum":"SHA-256:0cf150193997bd1355e0f49d3d49711730035257bc1aee1eaaad619e56b9e4e6", + "size":"35385382" + }, + { + "host":"x86_64-pc-linux-gnu", + "url":"http://arduino.esp8266.com/linux64-xtensa-lx106-elf-gb404fb9.tar.gz", + "archiveFileName":"linux64-xtensa-lx106-elf-gb404fb9.tar.gz", + "checksum":"SHA-256:46f057fbd8b320889a26167daf325038912096d09940b2a95489db92431473b7", + "size":"30262903" + }, + { + "host":"i686-pc-linux-gnu", + "url":"http://arduino.esp8266.com/linux32-xtensa-lx106-elf.tar.gz", + "archiveFileName":"linux32-xtensa-lx106-elf.tar.gz", + "checksum":"SHA-256:b24817819f0078fb05895a640e806e0aca9aa96b47b80d2390ac8e2d9ddc955a", + "size":"32734156" + } + ] +}, +{ + "name":"mkspiffs", + "version":"0.1.2", + "systems": [ + { + "host":"i686-mingw32", + "url":"https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-windows.zip", + "archiveFileName":"mkspiffs-0.1.2-windows.zip", + "checksum":"SHA-256:0a29119b8458b61a877408f7995e4944623a712e0d313a2c2f76af9ab55cc9f2", + "size":"230802" + }, + { + "host":"x86_64-apple-darwin", + "url":"https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-osx.tar.gz", + "archiveFileName":"mkspiffs-0.1.2-osx.tar.gz", + "checksum":"SHA-256:df656fae21a41c1269ea50cb53752dcaf6a4e1437255f3a9fb50b4025549b58e", + "size":"115091" + }, + { + "host":"i386-apple-darwin", + "url":"https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-osx.tar.gz", + "archiveFileName":"mkspiffs-0.1.2-osx.tar.gz", + "checksum":"SHA-256:df656fae21a41c1269ea50cb53752dcaf6a4e1437255f3a9fb50b4025549b58e", + "size":"115091" + }, + { + "host":"x86_64-pc-linux-gnu", + "url":"https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-linux64.tar.gz", + "archiveFileName":"mkspiffs-0.1.2-linux64.tar.gz", + "checksum":"SHA-256:1a1dd81b51daf74c382db71b42251757ca4136e8762107e69feaa8617bac315f", + "size":"46281" + }, + { + "host":"i686-pc-linux-gnu", + "url":"https://github.com/igrr/mkspiffs/releases/download/0.1.2/mkspiffs-0.1.2-linux32.tar.gz", + "archiveFileName":"mkspiffs-0.1.2-linux32.tar.gz", + "checksum":"SHA-256:e990d545dfcae308aabaac5fa9e1db734cc2b08167969e7eedac88bd0839667c", + "size":"45272" + } + ] +} ]