3 Commits
main ... legacy

Author SHA1 Message Date
Jon-William Lewis
57345a790d Merge branch 'legacy' of gitlab.xenami.net:xenami/vns into legacy 2019-04-08 08:59:31 -05:00
Jon-William Lewis
7ecc9e0361 Added old SNS script 2019-04-08 08:59:02 -05:00
Jon-William Lewis
3a757e08c5 Added old SNS script 2019-04-08 08:58:20 -05:00
6 changed files with 316 additions and 494 deletions

View File

@@ -1,3 +0,0 @@
v1.1
Added merge, rename options
Enabled gpg-agent

30
DEBUG
View File

@@ -1,30 +0,0 @@
Vim Note System, v1.1
The following is a table of exit codes
Code In Function Meaning
-----------------------------------------------------
10 vns Invalid argument given
20 sanityCheck Missing dependencies
21 sanityCheck VNS store not initialized
30 rm Insufficient arguments
31 rm Note does not exist
40 create Insufficient arguments
41 create Note already exists
50 edit Insufficient arguments
51 edit Note not found
60 print Insufficient arguments
70 mv Insufficient arguments
71 mv Couldn't read source note
72 mv Destination note already exists
81 merge No output specified
82 merge Output file already exists.
83 merge could not open note

View File

@@ -1,66 +1,8 @@
Vim Note System Simple Note System
================== ==================
## About ## About
Vim Note System is a shell script partially inspired by [pass]. Simple Note System, a script for managing notes inspired in part by "pass" is
vns stores notes as asymmetrically encrypted plaintext using the deprecated in favor of Vim Note System. This version 1.0 copy of Simple Note
vim-gnupg plugin. System is present under the legacy branch of Vim Note System for the purpose
of helping convert old openssl-encrypted SNS notes to GPG format.
VNS, formerly SNS, was originally conceived one morning during an update
to a popular note-taking app. The thought occurred that a note system need
not reinvent the wheel with its own GUI editor and proprietary file format,
but instead could use the tools already provided by the operating system.
vim note system
==================
usage: vns [-cedlp] <notebook/section/name>
vns [-hi]
vns git ...
-c | --create : Create note
-d | --delete : Delete note
-e | --edit : Open note for editing
-h | --help : Display this message
-i | --init : Initialize note store"
-l | --list : List all notes in <notebook>
-p | --print : Print note to console
## Installing
### Dependencies
* vim
* gpg2
* tree
* git
** Note: ** Install [vim-gnupg] before use. vns *does* check this, but only *after*
a note has been created.
To install, place `vns` in your path, and run `vns -i`.
vim note system will establish its note store under ~/.config/vns.
The location of the store may be changed on line 6.
To uninstall, remove the files you copied. Notes will still exist in ~/.config/vns
## Tips and Tricks
* To list all notes in all notebooks, simply run `vns`.
* Notes beginning with . will not appear in the listing
## Credits
The code here is my own, however much of VNS's design and behavior was
influenced by [pass].
## License
Vim Note System is licensed under the terms of the GNU General Public License
Version 2, as detailed in `LICENSE`.
## Bugs and Feature Requests
If something seems off, or just doesn't work, please open an issue and I'll look
into it.
Feature requests should be submitted to jon.lewis@xenami.net with [SNS Feature Request]
in the subject line.
[pass]: http://passwordstore.org
[vim-gnupg]:http://www.vim.org/scripts/script.php?script_id=3645

View File

@@ -1,28 +0,0 @@
# Simple Note System, version 2
## Error Code Reference
### General Codes
| Name | Code | Meaning |
|--------------|------|---------------------------------------|
| ERR_NO_STORE | 5 | the SNS store needs to be initialized |
| | | |
| ERR_NO_OPTS | 10 | No mode argument was specified |
| | | |
| ERR_NO_ARGS | 11 | A mode requiring an argument was |
| | | specified without an argument |
| | | |
### Encryption-related codes
|Name | Code | Meaning |
|------------|------|-----------------------------------------|
| ERR_NO_GPG | 100 | Encryption is enabled, but GPG is not |
| | | installed |
| | | |
| ERR_NO_KEY | 110 | Encryption is enabled, but no recipient |
| | | was specified |
### Creation-related codes
|Name | Code | Meaning |
|-----------------|------|------------------------------------|
| ERR_NOTE_EXiSTS | 200 | The specified note already exists |
| ERR_NOTE_NO_READ| 205 | The specified note cannot be read |

311
sns.sh Normal file
View File

@@ -0,0 +1,311 @@
#!/bin/bash
#==========================================================
# Simple Note System, v1.0
# Copyright 2014, Xenese Labs/Sicron-Perion XNF
#==========================================================
PROD_STR="Simple Note System"
VER_STR=v1.0
#==============================================================================
# Section: Helper Functions
#==============================================================================
function writeconf {
cat > $HOME/.sns << EOF
#==========================================================
# Simple Note System Config, v1.0
# Copyright 2014, Xenese Labs/Sicron-Perion XNF
#==========================================================
#Directory where notes will be stored
BASEDIR=$HOME/notes
#File extension to use (for listing notes)
EXT=note
#Preferred Editor
EDITOR=vim
#Encryption
#WARNING: ANY PREVIOUSLY UNENCRYPTED NOTES WILL BE LOST
ENCRYPTION="FALSE"
ENC_KEY=""
EOF
chmod 600 $HOME/.sns
}
function help {
echo ""
echo "usage: sns [-ce] NAME NOTEBOOK SECTION"
echo " sns [-d ] NAME NOTEBOOK SECTION"
echo " sns [-l ] NOTEBOOK"
echo " sns [-w ]"
echo ""
echo " -c | --create : Create note"
echo " -d | --delete : Delete note"
echo " -e | --edit : Open note for editing"
echo " -l | --list : List all notes in NOTEBOOK"
echo " -w | --wconf : Write default configuration to ~/.sns (useful for Encryption)"
echo ""
}
function pause {
read -p " Press [Enter] to continue."
echo ""
}
#==============================================================================
# End Section: Helper Functions
#==============================================================================
#==============================================================================
# Section: Configuration
#==============================================================================
if [ -r $HOME/.sns ]; then
source $HOME/.sns
else
BASEDIR=$HOME/notes
EDITOR=vim
EXT=note
fi
if [ "$ENCRYPTION" == "TRUE" ]; then
if [ -z "$ENC_KEY" ]; then
ERR_NO_KEY="TRUE"
ENCRYPTION="FALSE"
pause
fi
command -v openssl >/dev/null 2>&1 || { ERR_NO_SSL="TRUE"; ENCRYPTION="FALSE"; }
fi
if [ "$ENCRYPTION" == "TRUE" ]; then
PROD_STR="Simple Note System (Encryption Enabled)"
EXT="$EXT.enc"
if [ ! -d ~/.tmp ]; then
mkdir -p ~/.tmp
fi
fi
echo "$PROD_STR, $VER_STR"
if [ -n "$ERR_NO_SSL" ]; then
echo >&2 " Warning: OpenSSL not installed. Encryption disabled."
fi
if [ -n "$ERR_NO_KEY" ]; then
echo " Warning: No encryption key was provided. Encryption disabled."
fi
if [ -n "$ERR_NO_SSL" -o -n "$ERR_NO_KEY" ]; then
pause
fi
#==============================================================================
# End Section: Read Configuration
#==============================================================================
#==============================================================================
# Section: Argument Parsing
#==============================================================================
NAME=""
NOTEBOOK=""
SECTION=""
if [ -z "$1" ]; then #If no input was given, print help
help
exit
else #Assume the user wants to do something.
ARGS=( "$@" )
for ARG in ${ARGS[@]};do
if [ "$ARG" = "-c" -o $ARG == "--create" ]; then
CREATE="TRUE"
elif [ "$ARG" = "-d" -o $ARG == "--delete" ]; then
DELETE="TRUE"
elif [ "$ARG" = "-e" -o $ARG == "--edit" ]; then
EDIT="TRUE"
elif [ "$ARG" = "-ce" -o $ARG == "-ec" ]; then
EDIT="TRUE"
CREATE="TRUE"
elif [ "$ARG" == "-l" -o "$ARG" == "--list" ]; then #If user asks for list, print list
LIST="TRUE"
elif [ "$ARG" == "-h" -o "$ARG" == "--help" ]; then #If user asks for help, print help
help
exit
elif [ "$ARG" == "-w" -o "$ARG" == "--wconf" ]; then #If user wants to write config, write config
writeconf
exit
else
if [ -z "$NAME" -a -n $ARG ]; then
NAME=$ARG
echo "Name: $NAME"
elif [ -z "$NOTEBOOK" -a -n $ARG ]; then
NOTEBOOK=$ARG
echo "Notebook: $NOTEBOOK"
elif [ -z "$SECTION" -a -n $ARG ]; then
SECTION=$ARG/
echo "Section: $SECTION"
fi
fi
done
fi
#==============================================================================
# End Section: Argument Parsing
#==============================================================================
#==============================================================================
# Section: Main
#==============================================================================
NOTEDIR=$BASEDIR/$NOTEBOOK/$SECTION
NOTE=$NOTEDIR$NAME.$EXT
if [ "$ENCRYPTION" == "TRUE" ]; then
NOTE=$NOTE.tmp
fi
#==========================================================================
# Subection: List
#==========================================================================
if [ -n "$LIST" ]; then
NOTEBOOK="$NAME" #In case of a list command, arg parsing fails.
if [ -z "$NOTEBOOK" ]; then
echo " ERROR: Insufficient arguments"
help
exit
else
if [ -d "$BASEDIR"/"$NOTEBOOK" ]; then
echo ""
printf "Notes in $(basename $NOTEBOOK):"
echo ""
#find $BASEDIR/$NOTEBOOK -name "*.$EXT" -print0 | sed s:$BASEDIR/$NOTEBOOK/:" ":g | sed -e s:$EXT::g | tr "." " "
NOTES=( $(find $BASEDIR/$NOTEBOOK -name "*.$EXT" -print0 | sed s:$BASEDIR/$NOTEBOOK/:" ":g | sed -e s:$EXT::g | tr "." " " | tr "/" " ") )
let i=0
for NOTE in ${NOTES[@]}; do
if [ -d $BASEDIR/$NOTEBOOK/$NOTE ]; then
if [ "$LAST_SECTION" != "$NOTE" ]; then
printf " Section: $NOTE\n"
fi
LAST_SECTION=$NOTE
else
#if [ $(($i % 1)) -eq 0 ]; then
# printf "\n "
#fi
printf " $NOTE\n"
fi
let i++
done
printf "\n"
else
echo ""
echo "ERROR: Notebook $NOTEBOOK does not exist."
echo ""
fi
fi
exit
fi
#======================================================================
# Sanity Check - Actions below require a valid $NAME and $NOTEBOOK
#======================================================================
if [ -z "$NAME" -o -z "$NOTEBOOK" ]; then
if [ -z "$NAME" -o -z "$NOTEBOOK" ]; then
echo " ERROR: Insufficient arguments"
help
exit
fi
fi
#==========================================================================
# Subection: Delete
#==========================================================================
if [ "$DELETE" == "TRUE" ]; then
if [ -e $NOTE -o -e ${NOTE%.*} ]; then
if [ "$ENCRYPTION" == "TRUE" ]; then
rm ${NOTE%.*}
else
rm $NOTE
fi
echo ""
echo "Deleted note: $NOTEBOOK/$SECTION$NAME."
exit
else
echo ""
echo "ERROR: Note $NOTEBOOK/$SECTION$NAME does not exist."
exit
fi
fi
#==========================================================================
# Subection: Create
#==========================================================================
if [ -z "$CREATE" -a -z "$EDIT" ]; then #If no action specified, print help and exit
help
exit
else
if [ "$CREATE" == "TRUE" ]; then
if [ -e $NOTE -o -e ${NOTE%.*} ]; then
echo ""
echo "ERROR: Note already exists"
echo "Hint: use -e to edit the note."
echo ""
exit
else
#Create any necessary folders
mkdir -p $NOTEDIR
#Fill in title
echo "TITLE: $NAME" > $NOTE
#Fill the second line with the date
echo "DATE: $(date)" >> $NOTE
if [ "$ENCRYPTION" == "TRUE" ]; then
if [ $EDIT == "FALSE" ]; then
openssl enc -aes-256-cbc -salt -in $NOTE -out ${NOTE%.*} -pass pass:$ENC_KEY
fi
fi
fi
fi
#==========================================================================
# Subection: Edit
#==========================================================================
if [ "$EDIT" == "TRUE" ]; then
if [ -r "$NOTE" -o -r ${NOTE%.*} ]; then
if [ -z "$CREATE" ]; then
if [ "$ENCRYPTION" == "TRUE" ]; then
openssl enc -d -aes-256-cbc -in ${NOTE%.*} -pass pass:$ENC_KEY > $NOTE
fi
echo "" >> $NOTE
echo "EDIT $(date)" >> $NOTE
fi
$EDITOR $NOTE
if [ "$ENCRYPTION" == "TRUE" ]; then
openssl enc -aes-256-cbc -salt -in $NOTE -out ${NOTE%.*} -pass pass:$ENC_KEY
rm $NOTE
fi
else
echo ""
echo "ERROR: Note cannot be opened for editting."
echo ""
fi
fi
fi
exit

370
vns
View File

@@ -1,370 +0,0 @@
#!/usr/bin/env bash
# Vim Note System v1.1, a simple script for managing encrypted plaintext notes
# Copyright (C) 2018 Jon Lewis
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
set -euo pipefail # Terminate the script if anything goes wrong
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
readonly VNS_PRODUCT="Vim Note System, v1.1" # String to print for reports
readonly VNS_STORE="$HOME/.config/vns" # Where vns expects its note store
readonly GPG_TTY="$(tty)" # Sets up gpg-agent for use
vns_raise (){
# raise (message) (exit code)
# Prints error (message) to stderr, then exits with (exit code)
local -r VNS_RED_COLOR='\033[0;31m'
local -r VNS_RESET_COLOR='\033[0m'
printf "%s, %s\\n\\n" "$VNS_PRODUCT"
printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\\n" "$1" 1>&2
exit "$2"
}
vns_checkDeps (){
# checkDeps
# Prints a list of unbound variables
readonly VNS_DEPS=("vim" "gpg2" "tree" "git")
for DEP in "${VNS_DEPS[@]}"; do
if test ! -e "$(which "$DEP" 2>/dev/null)"; then
printf "%s " "$DEP"
fi
done
}
vns_sanityCheck () {
# sanityCheck
# Terminates script if environment is not suitable for vns
# --- Dependencies ---
# Get list of missing dependencies
local MISSING; MISSING="$(vns_checkDeps)"
# If that list is not empty, inform the user and exit on code 20
if [ -n "$MISSING" ]; then
vns_raise "Missing Dependencies: $MISSING" 20
fi
# --- Store ---
# Verify that the note store has been initialized
if [ ! -d "$VNS_STORE" ]; then
vns_raise "The vns store needs to be initialized (hint: -i)" 21
fi
}
vns_init () {
# initStore
# Prepares $VNS_STORE for use
if [ -d "$VNS_STORE/.git" ]; then
vns_raise "Store already initialized" 2;
fi
mkdir -p "$VNS_STORE"
cd "$VNS_STORE" || exit
git init >/dev/null
}
vns_printHelp (){
# printHelp
# Prints help information to stdout
printf "%s" "usage: vns [-cedlp] <notebook/section/name>"
printf "\\n%s" " vns -I"
printf "\\n%s" " vns -h"
printf "\\n%s" " vns git ..."
printf "\\n"
printf "\\n%s" " -c : Create note"
printf "\\n%s" " -d : Delete note"
printf "\\n%s" " -e : Open note for editing"
printf "\\n%s" " -h : Display this message"
printf "\\n%s" " -i : import file as note"
printf "\\n%s" " -I : Initialize note store"
printf "\\n%s" " -l : List all notes in <notebook>"
printf "\\n%s" " -m : Merge two or more notes"
printf "\\n%s" " -p : Print note to console"
printf "\\n\\n"
}
vns_list () {
# list (notebook)
# Prints a tree containing all notes in the notebook
# If no notebook is specified, the entire store is used
numNotes () { find . -name "*.gpg" \( ! -regex '.*/\..*' \) | wc -l; }
# Check for default behavior
if [ -z "${*:1:1}" ]; then
readonly NOTEBOOK=""
if [ "$(numNotes)" != "0" ];then
printf "%s\\n" "Store"
fi
else
readonly NOTEBOOK="$1"
printf "%s\\n" "$1"
fi
tree -C --noreport --prune "$VNS_STORE/$NOTEBOOK"\
| tail -n +2\
| sed s/\.gpg//g
}
vns_rm () {
# rm (note)
# removes (note) from the store
local -r VNS_BLUE_COLOR='\033[0;34m'
local -r VNS_RESET_COLOR='\033[0m'
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 30; fi
# Verify the note exists
if [ ! -r "$VNS_STORE/$1.gpg" ]; then
vns_raise "Note does not exist" 31;
fi
# Delete the Note
git rm "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Deleted $1" > /dev/null
# Report success
printf "%s, %s\\n\\n" "$VNS_PRODUCT"
printf "$VNS_BLUE_COLOR!$VNS_RESET_COLOR - %s\\n" "Deleted $VNS_STORE/$1"
}
vns_create () {
# create (note)
# Create a new note and open it for editing
local -r VNS_RED_COLOR='\033[0;31m'
local -r VNS_RESET_COLOR='\033[0m'
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 40; fi
# Refuse to overwrite a note
if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note already exists" 41; fi
# If the note belongs to a new notebook, create the notebook
if [ ! -d "$(dirname "$1")" ]; then mkdir -p "$VNS_STORE/$(dirname "$1")"; fi
# Create-Edit the note
vim "$VNS_STORE/$1.gpg"
# Warn the user if the note failed to encrypt
if ! grep "PGP" <<< "$(file "$VNS_STORE/$1.gpg")" > /dev/null; then
printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\\n %s\\n"\
"The created note was not encrypted."\
"Check your vim-gnupg setup."
fi
# Update Git
git add "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Added $1" > /dev/null
}
vns_edit () {
# edit (note)
# Open (note) for editing in Vim
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 50; fi
# Refuse to edit non-existent notes
if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note not found: $1" 51; fi
# Edit the specified note
vim "$VNS_STORE/$1.gpg"
# Update Git
git add "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Edited $1" > /dev/null
}
vns_import () {
# import (src) (dest)
# If src is the path to a file, and dest is a valid note name,
# import src dest copies an encrypted version of src to the note store
if [ -z "${*:1:1}" ]; then
vns_raise "No source file specified" 90
elif [ -z "${*:2:2}" ]; then
vns_raise "No destination name specified" 91
elif [ ! -f "$1" ]; then
vns_raise "Cannot read $1" 92
elif [ -f "$VNS_STORE/$2" ]; then
printf "%s" "Note already exists. Overwrite? (Y/N) "
local response; read -r response
case "$response" in
Yy)
rm "$VNS_STORE/$2";;
*)
vns_raise "User declined overwrite" 0;;
esac
fi
printf "%s:" "Specify GPG Public Key: "
local gpg_key; read -r gpg_key
gpg2 -r "$gpg_key" -o "$VNS_STORE/$2.gpg" -e "$1"
git add "$VNS_STORE/$2.gpg"
git commit -m "Imported file $1 as $2"
}
vns_print () {
# print (note)
# print the given note to stdout
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi
# Decrypt the specified note
gpg2 -d "$VNS_STORE/$1.gpg"
}
vns_mv () {
# mv (src) (dest)
# If (src) is a note in the vns store, mv src dest moves src to dest
if [ -z "${*:2}" ]; then vns_raise "Insufficient arguments" 70; fi
if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Cannot read $1" 71; fi
if [ -r "$VNS_STORE/$2.gpg" ]; then vns_raise "Note $2 already exists" 72; fi
git mv "$VNS_STORE/$1.gpg" "$VNS_STORE/$2.gpg"
}
vns_merge () {
# merge (output) (notes[])
# If notes[] is an array of note names and output is a new note name,
# merge (output) (notes[]) concatenates notes[] into output.
if [ -z "${*:1}" ]; then vns_raise "No output specified" 81; fi
if [ -z "${*:2}" ]; then vns_raise "No inputs specified" 84; fi
if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Output file already exists." 82; fi
# Make output file
if [ ! -r "$VNS_STORE/$2.gpg" ]; then vns_raise "Could not read $2" 83; fi
cp "$VNS_STORE/$2.gpg" "$VNS_STORE/$1.gpg"
local -r GPG_RECIP="$(gpg --list-only -v -d "$VNS_STORE/$1.gpg" 2>&1 | cut -f 5 -d " ")"
for note in "${@:3}"; do
if [ ! -r "$VNS_STORE/$note.gpg" ]; then
rm "$VNS_STORE/$1.gpg"
vns_raise "Could not read $note" 83;
fi
gpg2 --batch --yes -r "$GPG_RECIP" -o "$VNS_STORE/$1.gpg" -e <<< "$(gpg2 -d "$VNS_STORE/$1.gpg") $(gpg2 -d "$VNS_STORE/$note.gpg")"
done
for note in "${@:2}"; do
git rm "$VNS_STORE/$note.gpg"
done
git add "$VNS_STORE/$1.gpg"
git commit -m "merged files ${*:2} into $1"
}
vns_duplicate () {
if [ -z "${*:1:1}" ]; then
vns_raise "No source note specified" 100
elif [ -z "${*:2:2}" ]; then
vns_raise "No destination name specified" 101
elif [ ! -f "$VNS_STORE/$1" ]; then
vns_raise "Cannot read $1" 102
elif [ -f "$VNS_STORE/$2" ]; then
printf "%s" "Note already exists. Overwrite? (Y/N) "
local response; read -r response
case "$response" in
Yy)
rm "$VNS_STORE/$2";;
*)
vns_raise "User declined overwrite" 0;;
esac
fi
cp "$VNS_STORE/$1.gpg" "$VNS_STORE/$2.gpg"
git add "$VNS_STORE/$2"
}
vns () {
# Bypass sanity check if told to initialize store
if [ "$*" != "-i" ]; then
vns_sanityCheck;
# Change Directory to Store for Git passthrough
cd "$VNS_STORE" || exit;
fi
# Default action is to list all notes
if [ -z "${*:1:1}" ]; then vns_list ""; exit 0; fi
# List of valid arguments
declare -A -r ACTIONS=( ["-c"]="vns_create" ["-d"]="vns_rm"\
["-e"]="vns_edit" ["-l"]="vns_list"\
["-h"]="vns_printHelp" ["-I"]="vns_init"\
["-i"]="vns_import" ["-m"]="vns_merge"\
["-p"]="vns_print" ["-r"]="vns_mv"\
["-u"]="vns_duplicate" ["git"]="git" )
# If given an invalid argument, inform the user and exit on code 10
# Otherwise, perform the corresponding action
if ! test "${ACTIONS["$1"]+isset}"; then
vns_raise "Invalid argument: $1" 10
else
"${ACTIONS["$1"]}" "${@:2}"
fi
exit 0;
}
vns "$@"