Files
sxbm/sxbm
2021-05-01 08:04:09 +06:00

199 lines
4.8 KiB
Bash
Executable File

#!/bin/sh
#
# Description: A cli bookmark manager written in POSIX shell
#
# Author: NRK
##########
# CONFIG #
##########
# Where all the data gets stored
# Respects XDG_DATA_HOME if set
[ -z "$XDG_DATA_HOME" ] && XDG_DATA_HOME="$HOME/.local/share"
DATA_DIR="${XDG_DATA_HOME}/sxbm"
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
ENCRYPTION="0"
# Auto fetch title. 1 to enable, 0 to disable
TITLE_FETCH="1"
#################
### functions ###
#################
die(){
[ -z "$1" ] ||
printf "$@\n" > /dev/stderr
exit 1
}
usage(){
printf "Usage: sxbm <command> [<args>]\n"
printf "
COMMANDS:
add <link> [title] [+tags]
ls|list [-c|--disable-colors] [title] [+tags]
open [-f|--force] <line_num|title|+tags>
rm|remove [-f|--force] <line_num|title|+tags>
edit [line_num|title|+tags]
-h|--help print this text and exit
-v|--version print the version and exit\n\n"
}
bm_add(){
[ -z "$1" ] && die "No arguments provided. Use 'sxbm -h' for help"
# TODO while functional, this is extremely fucking stupid.
# there has to be a better way to do this.
local LINK=$( echo "$@" | grep -o "[^[:space:]]\+\.[^[:space:]]\+" )
[ -z "$LINK" ] && die "No links found"
[ "$( echo "$LINK" | wc -l )" -gt 1 ] && die "Too many links!!\n$LINK"
local REMAINING=$( echo "$@" | tr " " "\n" | grep -v "[^[:space:]]\+\.[^[:space:]]\+" )
[ -n "$REMAINING" ] &&
local TAGS=$( echo "$REMAINING" | grep "^\\+[^[:space:]]" | tr "\n" " " ) &&
local TITLE=$( echo "$REMAINING" | grep -v "^\\+[^[:space:]]" | tr "\n" " " )
echo "$LINK $TITLE $TAGS" >> $DATA_FILE &&
echo "Link $(wc -l < "$DATA_FILE") added successfully!" ||
die "Couldn't add link"
}
bm_list(){
local QUERY_TAG
local QUERY_TITLE
local QUERY_STRICT="||"
while [ -n "$1" ]; do
case "$1" in
"-c"|"--disable-colors")
COL_LINK=""; COL_TITLE=""; COL_LINE_NUM="";
shift
;;
"-s"|"--strict")
local QUERY_STRICT="&&"
shift
;;
*)
break
;;
esac
done
# POSIX shell doesn't have arrays.
# Desperate times calls for desperate measures!
while [ -n "$1" ]; do
case "$1" in
+*)
[ -z "$QUERY_TAG" ] &&
QUERY_TAG="/[[:space:]]\\$1[[:space:]]/" ||
QUERY_TAG="${QUERY_TAG} $QUERY_STRICT /[[:space:]]\\$1[[:space:]]/"
shift
;;
*)
if [ "$QUERY_STRICT" = "&&" ]; then
[ -z "$QUERY_TITLE" ] &&
QUERY_TITLE="grep -i -e \"$1\"" ||
QUERY_TITLE="${QUERY_TITLE} | grep -i -e \"$1\""
else
[ -z "$QUERY_TITLE" ] &&
QUERY_TITLE="grep -i -e \"$1\"" ||
QUERY_TITLE="${QUERY_TITLE} -e \"$1\""
fi
shift
;;
esac
done
[ -z "$QUERY_TITLE" ] &&
awk --posix -v COL_LINE_NUM="$COL_LINE_NUM" \
-v COL_LINK="$COL_LINK" -v COL_TITLE="$COL_TITLE" \
"$QUERY_TAG { LINK=\$1; \$1=\"\";
gsub(/[[:space:]]\+[^[:space:]]+/,\"\");
print COL_LINE_NUM NR \") \" COL_LINK LINK \" \" COL_TITLE \$0 }" \
"$DATA_FILE"
[ -n "$QUERY_TITLE" ] &&
awk --posix -v COL_LINE_NUM="$COL_LINE_NUM" \
-v COL_LINK="$COL_LINK" -v COL_TITLE="$COL_TITLE" \
"$QUERY_TAG { LINK=\$1; \$1=\"\";
gsub(/[[:space:]]\+[^[:space:]]+/,\"\");
print COL_LINE_NUM NR \") \" COL_LINK LINK \" \" COL_TITLE \$0 }" \
"$DATA_FILE" | eval "$QUERY_TITLE"
}
bm_open(){
if [ "$1" = "-f" ] || [ "$1" = "--force" ]; then
local FORCE=1
shift
fi
[ -z "$1" ] && die "No arguments given"
if [ -z "$2" ] && [ "$1" -eq "$1" 2>/dev/null ]; then
local LINK=$( awk -v F="$1" 'NR == F {print NR" "$1}' $DATA_FILE )
else
local LINK=$( bm_list "-c" "$@" )
fi
[ -n "$LINK" ] &&
local LINK_NUM=$( echo "$LINK" | wc -l ) ||
die "No links found"
if [ "$LINK_NUM" -gt 1 ] && [ -z "$FORCE" ]; then
die "Too many links\nUse 'sxbm open -f' to force open them all\n\n$( echo "$LINK" )"
fi
while [ "$LINK_NUM" -gt 0 ]; do
$BROWSER $( echo "$LINK" | awk "NR == $LINK_NUM {print \$2}" )
LINK_NUM=$(($LINK_NUM - 1))
done
}
############
### main ###
############
[ -z "$1" ] && usage && die "No command given"
[ -d "$DATA_DIR" ] ||
mkdir "$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")
;;
"edit")
;;
"-h"|"--help")
usage && die
;;
"-v"|"--version")
;;
*)
die "Invalid command. Use 'sxbm -h' for help!"
;;
esac