280 lines
5.9 KiB
Bash
Executable File
280 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
VERSION=1.1.0
|
|
|
|
# Retrieve script directory (not following link)
|
|
SCRIPT="${BASH_SOURCE[0]}"
|
|
SCRIPT_DIR="$( cd "$( dirname "${SCRIPT}" )" && pwd )"
|
|
INVOCATION_DIR=`pwd`
|
|
|
|
# Retrieve script name (follow link)
|
|
PROG=`basename "$0"`
|
|
|
|
CONFIGFILE=".${PROG}.conf"
|
|
|
|
JOPLIN_DIR=
|
|
CLIPPER_TOKEN=
|
|
CLIPPER_PORT=
|
|
|
|
TMPFILE=`mktemp "${TMPDIR:-/tmp/}$PROG.XXXXXXXX"`
|
|
|
|
# on macOS, the default getopt is a useless piece of shit
|
|
# install getopt via MacPorts or brew and put it in the PATH before /usr/bin
|
|
if [ "`getopt -V |cut -d\" \" -f1`" != "getopt" ]; then
|
|
echo "Error: getopt not compatible enough."
|
|
exit 1
|
|
fi
|
|
|
|
trap cleanup 0 1 2 3 6 15
|
|
|
|
function cleanup {
|
|
if [ -a "$TMPFILE" ]; then
|
|
unlink "$TMPFILE"
|
|
fi
|
|
}
|
|
|
|
function eexit {
|
|
cleanup
|
|
trap - 0 1 2 3 6 15
|
|
exit $1
|
|
}
|
|
|
|
function usage {
|
|
echo "usage: ${PROG} [-c CONFIGFILE] [-f] [-q|--quiet] [-n|--dry-run] [-d|--debug] [-V|--version] [-h] [--help]"
|
|
}
|
|
|
|
function long_usage {
|
|
echo "${PROG} - remove orphaned resources in Joplin"
|
|
echo ""
|
|
usage
|
|
echo ""
|
|
echo " -c CONFIGFILE "
|
|
echo " use CONFIGFILE, instead of searching the default locations: "
|
|
echo " $SCRIPT_DIR/$CONFIGFILE "
|
|
echo " $HOME/$CONFIGFILE "
|
|
echo " The first file found is used. "
|
|
echo ""
|
|
echo " -f "
|
|
echo " run without confirmation "
|
|
echo ""
|
|
echo " -q, --quiet "
|
|
echo " do not print informational messages "
|
|
echo " (errors will be shown) "
|
|
echo ""
|
|
echo " -n, --dry-run "
|
|
echo " only show orphaned resources (do not actually delete them) "
|
|
echo " implies -f "
|
|
echo ""
|
|
echo " -d, --debug "
|
|
echo " print debug information "
|
|
echo ""
|
|
echo " -V, --version "
|
|
echo " version information "
|
|
echo ""
|
|
echo " -h "
|
|
echo " usage information "
|
|
echo ""
|
|
echo " --help "
|
|
echo " this help "
|
|
echo ""
|
|
}
|
|
|
|
cflag=0
|
|
fflag=0
|
|
qflag=0
|
|
nflag=0
|
|
dflag=0
|
|
Vflag=0
|
|
hflag=0
|
|
hlflag=0
|
|
|
|
options=$(getopt -n $PROG -q -o c:fnqdVh -l help,version,debug,dry-run,quiet -- "$@")
|
|
if [ $? != 0 ]
|
|
then
|
|
echo "${PROG}: Error: unrecognized option $1"
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
eval set -- "$options"
|
|
|
|
while [ $# -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-c)
|
|
cflag=1
|
|
carg=$2
|
|
shift;;
|
|
-f)
|
|
fflag=1;;
|
|
-q|--quiet)
|
|
qflag=1;;
|
|
-n|--dry-run)
|
|
nflag=1;;
|
|
-V|--version)
|
|
Vflag=1;;
|
|
-d|--debug)
|
|
dflag=1;;
|
|
-h)
|
|
hflag=1;;
|
|
--help)
|
|
hlflag=1;;
|
|
--)
|
|
shift; break;;
|
|
*)
|
|
exit;
|
|
break;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ "$hflag" == "1" ]
|
|
then
|
|
usage
|
|
exit
|
|
fi
|
|
|
|
if [ "$hlflag" == "1" ]
|
|
then
|
|
long_usage
|
|
exit
|
|
fi
|
|
|
|
if [ "$nflag" == "1" ]
|
|
then
|
|
fflag=1
|
|
fi
|
|
|
|
if [ "$Vflag" == "1" ]
|
|
then
|
|
echo "$PROG $VERSION"
|
|
exit
|
|
fi
|
|
|
|
function debug {
|
|
if [ "$dflag" == "1" ]; then
|
|
echo "[debug] $1"
|
|
fi
|
|
}
|
|
|
|
function info {
|
|
if [ "$qflag" != "1" ]; then
|
|
echo "$1"
|
|
fi
|
|
}
|
|
|
|
function info-n {
|
|
if [ "$qflag" != "1" ]; then
|
|
echo -n "$1"
|
|
fi
|
|
}
|
|
|
|
function noConfigFound {
|
|
FN=' '
|
|
if [ ! -z "$1" ]; then
|
|
FN=" '$1' "
|
|
fi
|
|
echo "Error: No config file${FN}found."
|
|
exit 1
|
|
}
|
|
|
|
# precedence of config files:
|
|
# command line options
|
|
# config file specified on the command line
|
|
# environment vars
|
|
# local config file - same dir as script (if exists; not following link for dir)
|
|
# local config file - $HOME dir (if exists)
|
|
# global config file (if exists)
|
|
|
|
if [ "$cflag" == "1" ]; then
|
|
if [ -e "$carg" ]; then
|
|
. "$carg"
|
|
debug "Using config file: $carg"
|
|
else
|
|
noConfigFound "$carg"
|
|
fi
|
|
elif [ -e "$SCRIPT_DIR/$CONFIGFILE" ]; then
|
|
. "$SCRIPT_DIR/$CONFIGFILE"
|
|
debug "Using config file: $SCRIPT_DIR/$CONFIGFILE"
|
|
elif [ -e "$HOME/$CONFIGFILE" ]; then
|
|
. "$HOME/$CONFIGFILE"
|
|
debug "Using config file: $HOME/$CONFIGFILE"
|
|
else
|
|
noConfigFound
|
|
fi
|
|
|
|
DB=${JOPLIN_DIR}/database.sqlite
|
|
if [ ! -e "$DB" ]; then
|
|
echo "Error: Joplin database not found."
|
|
exit 1
|
|
fi
|
|
debug "Joplin database: $DB"
|
|
|
|
if [ -z "$CLIPPER_TOKEN" ]; then
|
|
echo "Error: Web Clipper token not set."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$CLIPPER_PORT" ]; then
|
|
echo "Error: Web Clipper port not set."
|
|
exit 1
|
|
fi
|
|
debug "Web Clipper port: $CLIPPER_PORT"
|
|
|
|
# retrieve the IDs of orphaned resources from the database
|
|
sqlite3 $DB "select resource_id from note_resources where is_associated = 0" >$TMPFILE
|
|
|
|
if [ ! -s "$TMPFILE" ]; then
|
|
info "No orphaned resources found."
|
|
exit
|
|
fi
|
|
|
|
ERR=0
|
|
|
|
if [ "$fflag" != "1" ]; then
|
|
echo -n "Delete orphaned resources? (yes/no): "
|
|
read answer
|
|
|
|
if [ "$answer"x != "yes"x ]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
for id in `cat $TMPFILE`
|
|
do
|
|
curlCMD="curl -s -X DELETE http://localhost:${CLIPPER_PORT}/resources/${id}?token=${CLIPPER_TOKEN}"
|
|
debug "$curlCMD"
|
|
infotext="Deleting resource id: $id"
|
|
info-n "$infotext"
|
|
if [ "$nflag" == "0" ]; then
|
|
# Delete ID
|
|
rc=""
|
|
rc=`$curlCMD`
|
|
|
|
if [ ! -z "$rc" ]; then
|
|
# error occured while deleting resource
|
|
ERR=1
|
|
if [ "$qflag" == "1" ]; then
|
|
# if --quiet, infotext has to be output, otherwise we don't know where the error occured
|
|
echo -n "$infotext - $rc"
|
|
else
|
|
echo -n " - $rc"
|
|
fi
|
|
else
|
|
info-n " - Success"
|
|
fi
|
|
fi
|
|
|
|
# A line break is required here
|
|
# Don't print empty lines, if --quiet and no error
|
|
if [[ "$qflag" == "1" && -z "$rc" ]]; then
|
|
:
|
|
else
|
|
echo ""
|
|
fi
|
|
done
|
|
|
|
if [ "$ERR" != "0" ]; then
|
|
exit 1
|
|
fi
|