scripts/pd (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
#!/usr/bin/env python3 # # ------------------------------------------------------------- # Journal Keeping Script [aka Personal Diary (pd)] # Author : Prithu Goswami <prithugoswami524@gmail.com> # ------------------------------------------------------------- # Prerequisites : make sure these programs are available on the # machine: # 'rclone' # 'vim' # 'gpg' (v2.X) # # This is a very messy script and is just a quick hack and is not # a very super secure way of keeping a journal but I hope to improve on # it with time. It uses unsymmetric AES-128 encryption. # # This script opens a temp file in a vim buffer and after wrting # and quiting from vim, it appends the contents to the file # 'pd_path' that is in the 'pd_dir' in the $HOME dir of the machine, # with a date and timestamp. It then encrypts the file using gpg # and uploads it to the cloud storage. # # NOTE : 'rclone' should be configured # with a remote first. run 'rlone config'. # The remote should have directory with the encrypted 'pd' file # Path to remote directory should be stored in 'rclone_dir' # # I use 'rclone' to sync the journal to my dropbox # the script first fetches any changes done to the pd file, # decryptis it using 'gpg' using the passhprase-file as '$HOME/.pdkey' # and then appends the entry, encrypts it and uploads it. # # VARIABLES # # 'key_path' : passphrase for AES encrypted file # default alogrithm used by gpg v2.2 is AES-128 according # to the man page # 'pd_dir' : The directory where the pd file is stored # 'pd_path' : The path to the pd file # 'rclone_dir' ; The direrctory of the pd file on the 'remote' # in this case the 'remote' is 'drop:' # # NOTE : # Make sure there already exists a symmetrically encrypted AES file # in 'pd_path' and also in 'rclone_dir' # # To symmetrically encrypt an empty file run: # `touch empty ; gpg2 --passphrase <secret> --batch -o pd -c empty` # this should create a symmetrically encrypted AES file named 'pd' with # the passphrase <secret> # This is not the most secure thing in the world I don't even intend it # to be. So anyways, the <secret> has to be saved as .pdkey in your home # directory or elsewhere ( if you're saving it elsewhere, then change # the 'key_path' variable accordingly import os import datetime import tempfile import subprocess import shlex import sys import hashlib ## VARIABLES ## # Change these accordingly env_home = os.environ['HOME'] tmp_pd_path = '/tmp/pd' key_path = env_home + '/.pdkey' pd_dir = env_home + '/Dropbox/pd' pd_path = pd_dir + '/pd' rclone_dir = 'drop:/pd' if not os.path.exists(key_path): print("Exiting..No .pdkey found in home dir") exit() if os.path.exists(tmp_pd_path): os.remove(tmp_pd_path) def fetch_and_decrypt(): """ Fetches the cloud copy first (sync) and then decrypts it to tmp_pd_path """ print("Fetching changes...") if not os.system('rclone sync {}/ {}/'.format(rclone_dir, pd_dir)): print("Done") decrypt_cmd = ('gpg --passphrase-file {} --batch -o {} -d {}' .format(key_path, tmp_pd_path, pd_path)) args = shlex.split(decrypt_cmd) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = p.communicate() if p.returncode: # if gpg exits with a non-zero return code print("Error while decrypting :\n" + err) exit() else: print("Something went wrong") def encrypt_and_push(): """ Encrypts the file at tmp_pd_path and then syncs to the cloud. i.e replace the copy in the cloud with the local one. """ if os.path.exists(pd_path): os.remove(pd_path) encrypt_cmd = ('gpg --passphrase-file {} --batch -o {} -c {}' .format(key_path, pd_path, tmp_pd_path)) args = shlex.split(encrypt_cmd) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = p.communicate() if p.returncode: print("Error while encrypting :\n" + err) exit() os.remove(tmp_pd_path) print("Pushing changes...") if not os.system('rclone sync {}/ {}/'.format(pd_dir, rclone_dir)): print("Done") else: print("Something went wrong") # PD edit argument # with the 'edit' argument passed to the script it will fetch the latest pd # version from the clound and let you edit and then push it back if len(sys.argv) > 1: if sys.argv[1] == 'edit': if os.path.exists(tmp_pd_path): os.remove(tmp_pd_path) fetch_and_decrypt() with open(tmp_pd_path, 'r') as pdtemp: hash_before_edit = (hashlib.sha1(pdtemp.read().encode('utf-8')) .hexdigest()) os.system("vim {}".format(tmp_pd_path)) with open(tmp_pd_path, 'r') as pdtemp: hash_after_edit = (hashlib.sha1(pdtemp.read().encode('utf-8')) .hexdigest()) if hash_before_edit == hash_after_edit: print("Nothing was changed. Exiting...") exit() encrypt_and_push() exit() entry = None with tempfile.NamedTemporaryFile(suffix='.pdentry') as temp: command = "vim {}".format(temp.name) os.system(command) entry = open(temp.name, 'r').read() if len(entry.strip()) == 0: print("Nothing was entered...") exit() fetch_and_decrypt() with open(tmp_pd_path, 'a', encoding='utf8') as fp: dt = datetime.datetime.now() date_string = dt.strftime('%a, %d %b %Y') time_string = dt.strftime('%I:%M %p') date_and_time = '[' + date_string + ' | ' + time_string + ']' fp.write('\n\n\n===============================\n' + date_and_time + '\n') fp.write(entry) encrypt_and_push() |