diff options
-rwxr-xr-x | damb | 307 |
1 files changed, 251 insertions, 56 deletions
@@ -1,18 +1,38 @@ #!/bin/sh -# dir where audio files are stored -amb_dir="$HOME/.local/share/damb" -pid_file="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/damb.pids" -config_dir="$HOME/.config/damb" -menu="wmenu" -ico=" " +damb_conf="${XDG_CONFIG_HOME:-$HOME/.config}/damb/damb.conf" +damb_data="${XDG_DATA_HOME:-$HOME/.local/share}/damb" +damb_pids="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/damb.pids" + +w_menu="wmenu" +x_menu="dmenu" + +ico_damb=" " +ico_locl=" " +ico_ytbe=" " +ico_sndc=" " +ico_gurl=" " +ico_what=" " + +usage() +{ + cat <<- EOF + Usage: damb [ command ] [ option ] + a bookmark manager using dmenu + Commands: + help show this help cruft + save <key> <value>, save a new key + rm <key>, remove a key + + EOF +} die() { : "${1:?}" command -v notify-send > /dev/null && - notify-send "${ico} damb" "$1" + notify-send "${ico_damb} damb" "$1" printf "\033[31;1merr: %b\033[0m\n" "$1" exit "${2:-1}" @@ -30,71 +50,246 @@ dep_check() unset dep } -menu_opt() +trim() +{ + : "${1:?}" + + _trimstr="${1#"${1%%[![:space:]]*}"}" + _trimstr="${_trimstr%"${_trimstr##*[![:space:]]}"}" + + echo "$_trimstr" +} + +gen_ico() +{ + case "$1" in + https://www.youtube.com/*|https://youtu.be/*) + echo "$ico_ytbe" ;; + https://soundcloud.com/*) + echo "$ico_sndc" ;; + http*) + echo "$ico_gurl" ;; + /*) + echo "$ico_locl" ;; + *) + echo "$ico_what" ;; + esac +} + +parse_keys() +{ + # usage parse_data [ getval <key> ] + line= + _key= + _value= + + [ -s "$damb_conf" ] || return 1 + + while read -r line + do + [ -z "$line" ] && continue + + _key="${line%%|*}" + _key="$(trim "$_key")" + + case "$_key" in + #*) continue + esac + + if [ "$1" = "getval" ]; then + [ "$2" != "$_key" ] && continue + + _value="${line##*|}" + _value="$(trim "$_value")" + echo "$_value" + return 0 + else + echo "$_key" + fi + done < "$damb_conf" + + unset _key _value + [ "$1" = "getval" ] && return 1 +} + +rm_key() +{ + # usage rm_data <key> + : "${1:?}" + cl= + line= + file= + value= + old_ifs="$IFS" + + IFS= + while read -r line + do + cl="$line\n" + + key="$(trim "${cl%%|*}")" + # catch match + if [ "$key" = "$1" ]; then + value="$(trim "${cl##*|}")" + + # delete if saved + case "$value" in + "$damb_data"*) rm -f "$value" + esac + continue + fi + + file="${file}${cl}" + done < "$damb_conf" + + IFS="$old_ifs" + # shellcheck disable=SC2059 + printf "$file" > "$damb_conf" + unset cl line file value old_ifs +} + +verify_val() +{ + # verify_val <value> + + case "$(file --brief --dereference --mime-type "$1")" in + audio/*|video/*) ;; + *) + echo "$1" | grep -qxE '^(https?://)?[^/]*\.[A-Za-z0-9]*(/.*)?' || + return 1 + esac +} + +write_kv() { - printf "%s\n" "select" "links" "stream" "stop" | "$menu" -p "$ico" + # verify_val <key> <value> + : "${1:?}" + : "${2:?}" + + key="$(trim "$1")" + val="$(trim "$2")" + + case "$key" in + [![:cntrl:][:print:]]*) ;; # check for unicode chars + *) key="$(gen_ico "$val") ${key}" + esac + + parse_keys getval "$key" > /dev/null && + die "keys must be unique" + verify_val "$val" || + die "invalid: $val" + + echo "$key | $val" >> "$damb_conf" } -get_ambs() +kill_ambs() { - find "$amb_dir" -type f -exec basename {} \; + while read -r pid; do + kill -9 "$pid" + done < "$damb_pids" + + rm "$damb_pids" } -get_link() +play_amb() { - grep -v "^#.*$" "$config_dir"/links | - grep "$(grep -v "^#.*$" "$config_dir"/links | cut -d '=' -f1 | "$menu" -p "$ico" -l 25)" | - cut -d '=' -f2 | tr -d ' ' + : "${1:?}" + + mpv --no-video --no-cache --no-resume-playback "$@" & + echo "$!" >> "$damb_pids" } -main() +set_menu() { - [ -z "$WAYLAND_DISPLAY" ] && - menu="dmenu" + if [ -n "$WAYLAND_DISPLAY" ]; then + menu="$w_menu" + elif [ -n "$DISPLAY" ]; then + menu="$x_menu" + else + die "tty not supported" + fi dep_check "$menu" +} - case "$(menu_opt)" in - select) - dep_check "ffplay" - ffplay -volume 20 -nodisp -loop 0 "$amb_dir/$(get_ambs | "$menu" -p "$ico" -l 25)" & - echo "$!" >> "$pid_file" - ;; - links) - dep_check "mpv" - mpv --no-video --no-resume-playback "$(get_link)" & - echo "$!" >> "$pid_file" - ;; - stop) - while read -r process - do - kill -9 "$process" - done < "$pid_file" - - rm "$pid_file" - ;; - stream) - paste= - dep_check "mpv" - - if [ -n "$WAYLAND_DISPLAY" ]; then - dep_check "wl-paste" - paste="$(wl-paste)" - elif [ -n "$DISPLAY" ]; then - dep_check "xclip" - paste="$(xclip -o -sel clip)" - else - die "tty supported, run a display server" +set_clip() +{ + if [ -n "$WAYLAND_DISPLAY" ]; then + dep_check "wl-paste" + _clip="$(wl-paste)" + elif [ -n "$DISPLAY" ]; then + dep_check "xclip" + _clip="$(xclip -o)" + fi + + verify_val "$_clip" +} + +gen_opts() +{ + + [ -s "$damb_pids" ] && while read -r pid; do + if [ -d "/proc/${pid}" ]; then + echo " stop the ambiances" + break; fi + done < "$damb_pids" + + set_clip && + echo "$(gen_ico "$_clip") $_clip (from clipboard)" - mpv --no-video "$paste" & - echo "$!" >> "$pid_file" - ;; - "") - ;; # stay quiet when user quits the program during selection + parse_keys +} + +gen_menu() +{ + [ -s "$damb_conf" ] || die "empty, try damb save" + key="$(gen_opts | wmenu -l 25)" || return 1 + + case "$key" in + *"stop the ambiances") + kill_ambs ;; + *"from clipboard)") + set_clip + play_amb "$_clip" ;; *) - die "option not implemented";; + play_amb --loop "$(parse_keys getval "$key")" ;; esac } -main "$@" +######## +# MAIN # +######## + +[ -d "$damb_data" ] || mkdir -p "$damb_data" +[ -d "${damb_conf%/*}" ] || mkdir -p "${damb_conf%/*}" + +set_menu +dep_check mpv + +case "$1" in +rm) + key="$(parse_keys | "$menu" -l 25)" || exit 1 + rm_key "$key" + ;; +save) + [ "$#" -ne 3 ] && + die "invalid usage, try damb help" + + if [ -f "$3" ]; then + cp "$3" "$damb_data" + val="${damb_data}/${3##*/}" + fi + + write_kv "$2" "${val:-$3}" + ;; +"") + gen_menu + ;; +help) + usage + ;; +*) + die "invalid usage $*, try damb help" + ;; +esac |