From d0d71cc5c3d156dc88e7bb4550d34fff5e872fcf Mon Sep 17 00:00:00 2001
From: Gregor Kleen <gkleen@yggdrasil.li>
Date: Mon, 31 Jan 2022 22:41:29 +0100
Subject: ...

---
 accounts/gkleen@sif/systemd.nix | 66 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/accounts/gkleen@sif/systemd.nix b/accounts/gkleen@sif/systemd.nix
index 21c50008..bd506590 100644
--- a/accounts/gkleen@sif/systemd.nix
+++ b/accounts/gkleen@sif/systemd.nix
@@ -47,15 +47,69 @@ in {
       Service = {
         Type = "oneshot";
         WorkingDirectory = "~";
-        ExecStart = toString (pkgs.writers.writePython3 "sync-keepass" {} ''
+        ExecStart = toString (pkgs.writers.writePython3 "sync-keepass" {
+          libraries = with pkgs.python3Packages; [ dateutil ];
+        } ''
           import json
           import subprocess
-          # from datetime import datetime
+          from os.path import (expanduser, getmtime, dirname)
+          from datetime import datetime
+          from dateutil.tz import tzlocal
+          from dateutil.parser import isoparse
+          from sys import stderr
 
-          res = None
-          with subprocess.Popen(['rclone', 'lsjson', 'surtr:store.kdbx'], stdout=subprocess.PIPE) as proc:  # noqa: E501
-              res = json.load(proc.stdout)
-          print(res)
+
+          remote_fs = 'surtr'
+          remote_file = f'{remote_fs}:store.kdbx'
+          target_file = expanduser('~/store.kdbx')
+          meta_file = expanduser('~/.store.kdbx.json')
+
+          upload_time = None
+          our_last_upload_time = None
+          mod_time = None
+
+
+          def get_upload_time():
+              upload_time = None
+              with subprocess.Popen(['rclone', 'lsjson', remote_file], stdout=subprocess.PIPE) as proc:  # noqa: E501
+                  for file in json.load(proc.stdout):
+                      if file['Path'] != 'store.kdbx':
+                          continue
+                      upload_time = isoparse(file['ModTime'])
+              return upload_time
+
+
+          def do_upload():
+              print('Uploading', file=stderr)
+              subprocess.run(['rclone', 'copy', '-I', target_file, f'{remote_fs}:'], check=True)  # noqa: E501
+              upload_time = get_upload_time()
+              with open(meta_file, 'w') as file:
+                  json.dump({'our_last_upload_time': upload_time.isoformat()}, file)
+
+
+          def do_download():
+              print('Downloading', file=stderr)
+              subprocess.run(['rclone', 'copy', '-I', remote_file, dirname(target_file)], check=True)  # noqa: E501
+
+
+          upload_time = get_upload_time()
+
+          try:
+              with open(meta_file, 'r') as file:
+                  file_content = json.load(file)
+                  our_last_upload_time = isoparse(file_content['our_last_upload_time'])  # noqa: E501
+          except FileNotFoundError:
+              pass
+
+          try:
+              mod_time = datetime.fromtimestamp(getmtime(target_file)).replace(tzinfo=tzlocal())  # noqa: E501
+          except FileNotFoundError:
+              pass
+
+          if upload_time is None or (mod_time is not None and mod_time > upload_time):  # noqa: E501
+              do_upload()
+          elif upload_time is not None and (mod_time is None or upload_time > mod_time) and (our_last_upload_time is None or upload_time > our_last_upload_time):  # noqa: E501
+              do_download()
         '');
         Environment = [ "RCLONE_PASSWORD_COMMAND=\"${pkgs.coreutils}/bin/cat ${config.sops.secrets.gkleen-rclone.path}\"" "PATH=${pkgs.rclone}/bin" ];
       };
-- 
cgit v1.2.3