summaryrefslogtreecommitdiff
path: root/accounts
diff options
context:
space:
mode:
Diffstat (limited to 'accounts')
-rw-r--r--accounts/gkleen@sif/systemd.nix66
1 files 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 {
47 Service = { 47 Service = {
48 Type = "oneshot"; 48 Type = "oneshot";
49 WorkingDirectory = "~"; 49 WorkingDirectory = "~";
50 ExecStart = toString (pkgs.writers.writePython3 "sync-keepass" {} '' 50 ExecStart = toString (pkgs.writers.writePython3 "sync-keepass" {
51 libraries = with pkgs.python3Packages; [ dateutil ];
52 } ''
51 import json 53 import json
52 import subprocess 54 import subprocess
53 # from datetime import datetime 55 from os.path import (expanduser, getmtime, dirname)
56 from datetime import datetime
57 from dateutil.tz import tzlocal
58 from dateutil.parser import isoparse
59 from sys import stderr
54 60
55 res = None 61
56 with subprocess.Popen(['rclone', 'lsjson', 'surtr:store.kdbx'], stdout=subprocess.PIPE) as proc: # noqa: E501 62 remote_fs = 'surtr'
57 res = json.load(proc.stdout) 63 remote_file = f'{remote_fs}:store.kdbx'
58 print(res) 64 target_file = expanduser('~/store.kdbx')
65 meta_file = expanduser('~/.store.kdbx.json')
66
67 upload_time = None
68 our_last_upload_time = None
69 mod_time = None
70
71
72 def get_upload_time():
73 upload_time = None
74 with subprocess.Popen(['rclone', 'lsjson', remote_file], stdout=subprocess.PIPE) as proc: # noqa: E501
75 for file in json.load(proc.stdout):
76 if file['Path'] != 'store.kdbx':
77 continue
78 upload_time = isoparse(file['ModTime'])
79 return upload_time
80
81
82 def do_upload():
83 print('Uploading', file=stderr)
84 subprocess.run(['rclone', 'copy', '-I', target_file, f'{remote_fs}:'], check=True) # noqa: E501
85 upload_time = get_upload_time()
86 with open(meta_file, 'w') as file:
87 json.dump({'our_last_upload_time': upload_time.isoformat()}, file)
88
89
90 def do_download():
91 print('Downloading', file=stderr)
92 subprocess.run(['rclone', 'copy', '-I', remote_file, dirname(target_file)], check=True) # noqa: E501
93
94
95 upload_time = get_upload_time()
96
97 try:
98 with open(meta_file, 'r') as file:
99 file_content = json.load(file)
100 our_last_upload_time = isoparse(file_content['our_last_upload_time']) # noqa: E501
101 except FileNotFoundError:
102 pass
103
104 try:
105 mod_time = datetime.fromtimestamp(getmtime(target_file)).replace(tzinfo=tzlocal()) # noqa: E501
106 except FileNotFoundError:
107 pass
108
109 if upload_time is None or (mod_time is not None and mod_time > upload_time): # noqa: E501
110 do_upload()
111 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
112 do_download()
59 ''); 113 '');
60 Environment = [ "RCLONE_PASSWORD_COMMAND=\"${pkgs.coreutils}/bin/cat ${config.sops.secrets.gkleen-rclone.path}\"" "PATH=${pkgs.rclone}/bin" ]; 114 Environment = [ "RCLONE_PASSWORD_COMMAND=\"${pkgs.coreutils}/bin/cat ${config.sops.secrets.gkleen-rclone.path}\"" "PATH=${pkgs.rclone}/bin" ];
61 }; 115 };