From c2e7aaa4784f75b73827d4f6f12f3c20992de6c3 Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Fri, 28 May 2021 14:44:04 +0000 Subject: [PATCH] Add graph export and ability to resume editing --- notes.sh | 63 ++++++++++++++++++++++++++++++++---- test.sh | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 7 deletions(-) diff --git a/notes.sh b/notes.sh index d9e08de..da3cc7d 100755 --- a/notes.sh +++ b/notes.sh @@ -31,14 +31,13 @@ set -e DATE_FORMAT="%a, %d %b %Y %H:%M:%S %z" PID=$$ BASEDIR=~/Maildir/personal/Notes +CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/notes.sh" +EDITOR="${EDITOR:-vim}" if [ -n "$NOTES_SH_BASEDIR" ]; then BASEDIR="$NOTES_SH_BASEDIR" fi -if [ -z "$EDITOR" ]; then - EDITOR=vim -fi if [ ! -d "$BASEDIR" ]; then mkdir -p "$BASEDIR"/{tmp,new,cur} @@ -81,6 +80,27 @@ uuid() echo } +yesno() { + PROMPT="$1" + DEFAULT="$2" + + if [[ "$DEFAULT" == "y" ]]; then + read -p "$PROMPT [Y/n] " -r CHOICE + if [[ "$REPLY" =~ ^[Nn]$ ]]; then + echo "n" + else + echo "y" + fi + else + read -p "$PROMPT [y/N] " -r CHOICE + if [[ "$REPLY" =~ ^[Yy]$ ]]; then + echo "y" + else + echo "n" + fi + fi +} + get_headers() { FILE="$1" @@ -297,9 +317,21 @@ edit_entry() { ID="$1" FILENAME="$(find_file_by_id "$ID")" - DIR=$(mktemp -d) - unpack_mime "$FILENAME" "$DIR" - "$EDITOR" "$DIR/note.md" + DIR="$CACHE_DIR/$ID" + + if [ -d "$DIR" ] && [ -f "$DIR/note.md" ]; then + RESUME_EDITING=$(yesno "Unsaved changes found for this note. Resume editing?" y) + fi + + if [ "$RESUME_EDITING" != "y" ]; then + rm -rf "$DIR" + mkdir -p "$DIR" + unpack_mime "$FILENAME" "$DIR" + fi + + if ! "$EDITOR" "$DIR/note.md"; then + die "Editor returned non-zero exit code. Leaving the note untouched." + fi UNIX_TIMESTAMP=$(date "+%s") HOSTNAME=$(hostname -s) @@ -312,6 +344,7 @@ edit_entry() { mv "$RESULT" "$BASEDIR/cur/$DEST_FILENAME" rm "$FILENAME" fi + rm -rf "$DIR" } list_entries() { @@ -345,6 +378,14 @@ list_entries() { grep -m2 -r -h "^Subject:\|^X-Note-Id:" "$BASEDIR" | awk "$FILTER" } +export_note() { + ID="$1" + FILENAME="$(find_file_by_id "$ID")" + + DIR="$2" + unpack_mime "$FILENAME" "$DIR" +} + get_raw_graph() { UUID_RE="[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" FILTER="\ @@ -407,7 +448,7 @@ get_graph() { } usage() { - echo "$0 {--new,--list,--edit,--graph,--help}" + echo "$0 {--new,--list,--edit,--export,--graph,--help}" } while (( "$#" )); do @@ -428,6 +469,14 @@ while (( "$#" )); do edit_entry "$2" exit 0 ;; + -E|--export) + if [ -z "$2" ] || [ -z "$3" ]; then + echo "Misssing arguments for $1" + exit 1 + fi + export_note "$2" "$3" + exit 0 + ;; -g|--graph) get_graph exit 0 diff --git a/test.sh b/test.sh index 51d922f..54aecdc 100755 --- a/test.sh +++ b/test.sh @@ -111,9 +111,107 @@ new_note_from_dir() { assert 'echo "$OUTPUT" | grep Subject' "Subject: This is a header" } +list_notes() { + "$BASE_DIR/notes.sh" -n <<- EOF + Subject: header1 + + # This is a body + EOF + "$BASE_DIR/notes.sh" -n <<- EOF + Subject: header2 + + # This is a body + EOF + + OUTPUT="$("$BASE_DIR"/notes.sh -l)" + + assert 'echo "$OUTPUT" | grep -o header1' 'header1' + assert 'echo "$OUTPUT" | grep -o header2' 'header2' +} + +export_note() { + "$BASE_DIR/notes.sh" -n <<- EOF + Subject: header1 + + # This is a body + EOF + NOTE_ID="$(cat "$(pwd)/notes/cur"/* | grep X-Note-Id | cut -d ' ' -f 2)" + + mkdir out + "$BASE_DIR/notes.sh" -E "$NOTE_ID" out + + assert 'cat out/note.md | grep Subject' "Subject: header1" +} + +edit_note() { + "$BASE_DIR/notes.sh" -n <<- EOF + Subject: header1 + + line1 + EOF + NOTE_ID="$(cat "$(pwd)/notes/cur"/* | grep X-Note-Id | cut -d ' ' -f 2)" + + cat > "$(pwd)/editor.sh" <<- EOF + #!/bin/bash + FILENAME="\$1" + echo "line2" >> "\$FILENAME" + EOF + chmod a+x "$(pwd)/editor.sh" + export EDITOR="$(pwd)/editor.sh" + + "$BASE_DIR/notes.sh" -e "$NOTE_ID" + + OUTPUT="$(cat "$(pwd)/notes/cur"/*)" + assert 'echo "$OUTPUT" | grep -o line1' "line1" + assert 'echo "$OUTPUT" | grep -o line2' "line2" +} + +resume_editing() { + "$BASE_DIR/notes.sh" -n <<- EOF + Subject: header1 + + myline1 + EOF + NOTE_ID="$(cat "$(pwd)/notes/cur"/* | grep X-Note-Id | cut -d ' ' -f 2)" + + cat > "$(pwd)/editor.sh" <<- EOF + #!/bin/bash + FILENAME="\$1" + echo "myline2" >> "\$FILENAME" + exit 1 + EOF + chmod a+x "$(pwd)/editor.sh" + export EDITOR="$(pwd)/editor.sh" + + "$BASE_DIR/notes.sh" -e "$NOTE_ID" 2>/dev/null || true + + OUTPUT="$(cat "$(pwd)/notes/cur"/*)" + assert 'echo "$OUTPUT" | grep myline | wc -l' "1" + + cat > "$(pwd)/editor.sh" <<- EOF + #!/bin/bash + FILENAME="\$1" + echo "myline3" >> "\$FILENAME" + EOF + chmod a+x "$(pwd)/editor.sh" + export EDITOR="$(pwd)/editor.sh" + + echo "y" | "$BASE_DIR/notes.sh" -e "$NOTE_ID" + + + OUTPUT="$(cat "$(pwd)/notes/cur"/*)" + assert 'echo "$OUTPUT" | grep -o myline1' "myline1" + assert 'echo "$OUTPUT" | grep -o myline2' "myline2" + assert 'echo "$OUTPUT" | grep -o myline3' "myline3" +} + testcase new_note_from_stdin testcase new_note_from_file testcase new_note_from_dir +testcase list_notes +testcase export_note +testcase edit_note +testcase resume_editing if [[ "$RESULT" == "0" ]]; then echo "All tests passed."