Ejemplo n.º 1
0
def replicate_files_on_change(
    src_dir,
    copy_file,
    timeout=None,
    use_gitignore=True,
    debugging=False,
    observer_up_event=None,
    terminate_event=None,
):
    """Wait for changes to files in src_dir and copy with copy_file().

    If provided, the timeout indicates when to return after that many seconds of no change.
    """
    print("debug: replicate on change start")
    src_dir = os.path.abspath(src_dir)
    if use_gitignore:
        spec = get_pathspec(src_dir, use_gitignore)
        event_handler = GitIgnoreCopyFileEventHandler(copy_file,
                                                      spec,
                                                      debugging=debugging)
    else:
        event_handler = CopyFileEventHandler(copy_file, debugging=debugging)
    observer = Observer()
    observer.schedule(event_handler, src_dir, recursive=True)
    if debugging:
        print("Starting observer")
    observer.start()
    if observer_up_event is not None:
        while not observer.is_alive():
            pass
        # wait for event listeners to settle
        time.sleep(0.5)
        observer_up_event.set()
        print("notified observer up")
    try:
        while True:
            time.sleep(0.5)
            if timeout:
                raise_if_timeout(event_handler.last_event_timestamp, timeout)
            if terminate_event and terminate_event.is_set():
                raise ConditionalTermination("Termination condition was set.")
    except (KeyboardInterrupt, NoChangeTimeout, ConditionalTermination) as e:
        if debugging:
            print(f"Exitting on {type(e).__name__}: {e}")
    finally:
        now = time.time()
        # still, dispatch the existing change events before we part ways
        while time.time(
        ) - now < TAIL_TIMEOUT and not observer.event_queue.empty():
            print("flushing events")
            observer.dispatch_events(observer.event_queue, observer.timeout)
        left = now + TAIL_TIMEOUT - time.time()
        observer.stop()
        observer.join(timeout=max(0, left))
        print(f"debug: finished replicate on change with {left} left")