Skip to content

Instantly share code, notes, and snippets.

@LeXofLeviafan
Last active August 24, 2024 04:13
Show Gist options
  • Save LeXofLeviafan/ef44453f2da72d2f55492b7d4c955d8d to your computer and use it in GitHub Desktop.
Save LeXofLeviafan/ef44453f2da72d2f55492b7d4c955d8d to your computer and use it in GitHub Desktop.
A custom script allowing to run bukuserver and switch out between multiple databases
#!/bin/bash
# Usage: `bukuserver.sh` starts up the server, `bukuserver.sh --stop` sends TERM to the already running server
# On startup, the user is offered to choose or create a new DB (cancel both to exit)
# After the server stops (via CTRL+C or `bukuserver --stop`), the choice is given again
# NOTE: requires Zenity to work
# Environment variables (override defaults via CLI or by modifying the script):
# DEVMODE non-empty value enables developer mode (rebuild on restart)
# BUKUSERVER path to executable, or directory to run from source
# VENV path to venv (default is relative to BUKUSERVER if in DEVMODE)
# BUKUSERVER_* Web-UI startup settings (see Bukuserver docs)
# specify default Web-UI settings in "$BUKU_CONFIG_DIR/bukuserver.env"
: "${BUKUSERVER:=`which bukuserver`}"
[ "$DEVMODE" ] && : "${VENV:=./venv}" || : "${VENV:=$HOME/.local/share/bukuserver/venv}"
BUKU_CONFIG_DIR=~/.local/share/buku
function _settermtitle { echo -en "\033]2;$1\007"; } # changes terminal title
function _select-db { # offers a choice between DBs in buku config dir, or to make a new one
if [ "$1" ] && zenity --question --title="Reuse previous DB?" --text="'$(basename "${1%.db}")'"; then
echo "$1"
return
fi
local -a FILES
while read FILE; do
[ -e "$FILE" ] && FILES+=( "$(basename "${FILE%.db}")" )
done < <(ls -1 "$BUKU_CONFIG_DIR"/{,.}*.db 2>/dev/null | sort)
local FILE
if [ ${#FILES[@]} != 0 ]; then
FILE=`zenity --list --title="Choose DB" --text="(or click Cancel to create new DB)" --column="Name" -- "${FILES[@]}"`
[ "$FILE" ] && echo "$BUKU_CONFIG_DIR/$FILE.db" && return
fi
while true; do
FILE=`zenity --entry --title="Create new DB?" --text="DB name (cannot contain '/'):" --entry-text="bookmarks"`
! [ "$FILE" ] && echo "No name given, qutting" >&2 && return
[[ "$FILE" == *'/'* ]] && zenity --error --text="DB name cannot contain '/'!" && continue
[ -e "$BUKU_CONFIG_DIR/$FILE.db" ] && ! zenity --question --text="'$FILE' exists already. Open anyway?" && continue
echo "$BUKU_CONFIG_DIR/$FILE.db"
return
done
}
# --stop implementation
if [ "$1" == '--stop' ]; then # stop existing server (or switch between DBs)
PID=`ps -afu "$USER" | grep '\bpython[^ ]* \(.*/bukuserver\|bukuserver/server\.py\) run$' | awk '{print $2}'`
[ "$PID" ] && kill "$PID"
exit
fi
_settermtitle 'bukuserver'
# loading default Web-UI settings
ENV_ENTRY='^([_A-Z]*)=("(.*)"|'\''(.*)'\''|(.*))$'
[ -r "$BUKU_CONFIG_DIR/bukuserver.env" ] && while read -r; do
if [[ $REPLY =~ $ENV_ENTRY ]]; then
KEY="${BASH_REMATCH[1]}"
VALUE="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}"
echo "default:$KEY=$VALUE"
[ "${!KEY}" ] || export "$KEY=$VALUE"
fi
done < "$BUKU_CONFIG_DIR/bukuserver.env"
# initializing venv
if [ -d "$BUKUSERVER" ]; then # run from source (using venv)
cd "$BUKUSERVER"
echo "Using '$(realpath "$VENV")'"
python -m venv "$VENV"
. "$VENV/bin/activate"
if ! [ "$DEVMODE" ]; then
pip install .[server]
else
pip install --editable .[server]
function bukuserver { python bukuserver/server.py "$@"; }
export -f bukuserver
fi
BUKUSERVER='bukuserver'
fi
# DB reopening loop
export BUKUSERVER_DB_FILE=`_select-db`
while [ "$BUKUSERVER_DB_FILE" ]; do
"$BUKUSERVER" run
export BUKUSERVER_DB_FILE=`_select-db "${DEVMODE:+$BUKUSERVER_DB_FILE}"`
done
@LeXofLeviafan
Copy link
Author

LeXofLeviafan commented Jul 12, 2024

Sample bukuserver.env:

BUKUSERVER_THEME='slate'
BUKUSERVER_DISABLE_FAVICON=false
BUKUSERVER_OPEN_IN_NEW_TAB=true

Shown in DEVMODE (developer mode) when restarting the server
DB reopen
Shown on startup (unless no DB files were found):
DB selection dialog
Shown if no DB was selected (or none found):
DB creation dialog
Shown if new DB name is taken already:
DB exists
Shown if DB name contains an invalid character (/):
DB naming error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment