X-Git-Url: https://git.danix.xyz/?a=blobdiff_plain;f=notes.sh;h=eba388f05287913e7ff31d484a87d4def21995b9;hb=fe606f6a0769e27ffd4b6889231f561d417e23f4;hp=84e06b7425ed799d3e17cb2289624a88fa108cca;hpb=53f2ed579b9f9f4883a143b272d43e1479fdb9b3;p=bash-notes.git diff --git a/notes.sh b/notes.sh old mode 100644 new mode 100755 index 84e06b7..eba388f --- a/notes.sh +++ b/notes.sh @@ -1,21 +1,39 @@ #! /bin/bash +# bash-notes © 2023 by danix is licensed under CC BY-NC 4.0. +# To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ + # set -ex PID=$$ VERSION="0.1" +set_defaults() { +# Binaries to use EDITOR=${EDITOR:-/usr/bin/vim} TERMINAL=${TERMINAL:-/usr/bin/alacritty} -JQ=$(which jq) +# 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 +TERM_OPTS="--class notes --title notes -e " +JQ=${JQ:-/usr/bin/jq} +# base directory for program files BASEDIR=${BASEDIR:-~/.local/share/bash-notes} -RCFILE=${RCFILE:-~/.bash-notes.rc} +# notes database in json format DB=${BASEDIR}/db.json +# directory containing the actual notes NOTESDIR=${BASEDIR}/notes +} # end set_defaults, do not change this line. + +set_defaults + +# Do not edit below this point +RCFILE=${RCFILE:-~/.config/bash-notes.rc} TMPDB=/tmp/db.json BASENAME=$( basename $0 ) +NOW=$(date +%s) if [ ! -x $JQ ]; then echo "jq not found in your PATH" @@ -45,49 +63,169 @@ fi # create PIDFILE echo $PID > $PIDFILE +# check if input is a number, returns false or the number itself +function check_noteID() { + IN=$1 + case $IN in + ''|*[!0-9]*) + return 1 + ;; + *) + echo $IN + ;; + esac +} + function helptext() { - echo "Parameters are:" - echo " -h : This help text" - echo " -s : specify directory where to store all notes." - echo " -e : specify EDITOR for this session only." - echo " -l : List existing notes" - echo " -a : Add new note" - echo " -m : Modify note" - echo " -d : Modify date for note" - echo " -r : Remove note" - echo " -v : Print version" + echo "Usage:" + echo " $0 [PARAMS] ..." + echo "" + cat << __NOWCONF__ +${BASENAME} configuration is: + +base directory: ${BASEDIR}/ +notes archive: ${NOTESDIR}/ +notes database: ${DB} +rc file: $RCFILE + +text editor: ${EDITOR} +terminal: ${TERMINAL} +jq executable: ${JQ} +__NOWCONF__ + + echo "" + echo "${BASENAME} parameters are:" + echo " -h | --help : This help text" + echo " -p | --plain : Output is in plain text" + echo " (without this option the output is formatted)" + echo " (this option must precede all others)" + echo " -l | --list : List existing notes" + echo " -a | --add [\"\"] : Add new note" + echo " -e | --edit [<note>] : Edit note" + echo " -d | --delete [<note> | all] : Delete single note or all notes at once" + echo " -v | --version : Print version" + echo " --userconf : Export User config file" + echo "" } function addnote() { + # remove eventually existing temp DB file + if [[ -f $TMPDB ]]; then + rm $TMPDB + fi + NOTETITLE="$1" echo "adding new note - \"$NOTETITLE\"" - NOW=$(date +%s) - LASTID=$($JQ '.notes[-1].id | tonumber' $DB) - [ null == $LASTID ] && LASTID=0 + LASTID=$($JQ '.notes[-1].id // 0 | tonumber' $DB) + # [ "" == $LASTID ] && LASTID=0 NOTEID=$(( $LASTID + 1 )) touch ${NOTESDIR}/${NOW} $JQ --arg i "$NOTEID" --arg t "$NOTETITLE" --arg f "$NOW" '.notes += [{"id": $i, "title": $t, "file": $f}]' "$DB" > $TMPDB mv $TMPDB $DB - $(${TERMINAL} --class notes --title notes -e ${EDITOR} ${NOTESDIR}/${NOW}) + # example for alacritty: + # alacritty --class notes --title notes -e /usr/bin/vim ... + $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${NOW}) } function listnotes() { - echo "list all notes" + # [ $PLAIN == true ] && echo "output is plain text" || echo "output is colored" + if [[ $(ls -A $NOTESDIR) ]]; then + if [ $PLAIN == false ]; then + echo "listing all notes" + echo "" + fi + [ $PLAIN == false ] && echo "[ID] [TITLE] [CREATED]" + for i in ${NOTESDIR}/*; do + local fname=$(basename $i) + DATE=$(date -d @${fname} +"%d/%m/%Y %R %z%Z") + TITLE=$($JQ -r --arg z $(basename $i) '.notes[] | select(.file == $z) | .title' $DB) + ID=$($JQ -r --arg z $(basename $i) '.notes[] | select(.file == $z) | .id' $DB) + [ $PLAIN == false ] && echo "[${ID}] ${TITLE} ${DATE}" || echo "${ID} - ${TITLE} - ${DATE}" + done + else + echo "no notes yet. You can add your first one with: ${BASENAME} -a \"your note title\"" + fi } function editnote() { - echo "edit note \"${1}\"" -} - -function datenote() { - echo "edit date for note \"${1}\"" - # FILEDATE=$(date -d @$NOW +%d/%m/%Y_%T) + NOTE=$1 + local OK=$(check_noteID $NOTE) + if [ ! $OK ]; then + echo "invalid note \"$NOTE\"" + exit 1 + fi + TITLE=$($JQ --arg i $OK '.notes[] | select(.id == $i) | .title' $DB) + FILE=$($JQ -r --arg i $OK '.notes[] | select(.id == $i) | .file' $DB) + if [ "$TITLE" ]; then + echo "editing note $TITLE" + $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${FILE}) + else + echo "note not found" + exit 1 + fi } function rmnote() { + # remove eventually existing temp DB file + if [[ -f $TMPDB ]]; then + rm $TMPDB + fi + NOTE=$1 - echo "removing note $NOTE" + if [ "all" == $NOTE ]; then + echo "You're going to delete all notes." + read -r -p "Do you wish to continue? (y/N) " ANSWER + case $ANSWER in + y|Y ) + $JQ 'del(.notes[])' $DB > $TMPDB + mv $TMPDB $DB + rm $NOTESDIR/* + echo "Deleted all notes" + ;; + * ) + echo "Aborting, no notes were deleted." + exit 1 + ;; + esac + else + local OK=$(check_noteID $NOTE) + if [ ! $OK ]; then + echo "invalid note \"$NOTE\"" + exit 1 + fi + + TITLE=$($JQ --arg i $OK '.notes[] | select(.id == $i) | .title' $DB) + FILE=$($JQ -r --arg i $OK '.notes[] | select(.id == $i) | .file' $DB) + if [ "$TITLE" ]; then + $JQ -r --arg i $OK 'del(.notes[] | select(.id == $i))' $DB > $TMPDB + mv $TMPDB $DB + rm $NOTESDIR/$FILE + echo "Deleted note $TITLE" + else + echo "note not found" + exit 1 + fi + fi +} + +function export_config() { + if [ -r ${RCFILE} ]; then + echo "Backing up current '${RCFILE}'...." + mv -f ${RCFILE} ${RCFILE}.$(date +%Y%m%d_%H%M) + fi + echo "Writing '${RCFILE}'...." + sed -n '/^set_defaults() {/,/^} # end set_defaults, do not change this line./p' $0 \ + | grep -v set_defaults \ + | sed -e 's/^\([^=]*\)=\${\1:-\([^}]*\)}/\1=\2/' \ + > ${RCFILE} + if [ -r ${RCFILE} ]; then + echo "Taking no further action." + exit 0 + else + echo "Could not write '${RCFILE}'...!" + exit 1 + fi } # we should expand on this function to add a sample note and explain a little bit @@ -111,15 +249,16 @@ jq executable: ${JQ} case $ANSWER in y|Y ) mkdir -p $NOTESDIR - cat << "__EOL__" > ${DB} + cat << __EOL__ > ${DB} { + "params": { + "version": "${VERSION}", + "dbversion": "${NOW}" + }, "notes": [] } __EOL__ - ;; - n|N ) - echo "No changes made. Exiting" - exit + echo; echo "All done, you can now write your first note." ;; * ) echo "No changes made. Exiting" @@ -136,7 +275,7 @@ fi # NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this # separately; see below. -GOPT=`getopt -o hvla:m:d:r: --long help,version,list,add:,modify:,date:,remove:,editor:,storage: \ +GOPT=`getopt -o hvpla:e:d: --long help,version,list,plain,userconf,add:,edit:,delete:,editor:,storage: \ -n 'bash-notes' -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi @@ -144,6 +283,8 @@ if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$GOPT': they are essential! eval set -- "$GOPT" +PLAIN=false + while true; do case "$1" in -h | --help ) @@ -154,6 +295,10 @@ while true; do echo $BASENAME v${VERSION} exit ;; + -p | --plain ) + PLAIN=true + shift + ;; -l | --list ) listnotes exit @@ -163,34 +308,24 @@ while true; do shift 2 addnote "$TITLE" ;; - -m | --modify ) + -e | --edit ) NOTE="$2" shift 2 editnote "$NOTE" ;; - -d | --date ) - NOTE="$2" - shift 2 - datenote "$NOTE" - ;; - -r | --remove ) + -d | --delete ) NOTE="$2" shift 2 rmnote "$NOTE" ;; - --editor ) - EDITOR="$2" - shift 2 - echo "changed EDITOR TO \"$EDITOR\"" - ;; - --storage ) - BASEDIR="$2" - shift 2 - echo "changed BASEDIR TO \"$BASEDIR\"" - # firstrun + --userconf ) + export_config + echo "config exported to \"$RCFILE\"" + exit ;; -- ) - shift; break + shift + break ;; * ) break