From 77c76b4e0407250fc0ba8ee0309a528a4a8f1f09 Mon Sep 17 00:00:00 2001 From: vg Date: Tue, 30 Aug 2022 09:57:12 +0200 Subject: git-sync on boo --- gamechestcli/rsync.py | 80 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'gamechestcli/rsync.py') diff --git a/gamechestcli/rsync.py b/gamechestcli/rsync.py index f27c4f3..37330f9 100644 --- a/gamechestcli/rsync.py +++ b/gamechestcli/rsync.py @@ -1,28 +1,82 @@ #!/usr/bin/python3 +import os +import re import subprocess +import humanfriendly + +from .structures import Progress + class Rsync: + _rsync_progress_re = re.compile(r'^\s*(\S+)\s+(\d+)%\s+(\S+)\s+(\S+)\s+$') + def __init__(self, src, dst): - pass + self.proc = subprocess.Popen( + [ + 'rsync', + '--partial', + # not human readable, easier to parse (but speed still appears + # in human form). + '--no-h', + '--info=progress2', + src, + dst, + ], + stdout=subprocess.PIPE, + #stderr=subprocess.DEVNULL, + encoding='utf8', + env={**os.environ, + **{'LC_ALL':'C.UTF-8', + 'LANG':'C.UTF-8', + 'LANGUAGE':'C.UTF-8', + }}, + ) + self.last_progress = Progress() - #def start(src, dst): + def select_fd(self): + 'useful to use selectors with the process stdout file descriptor' + return self.proc.stdout - def terminate(self): + def progress_read(self): + line = self.proc.stdout.readline() + if match := self._rsync_progress_re.search(line): + self.last_progress = Progress( + int(match.group(1)), + int(match.group(2)), + humanfriendly.parse_size(match.group(3), binary=True), + match.group(4), + ) + return self.last_progress - pass + def terminate(self): + self.proc.terminate() def poll(self): - pass + 'returns None if not terminated, otherwise return returncode' + return self.proc.poll() + + def wait(self, timeout=None): + return self.proc.wait(timeout) + + def __enter__(self): + return self + def __exit__(self, exc_type, value, traceback): + self.terminate() + self.wait() -def rsync(src, dst): - subprocess.run( - ['rsync', - '--partial', - # format: %l length in bytes, %b bytes actually transferred, %f - # filename. - '--out-format=%l %b %f', - ]) +if __name__ == '__main__': + import sys + import contextlib + with contextlib.suppress(KeyboardInterrupt): + with Rsync(sys.argv[1], sys.argv[2]) as rsync: + while rsync.poll() is None: + progress = rsync.progress_read() + print(f'{progress.bytes}b {progress.percent}% ' + f'{progress.speed}b/s {progress.eta}') + rc = rsync.poll() + print(f'rsync ended with code: {rc}') + print('Rsync test main ended') -- cgit v1.2.3