77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import time
|
|
import subprocess
|
|
from threading import Timer
|
|
from watchdog.observers import Observer
|
|
from watchdog.events import FileSystemEventHandler
|
|
from pathlib import Path
|
|
|
|
# PRODUCTION CONFIGURATION
|
|
local_dir = "//home/sgbv/obsidian/"
|
|
remote_dest = "ish:/root/obsidian/"
|
|
debounce_seconds = 2.0
|
|
|
|
# ignore workspace ui states to prevent infinite sync loops
|
|
excludes = [
|
|
"--exclude=.obsidian/workspace*",
|
|
"--exclude=.trash/",
|
|
"--exclude=.git/"
|
|
]
|
|
|
|
def build_rsync_cmd(src, dest):
|
|
return ["rsync", "-avz", "--delete"] + excludes + [src, dest]
|
|
|
|
def pull_sync():
|
|
print(f"pulling changes from ish to arch...")
|
|
subprocess.run(build_rsync_cmd(remote_dest, local_dir))
|
|
print("pull complete.")
|
|
|
|
def push_sync():
|
|
print(f"pushing changes from arch to ish...")
|
|
subprocess.run(build_rsync_cmd(local_dir, remote_dest))
|
|
print("push complete.")
|
|
|
|
class watchdog_push_handler(FileSystemEventHandler):
|
|
def __init__(self):
|
|
self.sync_timer = None
|
|
|
|
def on_any_event(self, event):
|
|
# ignore directory changes and workspace/hidden cache updates
|
|
if event.is_directory or any(x in event.src_path for x in [".obsidian", ".trash"]):
|
|
return
|
|
|
|
print(f"local change detected: {event.event_type}")
|
|
if self.sync_timer:
|
|
self.sync_timer.cancel()
|
|
|
|
self.sync_timer = Timer(debounce_seconds, push_sync)
|
|
self.sync_timer.start()
|
|
|
|
def watch_mode():
|
|
print(f"arch watchdog listening on {local_dir}")
|
|
handler = watchdog_push_handler()
|
|
observer = Observer()
|
|
observer.schedule(handler, local_dir, recursive=True)
|
|
observer.start()
|
|
|
|
try:
|
|
while True:
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
print("\nstopping watchdog...")
|
|
observer.stop()
|
|
observer.join()
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="arch sync node")
|
|
parser.add_argument("mode", nargs="?", default="watch", choices=["watch", "push", "pull"])
|
|
args = parser.parse_args()
|
|
|
|
if args.mode == "pull":
|
|
pull_sync()
|
|
elif args.mode == "push":
|
|
push_sync()
|
|
else:
|
|
watch_mode()
|