mirror of
https://github.com/levogevo/add-synced-lyrics.git
synced 2026-07-21 21:45:21 +00:00
179 lines
4.2 KiB
Bash
179 lines
4.2 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# many functions are invoked via variables
|
|
# shellcheck disable=SC2329
|
|
|
|
usage() {
|
|
echo "${PROGNAME} [options]
|
|
|
|
OPTIONS:
|
|
-d, --dir process files in directory
|
|
-r, --recurse recursively process directory
|
|
-f, --file process one file
|
|
-n, --dry-run do not actually add synced lyrics,
|
|
just show the files that would be processed
|
|
-e, --eval output bash functions that can be directly processed
|
|
by eval for use with testing this script.
|
|
-i, --ignore ignore errors, and continue attempting to find lyrics
|
|
even in the case of errors
|
|
-h, --help show this output
|
|
--debug extra information useful for debugging"
|
|
exit "${EXIT_CODE:-1}"
|
|
}
|
|
|
|
set_default_options() {
|
|
DIR=${DIR:-}
|
|
FILE=${FILE:-}
|
|
RECURSE=${RECURSE:-false}
|
|
DRY_RUN=${DRY_RUN:-false}
|
|
IGNORE=${IGNORE:-false}
|
|
DEBUG=${DEBUG:-false}
|
|
|
|
# cache
|
|
CACHE_HOME="${XDG_CACHE_HOME:-"${HOME}/.cache"}"
|
|
CACHE_DIR="${CACHE_HOME}/add-synced-lyrics"
|
|
if [[ ! -d "${CACHE_DIR}" ]]; then
|
|
mkdir "${CACHE_DIR}" || return 1
|
|
fi
|
|
|
|
readonly MUSIC_EXTENSION_REGEX='.*\.(opus)$'
|
|
}
|
|
|
|
process_options() {
|
|
while [[ $# -gt 0 ]]; do
|
|
option="$1"
|
|
value="${2:-}"
|
|
case "${option}" in
|
|
-d | --dir)
|
|
if [[ ! -d "${value}" ]]; then
|
|
echo "directory ${value} does not exist"
|
|
usage
|
|
fi
|
|
readonly DIR="${value}"
|
|
shift 2
|
|
;;
|
|
-r | --recurse)
|
|
readonly RECURSE=true
|
|
shift 1
|
|
;;
|
|
-n | --dry-run)
|
|
readonly DRY_RUN=true
|
|
shift 1
|
|
;;
|
|
-i | --ignore)
|
|
readonly IGNORE=true
|
|
shift 1
|
|
;;
|
|
--debug)
|
|
readonly DEBUG=true
|
|
shift 1
|
|
;;
|
|
-e | --eval)
|
|
output_eval_functions
|
|
exit 0
|
|
;;
|
|
-f | --file)
|
|
if [[ ! -f "${value}" ]]; then
|
|
echo "file ${value} does not exist"
|
|
usage
|
|
fi
|
|
readonly FILE="${value}"
|
|
shift 2
|
|
;;
|
|
-h | --help)
|
|
EXIT_CODE=0 usage
|
|
;;
|
|
*)
|
|
echo "bad option"
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "${DIR:-}${FILE:-}" == '' ]]; then
|
|
echo "either --dir or --file must be used"
|
|
usage
|
|
fi
|
|
|
|
if [[ -n "${DIR}" && -n "${FILE}" ]]; then
|
|
echo "cannot process both directory and file"
|
|
usage
|
|
fi
|
|
|
|
if [[ "${RECURSE}" == true && -n "${FILE}" ]]; then
|
|
echo "--recurse can only be used with --dir"
|
|
usage
|
|
fi
|
|
}
|
|
|
|
_determine_inputs_fd() {
|
|
local fdCmd=(
|
|
fd
|
|
--type f
|
|
"${MUSIC_EXTENSION_REGEX}"
|
|
"${DIR}"
|
|
)
|
|
|
|
if [[ "${RECURSE}" == false ]]; then
|
|
fdCmd+=(--max-depth 1)
|
|
fi
|
|
|
|
mapfile -t INPUTS < <("${fdCmd[@]}" | sort)
|
|
}
|
|
|
|
_determine_inputs_find() {
|
|
local findCmd=(
|
|
find
|
|
"${DIR}"
|
|
)
|
|
|
|
if [[ "${RECURSE}" == false ]]; then
|
|
findCmd+=(-maxdepth 1)
|
|
fi
|
|
|
|
findCmd+=(
|
|
-regextype posix-extended
|
|
-regex "${MUSIC_EXTENSION_REGEX}"
|
|
-type f
|
|
)
|
|
|
|
mapfile -t INPUTS < <("${findCmd[@]}" | sort)
|
|
}
|
|
|
|
_determine_inputs_bash() {
|
|
local unsortedInputs=()
|
|
local pattern="${DIR}/*"
|
|
shopt -s nullglob globstar || return 1
|
|
|
|
[[ "${RECURSE}" == true ]] && pattern="${DIR}/**/*"
|
|
mapfile -t unsortedInputs < <(printf '%s\n' ${pattern})
|
|
|
|
local filteredInputs=()
|
|
for input in "${unsortedInputs[@]}"; do
|
|
[[ "${input}" =~ ${MUSIC_EXTENSION_REGEX} ]] || continue
|
|
filteredInputs+=("${input}")
|
|
done
|
|
|
|
mapfile -t INPUTS < <(printf '%s\n' "${filteredInputs[@]}" | sort)
|
|
}
|
|
|
|
determine_inputs() {
|
|
INPUTS=()
|
|
if [[ -n "${FILE}" ]]; then
|
|
INPUTS=("${FILE}")
|
|
elif have_cmd fd; then
|
|
_determine_inputs_fd || return 1
|
|
elif have_cmd find; then
|
|
_determine_inputs_find || return 1
|
|
else
|
|
_determine_inputs_bash || return 1
|
|
fi
|
|
|
|
if [[ "${#INPUTS[@]}" -eq 0 ]]; then
|
|
echo "no inputs found, something is wrong"
|
|
exit 1
|
|
fi
|
|
|
|
readonly INPUTS
|
|
}
|