joplin-scripts/jnrmor

325 lines
7.7 KiB
Bash
Executable File

#!/usr/bin/env bash
VERSION=1.2.4
# 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 " ${XDG_CONFIG_HOME:-$HOME/.config}/$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 " --zero-history "
echo " DO NOT USE THIS - it is very dangerous - DATA LOSS!!! "
echo " override history timeframe and set to 0 "
echo ""
echo " --ignore-revisions "
echo " DO NOT USE THIS - it is very dangerous - DATA LOSS!!! "
echo " delete resources, even if they are used in revisions "
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
zhflag=0
irflag=0
options=$(getopt -n $PROG -q -o c:fnqdVh -l help,version,debug,dry-run,quiet,zero-history,ignore-revisions -- "$@")
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;;
--zero-history)
zhflag=1;;
--ignore-revisions)
irflag=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] $@"
fi
}
function info {
if [ "$qflag" != "1" ]; then
echo "$@"
fi
}
function info_n {
if [ "$qflag" != "1" ]; then
echo -n "$@"
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)
# local config file - $XDG_CONFIG_HOME or $HOME/.config 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"
elif [ -e "${XDG_CONFIG_HOME:-$HOME/.config}/$CONFIGFILE" ]; then
. "${XDG_CONFIG_HOME:-$HOME/.config}/$CONFIGFILE"
debug "Using config file: ${XDG_CONFIG_HOME:-$HOME/.config}/$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
KEEP=`sqlite3 $DB "select value from settings where key = 'revisionService.ttlDays'"`
if [ -z "$KEEP" ]; then
KEEP=90
fi
if [ "$zhflag" == "1" ]; then
KEEP=0
fi
sqlite3 $DB "select resource_id from note_resources where is_associated = 0 and resource_id not in (select resource_id from note_resources where is_associated = 1) group by resource_id having max(last_seen_time) < strftime('%s','now','-${KEEP} days')*1000" >$TMPFILE
if [ "$irflag" == "1" ]; then
sqlite3 $DB "select resource_id from note_resources where is_associated = 0" >$TMPFILE
fi
if [ ! -s "$TMPFILE" ]; then
info "No orphaned resources found."
exit
fi
ERR=0
if [[ "$irflag" == "1" || "$zhflag" == "1" ]]; then
if [ "$nflag" == "0" ]; then
echo "DANGER: You are using a very dangerous option."
echo "DANGER: Data loss is not only possible but rather almost certain."
echo ""
echo -n "Are you absolutely sure you know what you are doing? (yes/no): "
read answer
if [ "$answer"x != "yes"x ]; then
exit 1
fi
echo ""
unset answer
fi
fi
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 `sed 's/\s\+$//' $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