diff --git a/micropython/upysh/upysh.py b/micropython/upysh/upysh.py index 0f0ad65b..b872242e 100644 --- a/micropython/upysh/upysh.py +++ b/micropython/upysh/upysh.py @@ -2,7 +2,7 @@ import sys import os -class LS: +class _Ls: def __repr__(self): self.__call__() return "" @@ -26,7 +26,7 @@ class LS: pass -class PWD: +class _Pwd: def __repr__(self): return os.getcwd() @@ -34,7 +34,7 @@ class PWD: return self.__repr__() -class CLEAR: +class _Clear: def __repr__(self): return "\x1b[2J\x1b[H" @@ -42,7 +42,34 @@ class CLEAR: return self.__repr__() -def head(f, n=10): +class _StdinCommand: + def __init__(self, command, args): + self.command = command + self.args = args.copy() + + def __repr__(self): + cur_args = [] + for prompt, parser, default in self.args: + arg = input(prompt + ": ") + if arg == "": + if default is not None: + arg = default + else: + print(f"You must provide {prompt.lower()}") + return "" + else: + arg = parser(arg) + + cur_args.append(arg) + + self.command(*cur_args) + return "" + + def __call__(self, *args): + self.command(*args) + + +def _head_func(f, n=10): with open(f) as f: for i in range(n): l = f.readline() @@ -51,11 +78,11 @@ def head(f, n=10): sys.stdout.write(l) -def cat(f): +def _cat_func(f): head(f, 1 << 30) -def cp(s, t): +def _cp_func(s, t): try: if os.stat(t)[0] & 0x4000: # is directory t = t.rstrip("/") + "/" + s @@ -71,7 +98,7 @@ def cp(s, t): t.write(buf_mv[:n]) -def newfile(path): +def _newfile_func(path): print("Type file contents line by line, finish with EOF (Ctrl+D).") with open(path, "w") as f: while 1: @@ -83,12 +110,12 @@ def newfile(path): f.write("\n") -def rm(d, recursive=False): # Remove file or tree +def _rm_func(d, recursive=False): # Remove file or tree try: if (os.stat(d)[0] & 0x4000) and recursive: # Dir for f in os.ilistdir(d): if f[0] != "." and f[0] != "..": - rm("/".join((d, f[0]))) # File or Dir + rm("/".join((d, f[0])), True) # File or Dir os.rmdir(d) else: # File os.remove(d) @@ -96,7 +123,7 @@ def rm(d, recursive=False): # Remove file or tree print("rm of '%s' failed" % d) -class Man: +class _Man: def __repr__(self): return """ upysh is intended to be imported using: @@ -105,20 +132,42 @@ from upysh import * To see this help text again, type "man". upysh commands: -clear, ls, ls(...), head(...), cat(...), newfile(...) -cp('src', 'dest'), mv('old', 'new'), rm(...) -pwd, cd(...), mkdir(...), rmdir(...) +clear, ls, ls(...), head(...)*, cat(...)*, newfile(...)* +cp('src', 'dest')*, mv('old', 'new')*, rm(...)* +pwd, cd(...)*, mkdir(...)*, rmdir(...)* + +Most commands (marked with *) can be called interactively. +It means you don't have to type tons of brackets and quotes +(something alike what you expect from a normal shell), +to figure out this behavior just type cd or mv """ -man = Man() -pwd = PWD() -ls = LS() -clear = CLEAR() +man = _Man() +pwd = _Pwd() +ls = _Ls() +clear = _Clear() -cd = os.chdir -mkdir = os.mkdir -mv = os.rename -rmdir = os.rmdir +head = _StdinCommand( + _head_func, [["Filename", str, None], ["Num of lines (default=10)", int, 10]] +) + +cat = _StdinCommand(_cat_func, [["Filename", str, None]]) + +cp = _StdinCommand(_cp_func, [["Source", str, None], ["Target", str, None]]) + +newfile = _StdinCommand(_newfile_func, [["Filename", str, None]]) + +rm = _StdinCommand( + _rm_func, [["Filename", str, None], ["Recursive (default=False)", bool, False]] +) + +cd = _StdinCommand(os.chdir, [["Target", str, None]]) + +mkdir = _StdinCommand(os.mkdir, [["Directory name", str, None]]) + +mv = _StdinCommand(os.rename, [["Source", str, None], ["Target", str, None]]) + +rmdir = _StdinCommand(os.rmdir, [["Directory name", str, None]]) print(man)