Bootstrap

philcrump-phil-add-ntp
Marek Ventur 2018-08-26 20:27:23 +01:00
parent 63c685dc20
commit 69c7cd39b5
7 changed files with 72 additions and 40 deletions

View File

@ -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)
# Add all paths that are already files
@ -10,9 +10,10 @@ def sync(storage, patterns, resources, verbose):
paths.add("boot.py")
# wifi.json
wifi_path = os.path.join(root, "wifi.json")
if os.path.isfile(wifi_path):
paths.add(wifi_path)
if not skip_wifi:
wifi_path = os.path.join(root, "wifi.json")
if os.path.isfile(wifi_path):
paths.add(wifi_path)
if not patterns:
patterns = ["*"]
@ -28,7 +29,7 @@ def sync(storage, patterns, resources, verbose):
print("Resource %s is going to be synced" % key)
for path in resource['files'].keys():
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)
if not verbose:
print("Copying %s files: " % len(paths), end="", flush=True)
@ -56,8 +57,18 @@ def sync(storage, patterns, resources, verbose):
print(" DONE")
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):
# micropython has a tendecy
# micropython has a tendecy to turn directories into files
if not path or path == storage:
return
if os.path.isfile(path):

View File

@ -57,11 +57,13 @@ from resources import *
def main():
import argparse
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('-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('-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('--boot', help='defines which app to boot into after reboot')
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.boot = args.paths[0]
if command in ["test", "validate", "sync"]:
if command in ["test", "validate", "sync", "bootstrap"]:
resources = get_resources(path)
add_metadata(path, resources)
validate(path, resources)
@ -111,15 +113,21 @@ def main():
else:
args.paths = ["lib/test_%s.py" % p for p in args.paths]
if command in ["reset", "sync"]:
if command in ["reset", "sync", "bootstrap"]:
pyboard_util.stop_badge(args, args.verbose)
if command == "sync":
paths = args.paths if len(args.paths) else None
synced_resources = sync.sync(get_storage(args), paths, resources, args.verbose)
if command == "bootstrap":
sync.clean(get_storage(args))
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 "")
if args.run:
command = "run"
@ -135,7 +143,6 @@ def main():
if run_tests:
for resource in synced_resources:
pyboard_util.check_run([resource])
sync.set_no_boot(get_storage(args))
pyboard_util.run(args, [resource], False)
pyboard_util.soft_reset(args, False)

11
boot.py
View File

@ -1,7 +1,5 @@
import os, tilda
# micropython.alloc_emergency_exception_buf(100) # doesn't exist in TiLDA Mk4 yet
os.sync()
root = os.listdir()
@ -21,14 +19,13 @@ def file(file, remove):
print(str(e))
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:
os.remove("no_boot")
else:
start = None
if "main.py" in root:
start = "main.py"
start = file("once.txt", True) or file("default_app.txt", False) or any_home() or "bootstrap.py"
print(start)
#tilda.main(start)
print("Booting into %s" % start)
tilda.main(start)

View File

@ -14,12 +14,20 @@ def msg(text):
for i, line in enumerate(lines):
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():
with open("wifi.json", "w") as f:
f.write('{"ssid":"emfcamp","pw":"emfemf"}')
with open("wifi.json", "wt") as f:
f.write(json.dumps({"ssid":"emfcamp","pw":"emfemf"}))
f.flush()
os.sync()
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):
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");
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):
s = usocket.socket()
s.connect(usocket.getaddrinfo(HOST, 80)[0][4])
s.connect(addrinfo(HOST, 80))
body = b""
status = None
try:

View File

@ -3,15 +3,15 @@
___name___ = "Launcher"
___license___ = "MIT"
___categories___ = ["System"]
___dependencies___ = ["dialogs", "app"]
___dependencies___ = ["dialogs", "app", "ugfx_helper"]
___launchable___ = False
___bootstrapped___ = True
import ugfx
import ugfx_helper, ugfx
from app import *
from dialogs import *
ugfx.init()
ugfx_helper.init()
ugfx.clear()
options = [{"title": a.title, "app": a} for a in get_apps()]

View File

@ -17,16 +17,16 @@ They also *may*:
"""
___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
_state = None
def init(enable_menu_button = True):
global _state
_state = {"menu": False}
ugfx.init()
ugfx_helper.init()
if enable_menu_button:
pass

View File

@ -166,20 +166,17 @@ def open_http_socket(method, url, json=None, timeout=None, headers=None, data=No
content = None
# ToDo: Handle IPv6 addresses
addr = get_address_info(host, port)
addr = c(host, port)
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:
urlpath += "?" + urlencode(params)
sock.connect(addr)
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))