From d0d71cc5c3d156dc88e7bb4550d34fff5e872fcf Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Mon, 31 Jan 2022 22:41:29 +0100 Subject: ... --- accounts/gkleen@sif/systemd.nix | 66 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'accounts') 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