Bootstrap
parent
63c685dc20
commit
69c7cd39b5
|
@ -1,6 +1,6 @@
|
||||||
import os, shutil, sys, fnmatch
|
import os, shutil, sys, fnmatch, glob
|
||||||
|
|
||||||
def sync(storage, patterns, resources, verbose):
|
def sync(storage, patterns, resources, verbose, skip_wifi):
|
||||||
root = get_root(verbose)
|
root = get_root(verbose)
|
||||||
|
|
||||||
# Add all paths that are already files
|
# Add all paths that are already files
|
||||||
|
@ -10,9 +10,10 @@ def sync(storage, patterns, resources, verbose):
|
||||||
paths.add("boot.py")
|
paths.add("boot.py")
|
||||||
|
|
||||||
# wifi.json
|
# wifi.json
|
||||||
wifi_path = os.path.join(root, "wifi.json")
|
if not skip_wifi:
|
||||||
if os.path.isfile(wifi_path):
|
wifi_path = os.path.join(root, "wifi.json")
|
||||||
paths.add(wifi_path)
|
if os.path.isfile(wifi_path):
|
||||||
|
paths.add(wifi_path)
|
||||||
|
|
||||||
if not patterns:
|
if not patterns:
|
||||||
patterns = ["*"]
|
patterns = ["*"]
|
||||||
|
@ -28,7 +29,7 @@ def sync(storage, patterns, resources, verbose):
|
||||||
print("Resource %s is going to be synced" % key)
|
print("Resource %s is going to be synced" % key)
|
||||||
for path in resource['files'].keys():
|
for path in resource['files'].keys():
|
||||||
paths.add(path)
|
paths.add(path)
|
||||||
if not found:
|
if not found and (pattern not in paths):
|
||||||
print("WARN: No resources to copy found for pattern %s" % patterns)
|
print("WARN: No resources to copy found for pattern %s" % patterns)
|
||||||
if not verbose:
|
if not verbose:
|
||||||
print("Copying %s files: " % len(paths), end="", flush=True)
|
print("Copying %s files: " % len(paths), end="", flush=True)
|
||||||
|
@ -56,8 +57,18 @@ def sync(storage, patterns, resources, verbose):
|
||||||
print(" DONE")
|
print(" DONE")
|
||||||
return synced_resources
|
return synced_resources
|
||||||
|
|
||||||
|
def clean(storage):
|
||||||
|
print("Cleaning:", end=" ", flush=True)
|
||||||
|
files = glob.glob(os.path.join(storage, "*"))
|
||||||
|
for f in files:
|
||||||
|
if os.path.isfile(f):
|
||||||
|
os.remove(f)
|
||||||
|
else:
|
||||||
|
shutil.rmtree(f)
|
||||||
|
print("DONE")
|
||||||
|
|
||||||
def ensure_dir(path, storage):
|
def ensure_dir(path, storage):
|
||||||
# micropython has a tendecy
|
# micropython has a tendecy to turn directories into files
|
||||||
if not path or path == storage:
|
if not path or path == storage:
|
||||||
return
|
return
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
|
|
|
@ -57,11 +57,13 @@ from resources import *
|
||||||
def main():
|
def main():
|
||||||
import argparse
|
import argparse
|
||||||
cmd_parser = argparse.ArgumentParser(description='Toolchain for working with the TiLDA Mk4')
|
cmd_parser = argparse.ArgumentParser(description='Toolchain for working with the TiLDA Mk4')
|
||||||
cmd_parser.add_argument('command', nargs=1, help='command [test|reset|sync|run|validate|wifi|firmware-update|app]', choices=['test', 'reset', 'sync', 'validate', 'run', 'wifi', 'firmware-update', 'app'])
|
cmd_parser.add_argument('command', nargs=1, help='command [test|reset|sync|run|validate|wifi|firmware-update|app|bootstrap]', choices=['test', 'reset', 'sync', 'validate', 'run', 'wifi', 'firmware-update', 'app', 'bootstrap'])
|
||||||
|
cmd_parser.add_argument('-c', '--clean', action='store_true', help='clean mass storage before writing')
|
||||||
cmd_parser.add_argument('-d', '--device', help='the serial device of the badge')
|
cmd_parser.add_argument('-d', '--device', help='the serial device of the badge')
|
||||||
cmd_parser.add_argument('-s', '--storage', help='the usb mass storage path of the badge')
|
cmd_parser.add_argument('-s', '--storage', help='the usb mass storage path of the badge')
|
||||||
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
|
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
|
||||||
cmd_parser.add_argument('-v', '--verbose', action='store_true', help='adds more output')
|
cmd_parser.add_argument('-v', '--verbose', action='store_true', help='adds more output')
|
||||||
|
cmd_parser.add_argument('--skip-wifi', action='store_true', help='does not sync wifi.json')
|
||||||
cmd_parser.add_argument('--print_resources', action='store_true', help='prints resources in json')
|
cmd_parser.add_argument('--print_resources', action='store_true', help='prints resources in json')
|
||||||
cmd_parser.add_argument('--boot', help='defines which app to boot into after reboot')
|
cmd_parser.add_argument('--boot', help='defines which app to boot into after reboot')
|
||||||
cmd_parser.add_argument('--run', help='like run, but after a sync')
|
cmd_parser.add_argument('--run', help='like run, but after a sync')
|
||||||
|
@ -90,7 +92,7 @@ def main():
|
||||||
args.run = "%s/main.py" % args.paths[0]
|
args.run = "%s/main.py" % args.paths[0]
|
||||||
#args.boot = args.paths[0]
|
#args.boot = args.paths[0]
|
||||||
|
|
||||||
if command in ["test", "validate", "sync"]:
|
if command in ["test", "validate", "sync", "bootstrap"]:
|
||||||
resources = get_resources(path)
|
resources = get_resources(path)
|
||||||
add_metadata(path, resources)
|
add_metadata(path, resources)
|
||||||
validate(path, resources)
|
validate(path, resources)
|
||||||
|
@ -111,15 +113,21 @@ def main():
|
||||||
else:
|
else:
|
||||||
args.paths = ["lib/test_%s.py" % p for p in args.paths]
|
args.paths = ["lib/test_%s.py" % p for p in args.paths]
|
||||||
|
|
||||||
|
if command in ["reset", "sync", "bootstrap"]:
|
||||||
if command in ["reset", "sync"]:
|
|
||||||
pyboard_util.stop_badge(args, args.verbose)
|
pyboard_util.stop_badge(args, args.verbose)
|
||||||
|
|
||||||
if command == "sync":
|
if command == "bootstrap":
|
||||||
paths = args.paths if len(args.paths) else None
|
sync.clean(get_storage(args))
|
||||||
synced_resources = sync.sync(get_storage(args), paths, resources, args.verbose)
|
sync.sync(get_storage(args), ["bootstrap.py"], {}, args.verbose, args.skip_wifi)
|
||||||
|
pyboard_util.soft_reset(args)
|
||||||
|
|
||||||
if command in ["reset", "sync"]:
|
if command == "sync":
|
||||||
|
if args.clean:
|
||||||
|
sync.clean(get_storage(args))
|
||||||
|
paths = args.paths if len(args.paths) else None
|
||||||
|
synced_resources = sync.sync(get_storage(args), paths, resources, args.verbose, args.skip_wifi)
|
||||||
|
|
||||||
|
if (command in ["reset", "sync"]) or run_tests:
|
||||||
sync.set_boot_app(get_storage(args), args.boot or "")
|
sync.set_boot_app(get_storage(args), args.boot or "")
|
||||||
if args.run:
|
if args.run:
|
||||||
command = "run"
|
command = "run"
|
||||||
|
@ -135,7 +143,6 @@ def main():
|
||||||
if run_tests:
|
if run_tests:
|
||||||
for resource in synced_resources:
|
for resource in synced_resources:
|
||||||
pyboard_util.check_run([resource])
|
pyboard_util.check_run([resource])
|
||||||
sync.set_no_boot(get_storage(args))
|
|
||||||
pyboard_util.run(args, [resource], False)
|
pyboard_util.run(args, [resource], False)
|
||||||
pyboard_util.soft_reset(args, False)
|
pyboard_util.soft_reset(args, False)
|
||||||
|
|
||||||
|
|
11
boot.py
11
boot.py
|
@ -1,7 +1,5 @@
|
||||||
import os, tilda
|
import os, tilda
|
||||||
|
|
||||||
# micropython.alloc_emergency_exception_buf(100) # doesn't exist in TiLDA Mk4 yet
|
|
||||||
|
|
||||||
os.sync()
|
os.sync()
|
||||||
root = os.listdir()
|
root = os.listdir()
|
||||||
|
|
||||||
|
@ -21,14 +19,13 @@ def file(file, remove):
|
||||||
print(str(e))
|
print(str(e))
|
||||||
|
|
||||||
def any_home():
|
def any_home():
|
||||||
return app(next(a for a in root if a.startswith("home")))
|
h = [a for a in root if a.startswith("home")]
|
||||||
|
return h[0] if len(h) else False
|
||||||
|
|
||||||
if "no_boot" in root:
|
if "no_boot" in root:
|
||||||
os.remove("no_boot")
|
|
||||||
else:
|
|
||||||
start = None
|
start = None
|
||||||
if "main.py" in root:
|
if "main.py" in root:
|
||||||
start = "main.py"
|
start = "main.py"
|
||||||
start = file("once.txt", True) or file("default_app.txt", False) or any_home() or "bootstrap.py"
|
start = file("once.txt", True) or file("default_app.txt", False) or any_home() or "bootstrap.py"
|
||||||
print(start)
|
print("Booting into %s" % start)
|
||||||
#tilda.main(start)
|
tilda.main(start)
|
||||||
|
|
30
bootstrap.py
30
bootstrap.py
|
@ -14,12 +14,20 @@ def msg(text):
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
ugfx.text(5, 65 + i * 20, line, ugfx.BLACK)
|
ugfx.text(5, 65 + i * 20, line, ugfx.BLACK)
|
||||||
|
|
||||||
def wifi_details():
|
def wifi_details(final_try = False):
|
||||||
if not "wifi.json" in os.listdir():
|
if not "wifi.json" in os.listdir():
|
||||||
with open("wifi.json", "w") as f:
|
with open("wifi.json", "wt") as f:
|
||||||
f.write('{"ssid":"emfcamp","pw":"emfemf"}')
|
f.write(json.dumps({"ssid":"emfcamp","pw":"emfemf"}))
|
||||||
|
f.flush()
|
||||||
|
os.sync()
|
||||||
with open("wifi.json") as f:
|
with open("wifi.json") as f:
|
||||||
return json.loads(f.read())
|
try:
|
||||||
|
return json.loads(f.read())
|
||||||
|
except Exception as e:
|
||||||
|
if final_try:
|
||||||
|
raise e
|
||||||
|
os.remove("wifi.json")
|
||||||
|
return wifi_details()
|
||||||
|
|
||||||
def connect(wifi):
|
def connect(wifi):
|
||||||
details = wifi_details()
|
details = wifi_details()
|
||||||
|
@ -34,9 +42,21 @@ def connect(wifi):
|
||||||
raise OSError("Timeout while trying to\nconnect to wifi.\n\nPlease connect your\nbadge to your computer\nand edit wifi.json with\nyour wifi details");
|
raise OSError("Timeout while trying to\nconnect to wifi.\n\nPlease connect your\nbadge to your computer\nand edit wifi.json with\nyour wifi details");
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def addrinfo(host, port, retries_left = 20):
|
||||||
|
try:
|
||||||
|
return usocket.getaddrinfo(host, port)[0][4]
|
||||||
|
except OSError as e:
|
||||||
|
if ("-15" in str(e)) and retries_left:
|
||||||
|
# [addrinfo error -15]
|
||||||
|
# This tends to happen after startup and goes away after a while
|
||||||
|
time.sleep_ms(200)
|
||||||
|
return addrinfo(host, port, retries_left - 1)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
def get(path):
|
def get(path):
|
||||||
s = usocket.socket()
|
s = usocket.socket()
|
||||||
s.connect(usocket.getaddrinfo(HOST, 80)[0][4])
|
s.connect(addrinfo(HOST, 80))
|
||||||
body = b""
|
body = b""
|
||||||
status = None
|
status = None
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
___name___ = "Launcher"
|
___name___ = "Launcher"
|
||||||
___license___ = "MIT"
|
___license___ = "MIT"
|
||||||
___categories___ = ["System"]
|
___categories___ = ["System"]
|
||||||
___dependencies___ = ["dialogs", "app"]
|
___dependencies___ = ["dialogs", "app", "ugfx_helper"]
|
||||||
___launchable___ = False
|
___launchable___ = False
|
||||||
___bootstrapped___ = True
|
___bootstrapped___ = True
|
||||||
|
|
||||||
import ugfx
|
import ugfx_helper, ugfx
|
||||||
from app import *
|
from app import *
|
||||||
from dialogs import *
|
from dialogs import *
|
||||||
|
|
||||||
ugfx.init()
|
ugfx_helper.init()
|
||||||
ugfx.clear()
|
ugfx.clear()
|
||||||
|
|
||||||
options = [{"title": a.title, "app": a} for a in get_apps()]
|
options = [{"title": a.title, "app": a} for a in get_apps()]
|
||||||
|
|
|
@ -17,16 +17,16 @@ They also *may*:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
___license___ = "MIT"
|
___license___ = "MIT"
|
||||||
___dependencies___ = ["database", "buttons", "random", "app", "sleep"]
|
___dependencies___ = ["database", "buttons", "random", "app", "sleep", "ugfx_helper"]
|
||||||
|
|
||||||
import database, ugfx, random, buttons, tilda, sleep
|
import database, ugfx, random, buttons, tilda, sleep, ugfx_helper
|
||||||
from app import App
|
from app import App
|
||||||
|
|
||||||
_state = None
|
_state = None
|
||||||
def init(enable_menu_button = True):
|
def init(enable_menu_button = True):
|
||||||
global _state
|
global _state
|
||||||
_state = {"menu": False}
|
_state = {"menu": False}
|
||||||
ugfx.init()
|
ugfx_helper.init()
|
||||||
|
|
||||||
if enable_menu_button:
|
if enable_menu_button:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -166,20 +166,17 @@ def open_http_socket(method, url, json=None, timeout=None, headers=None, data=No
|
||||||
content = None
|
content = None
|
||||||
|
|
||||||
# ToDo: Handle IPv6 addresses
|
# ToDo: Handle IPv6 addresses
|
||||||
addr = get_address_info(host, port)
|
addr = c(host, port)
|
||||||
|
|
||||||
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
|
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
|
||||||
|
|
||||||
if proto == 'https:':
|
|
||||||
# todo: fix this
|
|
||||||
sock = ussl.wrap_socket(sock, ca_certs="DST Root CA X3", cert_reqs=ussl.CERT_OPTIONAL) # ,
|
|
||||||
|
|
||||||
if params:
|
if params:
|
||||||
urlpath += "?" + urlencode(params)
|
urlpath += "?" + urlencode(params)
|
||||||
|
|
||||||
sock.connect(addr)
|
sock.connect(addr)
|
||||||
|
|
||||||
if proto == 'https:':
|
if proto == 'https:':
|
||||||
sock.settimeout(0) # Actually make timeouts working properly with ssl
|
sock = ussl.wrap_socket(sock, ca_certs="DST Root CA X3", cert_reqs=ussl.CERT_OPTIONAL)
|
||||||
|
|
||||||
sock.send('%s /%s HTTP/1.0\r\nHost: %s\r\n' % (method, urlpath, host))
|
sock.send('%s /%s HTTP/1.0\r\nHost: %s\r\n' % (method, urlpath, host))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue