Files
sxbm/sxbm
NRK 913a220ba1 list: major restructure
currently only tag search is functional.
2021-09-08 06:09:00 +06:00

232 lines
4.8 KiB
Bash
Executable File

#!/bin/sh
#
# Description: A cli bookmark manager written in POSIX shell
#
# Author: NRK
## Copyright 2021 NRK
## Licensed under GPL v3. See LICENSE for more details.
# set -x
##########
# CONFIG #
##########
# Appname and Version
APPNAME="sxbm"
VERSION="v0.3.1"
# Where all the bookmarks get stored
# Respects XDG_DATA_HOME if set
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/${APPNAME}"
DATA_FILE="${DATA_DIR}/bookmarks"
# Colors
# For a list of ANSI color codes, check the link below
# https://gist.github.com/Prakasaka/219fe5695beeb4d6311583e79933a009
COL_LINK="\033[1;31m" # Red
COL_TITLE="\033[0;33m" # Yellow
COL_LINE_NUM="\033[1;34m" # Blue
# 1 to enable encryption, 0 to disable it
# This currently does nothing, since the feature isn't implemented yet.
ENCRYPTION="0"
#################
### functions ###
#################
die() {
[ -n "$1" ] &&
printf "$@\n" > /dev/stderr
exit 1
}
usage() {
cat << EOF
Usage: $APPNAME <command> [<args>]
COMMANDS:
add <link> [title] [+tags]
ls|list [-s|--strict] [-c|--disable-colors] [title] [+tags]
open [-f|--force] <line_num|title|+tags>
rm|remove <line_num>
edit
-h|--help print this text and exit
-v|--version print the version and exit
EOF
}
version() {
cat << EOF
$APPNAME $VERSION
GPLv3 license
https://github.com/n-r-k/sxbm
EOF
}
bm_add() {
[ -z "$1" ] && die "No arguments provided. Use '$APPNAME -h' for help"
while [ -n "$1" ]; do
case "$1" in
*.*) [ -z "$LINK" ] &&
LINK="$1" ||
die "too many links\n$LINK\n$1" ;;
+*) TAGS="${TAGS}$1 " ;;
*) TITLE="${TITLE}$1 " ;;
esac
shift
done
[ -z "$LINK" ] && die "No links found"
echo "$LINK $TITLE $TAGS" >> "$DATA_FILE" &&
echo "Link $(wc -l < "$DATA_FILE") added successfully!" ||
die "Couldn't add link"
}
__awk_search() {
awk "$@"' { LINK=$1; $1="";
print NR ") " LINK " " $0 }' "$DATA_FILE"
}
# this entire function is a massive joke
bm_list() {
TAG_STRICT="||"
TITLE_STRICT="&&"
while [ -n "$1" ]; do
case "$1" in
"-c"|"--disable-colors")
unset COL_LINK COL_TITLE COL_LINE_NUM
;;
"-s"|"--strict")
TAG_STRICT="&&"
;;
"-S")
TITLE_STRICT="||"
;;
*)
break
;;
esac
shift
done
# search titles
# awk 'toupper($0)~"[[:blank:]]SUCKLESS[[:blank:]]" && toupper($0)~"[[:blank:]]ROCKS[[:blank:]]"'
# search tags
# awk "/[[:blank:]]\+apps($| )/ || /[[:blank:]]\+books($| )/"
while [ -n "$1" ]; do
case "$1" in
+*)
QUERY_TAG="/[[:blank:]]\\$1($| )/ $TAG_STRICT $QUERY_TAG"
;;
*)
tmp_char="$(echo "$1" | tr '[:lower:]' '[:upper:]')"
QUERY_TITLE=""
;;
esac
shift
done
QUERY_TAG="${QUERY_TAG%$TAG_STRICT }"
if [ -z "$QUERY_TAG" ] && [ -z "$QUERY_TITLE" ]; then
__awk_search
elif [ -n "$QUERY_TAG" ] && [ -z "$QUERY_TITLE" ]; then
__awk_search "$QUERY_TAG"
elif [ -z "$QUERY_TAG" ] && [ -n "$QUERY_TITLE" ]; then
__awk_search "$QUERY_TITLE"
elif [ -n "$QUERY_TAG" ] && [ -n "$QUERY_TITLE" ]; then
printf '%s\n%s\n' \
"$(__awk_search "$QUERY_TAG")" "$(__awk_search "$QUERY_TITLE")" |
sort | uniq -d
fi
}
bm_open() {
if [ "$1" = "-f" ] || [ "$1" = "--force" ]; then
FORCE=1
shift
fi
[ -z "$1" ] && die "No arguments given"
if [ -z "$2" ] && [ "$1" -eq "$1" 2>/dev/null ]; then
LINK=$(sed -n "s| .*||;${1}p;" "$DATA_FILE")
else
LINK=$(bm_list "-c" "$@" | cut -d " " -f 2)
fi
[ -n "$LINK" ] &&
LINK_NUM=$(echo "$LINK" | wc -l) ||
die "No links found"
[ "$LINK_NUM" -gt 1 ] && [ -z "$FORCE" ] &&
die "Too many links\nUse '$APPNAME open -f' to force open them all\n\n$LINK"
nohup $BROWSER $LINK 1>/dev/null 2>&1 &
}
bm_edit() {
$EDITOR "$DATA_FILE"
}
bm_remove() {
[ -z "$1" ] && die "No arguments given"
[ "$1" -eq "$1" 2>/dev/null ] &&
LINK=$(sed "${1}q;d" "$DATA_FILE") ||
die "Link not found"
printf "Delete this link? (y/n)\n$LINK\n"
read ANSWER
if [ "$ANSWER" = "y" ] || [ "$ANSWER" = "yes" ]; then
sed -i --follow-symlinks "${1}d" "$DATA_FILE" &&
echo "Deleted successfully" ||
die "Couldn't delete link"
fi
}
############
### main ###
############
[ -z "$1" ] && usage && die "No command given"
[ -d "$DATA_DIR" ] ||
mkdir -p "$DATA_DIR" ||
die "Unable to create $DATA_DIR"
case "$1" in
"add")
shift
bm_add "$@"
;;
"ls"|"list")
shift
bm_list "$@"
;;
"open")
shift
bm_open "$@"
;;
"rm"|"remove")
shift
bm_remove "$@"
;;
"edit")
shift
bm_edit "$@"
;;
"-h"|"--help")
usage && exit 0
;;
"-v"|"--version")
version && exit 0
;;
*)
die "Invalid command. Use '$APPNAME -h' for help!"
;;
esac