tools/mpremote: Show progress indicator when copying large files.

When copying large files (> 2048 bytes) to or from a device with
`mpremote cp` a progress bar and percentage counter are temporarily shown.
This commit is contained in:
Rob Knegjens 2022-04-05 16:05:28 -07:00 committed by Damien George
parent b59989f40e
commit 56978c3dde
2 changed files with 43 additions and 6 deletions

View File

@ -268,6 +268,27 @@ def do_disconnect(pyb):
pyb.close()
def show_progress_bar(size, total_size):
if not sys.stdout.isatty():
return
verbose_size = 2048
bar_length = 20
if total_size < verbose_size:
return
elif size >= total_size:
# Clear progress bar when copy completes
print("\r" + " " * (20 + bar_length) + "\r", end="")
else:
progress = size / total_size
bar = round(progress * bar_length)
print(
"\r ... copying {:3.0f}% [{}{}]".format(
progress * 100, "#" * bar, "-" * (bar_length - bar)
),
end="",
)
def do_filesystem(pyb, args):
def _list_recursive(files, path):
if os.path.isdir(path):
@ -293,9 +314,13 @@ def do_filesystem(pyb, args):
if d not in known_dirs:
pyb.exec_("try:\n uos.mkdir('%s')\nexcept OSError as e:\n print(e)" % d)
known_dirs.add(d)
pyboard.filesystem_command(pyb, ["cp", "/".join((dir, file)), ":" + dir + "/"])
pyboard.filesystem_command(
pyb,
["cp", "/".join((dir, file)), ":" + dir + "/"],
progress_callback=show_progress_bar,
)
else:
pyboard.filesystem_command(pyb, args)
pyboard.filesystem_command(pyb, args, progress_callback=show_progress_bar)
args.clear()

View File

@ -491,7 +491,10 @@ class Pyboard:
)
self.exec_(cmd, data_consumer=stdout_write_bytes)
def fs_get(self, src, dest, chunk_size=256):
def fs_get(self, src, dest, chunk_size=256, progress_callback=None):
if progress_callback:
src_size = int(self.exec_("import os\nprint(os.stat('%s')[6])" % src))
written = 0
self.exec_("f=open('%s','rb')\nr=f.read" % src)
with open(dest, "wb") as f:
while True:
@ -507,9 +510,15 @@ class Pyboard:
if not data:
break
f.write(data)
if progress_callback:
written += len(data)
progress_callback(written, src_size)
self.exec_("f.close()")
def fs_put(self, src, dest, chunk_size=256):
def fs_put(self, src, dest, chunk_size=256, progress_callback=None):
if progress_callback:
src_size = os.path.getsize(src)
written = 0
self.exec_("f=open('%s','wb')\nw=f.write" % dest)
with open(src, "rb") as f:
while True:
@ -520,6 +529,9 @@ class Pyboard:
self.exec_("w(b" + repr(data) + ")")
else:
self.exec_("w(" + repr(data) + ")")
if progress_callback:
written += len(data)
progress_callback(written, src_size)
self.exec_("f.close()")
def fs_mkdir(self, dir):
@ -546,7 +558,7 @@ def execfile(filename, device="/dev/ttyACM0", baudrate=115200, user="micro", pas
pyb.close()
def filesystem_command(pyb, args):
def filesystem_command(pyb, args, progress_callback=None):
def fname_remote(src):
if src.startswith(":"):
src = src[1:]
@ -579,7 +591,7 @@ def filesystem_command(pyb, args):
src = fname_remote(src)
dest2 = fname_cp_dest(src, dest)
print(fmt % (src, dest2))
op(src, dest2)
op(src, dest2, progress_callback=progress_callback)
else:
op = {
"ls": pyb.fs_ls,