all repos — dotfiles @ 003e2aabc008ffb6800f3f1198673ef0cebc54e2

linux dotfiles

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
#!/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.
#
# 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.
#
# 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()