diff --git a/tools/run.py b/tools/run.py index 3ad81103ebdd27c7cc66796534a35be83b1c825a..a33c153e3fb9c5cd25f2609e91950d4dca982b18 100755 --- a/tools/run.py +++ b/tools/run.py @@ -5,18 +5,24 @@ #! nix-shell -i python3 -p "python3.withPackages (ps: [ ps.pyserial ])" import sys +import os.path import base64 import argparse +import tarfile import serial -from signal import signal, SIGINT -from sys import exit - - - parser = argparse.ArgumentParser(description="Executes python scripts on card10") parser.add_argument( - "script", type=argparse.FileType("r"), help="micropython file to execute" + "-r", "--run", + required=False, + type=argparse.FileType("r"), + help="MicroPython file to execute without writing to storage" +) +parser.add_argument( + "-u", "--upload", + required=False, + type=argparse.FileType("r"), + help="Tarball to unpack and upload into apps folder", ) parser.add_argument( "-d", @@ -24,22 +30,11 @@ parser.add_argument( default="/dev/ttyACM0", help="Serial device of the pycardium console", ) -args = parser.parse_args() -code = base64.b64encode(bytes(args.script.read(), "utf-8")) +def applyBase64(s, code, fun="exec", extraSetup="", extraNewline=False): + n = 80 + codechunks = [code[i:i+n] for i in range(0, len(code), n)] -n=100 -codechunks = [code[i:i+n] for i in range(0, len(code), n)] - -with serial.Serial(port=args.device, baudrate=115200) as s: - - def handler(signal_received, frame): - # Handle any cleanup here - print('SIGINT or CTRL-C detected. Exiting gracefully') - s.write(b"\x03") - exit(0) - - signal(SIGINT, handler) s.write(b"\x03") # ctrl-c s.readline() s.write(b"import ubinascii; \r\n") @@ -51,29 +46,66 @@ with serial.Serial(port=args.device, baudrate=115200) as s: s.readline() #dont echo this line s.write(b"'']\r\n") s.readline() - - s.write(b"exec(ubinascii.a2b_base64(''.join(code)))\r\n") + #print(s.readline()) + + for cmd in extraSetup: + if len(cmd) > 0: + s.write(bytes(cmd, 'utf-8')) + s.write(b"\r\n") + s.readline() + else: + s.write(b"\r\n") + s.readline() + + s.write(bytes(fun, 'utf-8')) + s.write(b"(ubinascii.a2b_base64(''.join(code)))\r\n") + if extraNewline: + s.write(b"\r\n") + s.readline() + s.readline() s.readline() - - - - - - line = "" - buf = b"" #s.read() - while True: -# while not line.startswith(">>>"): - char="" - - buf+=s.read() - + + +args = parser.parse_args() + +if args.run is None and args.upload is None: + print("Either -e or -u has to be specified") + +with serial.Serial(port=args.device, baudrate=115200) as s: + + if args.upload is not None: + tar = tarfile.TarFile.gzopen(args.upload.name) + for tarinfo in tar: + print(tarinfo.name) + payload = base64.b64encode(tar.extractfile(tarinfo.name).read()) + applyBase64(s, payload, + fun="with open('/apps/{}',\"w\") as f: f.write".format(tarinfo.name), + extraSetup=[ + "try: os.mkdir(\"/apps/{}\")".format(os.path.dirname(tarinfo.name)), + "except: pass", + "" + ], + extraNewline=True) + + elif args.run is not None: + payload = base64.b64encode(bytes(args.run.read(), "utf-8")) + applyBase64(s, payload) + try: - char = buf.decode("utf-8") - print (char, end="") buf = b"" + while True: + buf += s.read() + + try: + char = buf.decode("utf-8") + print(char, end="") + buf = b"" - except: - if(len(buf)>3): - print("ENCODING ERROR") - buf="" - + except UnicodeDecodeError as e: + if len(buf) > 3: + print(e) + buf = b"" + + except KeyboardInterrupt: + print('CTRL-C detected. Exiting gracefully.') + s.write(b"\x03")