X-Git-Url: https://git.danix.xyz/?a=blobdiff_plain;f=notes.sh;h=a9afd607a1fbb1be68e700ec7b1a35783b093df2;hb=HEAD;hp=8a9c082237a31b84c5ec43f454811224d0610da1;hpb=efa3e6079384bc77f194081dff89361e4eda87b2;p=bash-notes.git diff --git a/notes.sh b/notes.sh index 8a9c082..a9afd60 100755 --- a/notes.sh +++ b/notes.sh @@ -17,7 +17,7 @@ PID=$$ BASENAME=$( basename "$0" ) NOW=$(date +%s) -VERSION="0.3" +VERSION="0.4git" DBVERSION=${VERSION}_${NOW} set_defaults() { @@ -25,6 +25,8 @@ set_defaults() { JQ=${JQ:-/usr/bin/jq} EDITOR=${EDITOR:-/usr/bin/vim} TERMINAL=${TERMINAL:-/usr/bin/alacritty} +# Git binary only used if $USEGIT is true - See below +GIT=${GIT:-/usr/bin/git} # add options for your terminal. Remember to add the last option to execute # your editor program, otherwise the script will fail. # see example in the addnote function @@ -43,6 +45,17 @@ DB=${BASEDIR}/db.json # directory containing the actual notes NOTESDIR=${BASEDIR}/notes +### GIT SUPPORT + +# If you want to store your notes in a git repository set this to true +USEGIT=true +# Address of your remote repository. Without this GIT will refuse to work +GITREMOTE=${GITREMOTE:-""} +# How long should we wait (in seconds) between sync on the git remote. Default 3600 (1 hour) +GITSYNCDELAY=${GITSYNCDELAY:-"3600"} +# The name of this client. If left empty, defaults to the output of hostname +GITCLIENT=${GITCLIENT:-""} + } # end set_defaults, do not change this line. set_defaults @@ -82,7 +95,7 @@ fi echo $PID > "$PIDFILE" # Export config to file -function export_config() { +export_config() { if [ -r ${RCFILE} ]; then echo "Backing up current '${RCFILE}'...." mv -f ${RCFILE} ${RCFILE}.$(date +%Y%m%d_%H%M) @@ -103,7 +116,7 @@ function export_config() { # we should expand on this function to add a sample note and explain a little bit # how the program works. -function firstrun() { +firstrun() { [ -f $RCFILE ] && RC=$RCFILE || RC="none" clear @@ -129,6 +142,9 @@ jq executable: ${JQ} "version": "${VERSION}", "dbversion": "${DBVERSION}" }, + "git": { + "lastpull": "" + }, "notes": [] } __EOL__ @@ -147,11 +163,11 @@ if [[ ! -d $NOTESDIR ]]; then firstrun fi # check if input is a number, returns false or the number itself -function check_noteID() { +check_noteID() { IN=$1 case $IN in ''|*[!0-9]*) - return 1 + false ;; *) echo "$IN" @@ -159,7 +175,7 @@ function check_noteID() { esac } -function helptext() { +helptext() { echo "Usage:" echo " $0 [PARAMS] [note ID]..." echo "" @@ -177,35 +193,210 @@ function helptext() { echo -e " -v | --version\t\t: Print version" echo -e " --userconf\t\t\t: Export User config file" echo -e " --backup []\t\t: Backup your data in your destination folder" + echo -e " --showconf\t\t\t: Display running options" + echo -e " --sync\t\t\t: Sync notes to git repository" echo "" echo -e "if a non option is passed and is a valid note ID, the note will be displayed." } -function configtext() { - cat << __NOWCONF__ -${BASENAME} configuration is: +configtext() { + [ $USEGIT ] && GITUSE="enabled" || GITUSE="disabled" + if [ -n $GITCLIENT ]; then + CLIENTGIT="$( hostname )" + else + CLIENTGIT="$GITCLIENT" + fi + clear + echo -e "${BASENAME} configuration is:" + + echo -e "\tbase directory: ${BASEDIR}/" + echo -e "\tnotes archive: ${NOTESDIR}/" + echo -e "\tnotes database: ${DB}" + echo -e "\trc file: $RCFILE" + echo -e "\tdebug file: /tmp/debug_bash-note.log" + echo + echo -e "\ttext editor: ${EDITOR}" + echo -e "\tterminal: ${TERMINAL}" + echo -e "\tjq executable: ${JQ}" + echo -e "\tPAGER: ${PAGER}" + echo + echo -e "\tGIT: ${GITUSE} - ${GIT}" + echo -e "\tGIT remote: ${GITREMOTE}" + echo -e "\tGIT sync delay: ${GITSYNCDELAY}" + echo -e "\tGIT client name: ${CLIENTGIT}" +} -base directory: ${BASEDIR}/ -notes archive: ${NOTESDIR}/ -notes database: ${DB} -rc file: $RCFILE -debug file: /tmp/debug_bash-note.log +# this function returns a random 2 words title +random_title() { + # Constants + X=0 + DICT=/usr/share/dict/words + OUTPUT="" + + # total number of non-random words available + COUNT=$(cat $DICT | wc -l) + + # while loop to generate random words + while [ "$X" -lt 2 ] + do + RAND=$(od -N3 -An -i /dev/urandom | awk -v f=0 -v r="$COUNT" '{printf "%i\n", f + r * $1 / 16777216}') + OUTPUT+="$(sed `echo $RAND`"q;d" $DICT)" + (("X = X + 1")) + [[ $X -eq 1 ]] && OUTPUT+=" " + done + + echo $OUTPUT +} + +# check if GITCLIENT has been set or set it to the output of hostname +if [ -z "$GITCLIENT" ]; then + GITCLIENT=$( hostname ) +fi +# returns true if the argument provided directory is a git repository +is_git_repo() { + DIR=$1 + if [[ -d $DIR ]]; then + cd $DIR + if git rev-parse 2>/dev/null; then + true + else + false + fi + fi +} -text editor: ${EDITOR} -terminal: ${TERMINAL} -jq executable: ${JQ} -PAGER: ${PAGER} -__NOWCONF__ +# sync local repository to remote +# accepts -f parameter to skip last sync check +gitsync() { + FORCE=$1 + if [[ $USEGIT && -n $GITREMOTE ]]; then + [ $PLAIN == false ] && echo "Syncing notes with git on remote \"$GITREMOTE\"" + NOWSYNC=$(date +%s) + if [[ $FORCE == "-f" ]]; then + $JQ --arg n "$NOWSYNC" '.git["lastpull"] = $n' "$DB" > $TMPDB + mv $TMPDB $DB + cd $BASEDIR + [ $PLAIN == false ] && $GIT pull || $GIT pull -q + else + # LASTSYNC is the last time we synced to the remote, or 0 if it's the first time. + LASTSYNC=$($JQ -r '.git["lastpull"] // 0' "$DB") + SYNCDIFF=$(( ${NOWSYNC} - ${LASTSYNC} )) + if (( $SYNCDIFF > $GITSYNCDELAY )); then + #more than our delay time has passed. We can sync again. + $JQ --arg n "$NOWSYNC" '.git["lastpull"] = $n' "$DB" > $TMPDB + mv $TMPDB $DB + cd $BASEDIR + [ $PLAIN == false ] && $GIT pull || $GIT pull -q + else + # Last synced less than $GITSYNCDELAY seconds ago. We shall wait + [ $PLAIN == false ] && echo "Last synced less than $GITSYNCDELAY seconds ago. We shall wait" + fi + fi + else + # no git, so we just keep going + true + fi +} + +# add note to git and push it to remote +gitadd() { + if [[ $USEGIT && -n $GITREMOTE ]]; then + [ $PLAIN == false ] && echo "Adding note to remote \"$GITREMOTE\"" + cd $BASEDIR + $GIT add . + $GIT commit -m "$(basename $0) - adding note from ${GITCLIENT}" + $GIT push origin master + else + # no git, so we just keep going + true + fi +} + +# edited note added to git and pushed it to remote +gitedit() { + if [[ $USEGIT && -n $GITREMOTE ]]; then + [ $PLAIN == false ] && echo "Editing note on remote \"$GITREMOTE\"" + cd $BASEDIR + $GIT add . + $GIT commit -m "$(basename $0) - ${GITCLIENT} note edited." + $GIT push origin master + else + # no git, so we just keep going + true + fi +} +# add note to git and push it to remote +gitremove() { + NOTE=$1 + FILE=$2 + if [[ $USEGIT && -n $GITREMOTE ]]; then + [ $PLAIN == false ] && echo "Deleting notes from remote \"$GITREMOTE\"" + if [ "all" == $NOTE ];then + echo "Deleting all notes" + cd $BASEDIR + $GIT rm notes/* + $GIT commit -m "$(basename $0) - ${GITCLIENT} removing all notes." + $GIT push origin master + else + local OK=$(check_noteID "$NOTE") + if [[ "$OK" ]]; then + echo "Deleting note ID ${NOTE}" + cd $BASEDIR + $GIT rm notes/${FILE} + $GIT add . + $GIT commit -m "$(basename $0) - ${GITCLIENT} removing note ID ${NOTE}." + $GIT push origin master + fi + fi + else + # no git, so we just keep going + true + fi } -function addnote() { +# check for USEGIT and subsequent variables +if [[ $USEGIT && -n $GITREMOTE ]]; then + # GIT is a go. + if ! is_git_repo $BASEDIR; then + # initializing git repository + cd $BASEDIR + $GIT init + echo "adding all files to git" + $GIT add . + $GIT commit -m "$(basename $0) - initial commit from ${GITCLIENT}" + $GIT remote add origin $GITREMOTE + $GIT push -u origin master + fi +elif [[ $USEGIT && -z $GITREMOTE ]]; then + echo "GITREMOTE variable not set. reverting USEGIT to false" + USEGIT=false +fi + +addnote() { + # attempt syncing before adding a note + gitsync -f # remove eventually existing temp DB file if [[ -f $TMPDB ]]; then rm $TMPDB fi - NOTETITLE="$1" + # RANDOM TITLE + RTITLE=$(random_title) + + if [[ -z $1 ]]; then + read -r -p "Title: " TITLE + case "$TITLE" in + '' ) + NOTETITLE="$RTITLE" + ;; + * ) + NOTETITLE=$TITLE + ;; + esac + fi + + # [[ -z "$1" ]] && NOTETITLE="$RTITLE" || NOTETITLE="$1" echo "adding new note - \"$NOTETITLE\"" # shellcheck disable=SC2086 LASTID=$($JQ '.notes[-1].id // 0 | tonumber' $DB) @@ -221,8 +412,10 @@ function addnote() { # alacritty --class notes --title notes -e /usr/bin/vim ... # shellcheck disable=SC2086,SC2091 $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${NOW}) + # add note to git and push to remote + gitadd } -function backup_data() { +backup_data() { BACKUPDIR="$1" echo "backing up data in $BACKUPDIR" @@ -250,9 +443,9 @@ function backup_data() { fi # ok, we have a backup directory if [ -r $RCFILE ]; then - BCKUP_COMM=$(rsync -avz --progress ${RCFILE}* ${BASEDIR}/* ${BACKUPDIR}) + BCKUP_COMM=$(rsync -avz --progress ${RCFILE}* ${BASEDIR}/ ${BACKUPDIR}) else - BCKUP_COMM=$(rsync -avz --progress ${BASEDIR}/* ${BACKUPDIR}) + BCKUP_COMM=$(rsync -avz --progress ${BASEDIR}/ ${BACKUPDIR}) fi # run the command if [ "$BCKUP_COMM" ]; then @@ -263,7 +456,7 @@ function backup_data() { fi } -function backup_restore() { +backup_restore() { BACKUPDIR="$1" echo "restoring backup from $BACKUPDIR" echo "This will overwrite all your notes and configurations with the backup." @@ -295,6 +488,13 @@ function backup_restore() { fi cp --verbose ${BACKUPDIR}/${BACKUPDB} $DB fi + # restoring git repo subdirectory + if [ -d $BACKUPDIR/.git ]; then + if [ /bin/ls -A ${BASEDIR}/.git ]; then + rm -rf ${BASEDIR}/.git + fi + cp -r --verbose ${BACKUPDIR}/.git ${BASEDIR}/ + fi ;; * ) echo "No changes made. Exiting" @@ -303,7 +503,7 @@ function backup_restore() { esac } -function editnote() { +editnote() { NOTE=$1 # shellcheck disable=SC2155 local OK=$(check_noteID "$NOTE") @@ -321,12 +521,15 @@ function editnote() { echo "editing note $TITLE" # shellcheck disable=SC2086,SC2091 $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${FILE}) + gitedit else echo "note not found" exit 1 fi } -function listnotes() { +listnotes() { + # attempt syncing before listing all notes + gitsync # [ $PLAIN == true ] && echo "output is plain text" || echo "output is colored" if [[ $(ls -A "$NOTESDIR") ]]; then if [ $PLAIN == false ]; then @@ -348,7 +551,7 @@ function listnotes() { echo "no notes yet. You can add your first one with: ${BASENAME} -a \"your note title\"" fi } -function rmnote() { +rmnote() { # remove eventually existing temp DB file if [[ -f $TMPDB ]]; then rm $TMPDB @@ -366,6 +569,7 @@ function rmnote() { mv $TMPDB $DB # shellcheck disable=SC2086 rm $NOTESDIR/* + gitremove "all" echo "Deleted all notes" ;; * ) @@ -379,6 +583,7 @@ function rmnote() { if [ ! "$OK" ]; then echo "invalid note \"$NOTE\"" echo "Use the note ID that you can fetch after listing your notes" + sleep 1 exit 1 fi @@ -392,14 +597,18 @@ function rmnote() { # shellcheck disable=SC2086 mv $TMPDB $DB rm $NOTESDIR/$FILE + gitremove $OK $FILE echo "Deleted note $TITLE" + sleep 1 + exit else echo "note not found" + sleep 1 exit 1 fi fi } -function shownote() { +shownote() { NOTE=$1 # shellcheck disable=SC2155 @@ -417,7 +626,7 @@ function shownote() { fi } # shellcheck disable=SC2006 -GOPT=$(getopt -o hvplr::a::e::d::s:: --long help,version,list,plain,userconf,restore::,backup::,add::,edit::,delete::,show:: -n 'bash-notes' -- "$@") +GOPT=$(getopt -o hvplr:a::e:d:s: --long help,version,list,plain,userconf,showconf,sync,restore:,backup:,add::,edit:,delete:,show: -n 'bash-notes' -- "$@") # shellcheck disable=SC2181 if [ $? != 0 ] ; then helptext >&2 ; exit 1 ; fi @@ -445,70 +654,41 @@ while true; do exit ;; -a | --add ) - case "$2" in - '' ) - read -r -p "Title: " TITLE - ;; - * ) - TITLE=$2 - ;; - esac + TITLE=$2 shift 2 addnote "$TITLE" exit ;; -e | --edit ) - case "$2" in - '' ) - read -r -p "Note ID: " NOTE - ;; - * ) - NOTE=$2 - ;; - esac + NOTE=$2 shift 2 editnote "$NOTE" exit ;; -d | --delete ) - case "$2" in - '' ) - read -r -p "Note ID: " NOTE - ;; - * ) - NOTE=$2 - ;; - esac + NOTE=$2 shift 2 rmnote "$NOTE" exit ;; -s | --show ) - case "$2" in - '' ) - read -r -p "Note ID: " NOTE - ;; - * ) - NOTE=$2 - ;; - esac + NOTE=$2 shift 2 shownote "$NOTE" exit ;; -r | --restore ) - case "$2" in - '' ) - read -r -p "Backup Dir: " RDIR - ;; - * ) - RDIR=$2 - ;; - esac + RDIR=$2 shift 2 backup_restore $RDIR exit ;; + --sync ) + # I'm forcing it because if you run it manually, chances are that you need to. + gitsync -f + shift + exit + ;; --userconf ) export_config # shellcheck disable=SC2317 @@ -516,15 +696,12 @@ while true; do # shellcheck disable=SC2317 exit ;; + --showconf ) + configtext + exit + ;; --backup ) - case "$2" in - '' ) - read -r -p "Backup Dir: " BDIR - ;; - * ) - BDIR=$2 - ;; - esac + BDIR=$2 shift 2 backup_data $BDIR exit