diff options
author | vg <vgm+dev@devys.org> | 2022-08-30 09:57:12 +0200 |
---|---|---|
committer | vg <vgm+dev@devys.org> | 2022-08-30 09:57:12 +0200 |
commit | 77c76b4e0407250fc0ba8ee0309a528a4a8f1f09 (patch) | |
tree | e07eced6c7a6fadbc5c12fb53ccd369c11674285 /gamechestcli/rsync.py | |
parent | 7fe1ae0d26c3790ac81a0ee7b1bf01a383388575 (diff) | |
download | gamechest-77c76b4e0407250fc0ba8ee0309a528a4a8f1f09.tar.gz gamechest-77c76b4e0407250fc0ba8ee0309a528a4a8f1f09.tar.bz2 gamechest-77c76b4e0407250fc0ba8ee0309a528a4a8f1f09.zip |
git-sync on boo
Diffstat (limited to 'gamechestcli/rsync.py')
-rw-r--r-- | gamechestcli/rsync.py | 80 |
1 files changed, 67 insertions, 13 deletions
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') |