import socket from pathlib import Path from exec_print_capture import execute_print_capture def rsync_inform(rsync_cmd: list[str], inform_cmd: list[str], user_input_file: Path): """ First, this method transfers files to a remote pc. Then, it informs the remote pc. If some error occurs during the above steps, it waits for user input (via a UNIX-socket) and repeats the failed step. :param rsync_cmd: :param inform_cmd: :param user_input_file: :return: """ # - rsync to remote pc # - catch error # - wait until user input, then repeat _execute_loop_until_successful(rsync_cmd, user_input_file) # - inform remote pc about complete rsync # - catch error # - wait until user input, then repeat _execute_loop_until_successful(inform_cmd, user_input_file) def _execute_loop_until_successful(cmd: list[str], user_input_file: Path): while True: returncode, _out, _err = execute_print_capture(cmd) if returncode == 0: break else: print(f'\n' f'Error while executing:\n' f'\t{cmd}\n' f'\tFor details, see above output.') _wait_for_user(user_input_file) print() def _wait_for_user(socket_file: Path): """ Waits until user writes 'OK\n' to UNIX-socket. """ # INSPIRATION: https://pymotw.com/3/socket/uds.html print(f'Info:\n' f'\tPlease fix the above error first. Then continue here:\n' f'\tsudo pacman -S --needed openbsd-netcat\n' f'\techo "OK" | nc -U "{socket_file.absolute()}"') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.bind(str(socket_file)) sock.listen(1) while True: connection, client_address = sock.accept() try: b: bytes = connection.recv(32) if b == b'OK\n': print('Received "OK" from user.') break else: print(f'Received unknown message: {b}') except Exception as e: print(f'Error while reading message: {e}') finally: connection.close() sock.close() socket_file.unlink(missing_ok=False)