You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DevOps-Bash-tools/lib/spotify.sh

105 lines
3.5 KiB
Bash

#!/usr/bin/env bash
# vim:ts=4:sts=4:sw=4:et
#
# Author: Hari Sekhon
# Date: 2020-07-20 00:26:08 +0100 (Mon, 20 Jul 2020)
#
# https://github.com/HariSekhon/DevOps-Bash-tools
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
#
# https://www.linkedin.com/in/HariSekhon
#
set -euo pipefail
[ -n "${DEBUG:-}" ] && set -x
libdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck disable=SC1090
. "$libdir/utils.sh"
offset="${SPOTIFY_OFFSET:-0}"
# conservative, some API endpoints can take 100, others 50 - this is the safe choice but will go faster for those APIs if you can set 100 where appropriate
limit="${SPOTIFY_LIMIT:-50}"
if ! [[ "$offset" =~ ^[[:digit:]]+$ ]]; then
echo "Invalid \$SPOTIFY_OFFSET = $offset found in environment" >&2
exit 1
fi
if ! [[ "$limit" =~ ^[[:digit:]]+$ ]]; then
echo "Invalid \$SPOTIFY_LIMIT = $limit found in environment" >&2
exit 1
fi
spotify_token(){
# tokens with authorization have length 281, tokens without 219, so if there is an unauthorized token in the environment, regenerate it to avoid 401 errors
# [ -a ] works in bash and is the most concise way of doing this
# shellcheck disable=SC2166
if [ -z "${SPOTIFY_ACCESS_TOKEN:-}" ] ||
[ -n "${SPOTIFY_PRIVATE:-}" -a "${#SPOTIFY_ACCESS_TOKEN}" -lt 280 ]; then
SPOTIFY_ACCESS_TOKEN="$("$libdir/../spotify_api_token.sh")"
fi
export SPOTIFY_ACCESS_TOKEN
}
spotify_user(){
spotify_user="${spotify_user:-${SPOTIFY_USER:-}}"
if [ -z "$spotify_user" ]; then
if [ -n "${SPOTIFY_PRIVATE:-}" ]; then
spotify_user="$(SPOTIFY_PRIVATE=1 "$libdir/../spotify_api.sh" "/v1/me" | jq -r '.id')"
else
usage "\$SPOTIFY_USER not defined, and not using SPOTIFY_PRIVATE to auto-infer user from an authorized token"
fi
fi
}
# used by client scripts
# shellcheck disable=SC2034
usage_auth_msg="Requires \$SPOTIFY_ACCESS_TOKEN, or \$SPOTIFY_ID and \$SPOTIFY_SECRET to be defined in the environment"
# srcdir defined in client scripts
# shellcheck disable=SC2034,SC2154
usage_token_private="export SPOTIFY_ACCESS_TOKEN=\"\$(SPOTIFY_PRIVATE=1 '$libdir/../spotify_api_token.sh')\""
# shellcheck disable=SC2034
usage_playlist_help="See spotify_playlists.sh --help for details on accessing private playlists"
# shellcheck disable=SC2034
usage_auth_help="See spotify_api_token.sh --help for authentication details and setting up your SPOTIFY_ID, SPOTIFY_SECRET and callback URL"
get_next(){
jq -r '.next' <<< "$*"
}
is_local_uri(){
[[ "$1" =~ ^spotify:local:|open.spotify.com/local/ ]]
}
is_spotify_playlist_id(){
#local playlist_id="${1:-}"
#if [ -z "$playlist_id" ]; then
# die "no playlist id passed to function is_spotify_playlist_id()"
#fi
[[ "$1" =~ [[:alnum:]]{22} ]]
}
validate_spotify_uri(){
local uri="$1"
if ! [[ "$uri" =~ ^(spotify:(track|album|artist):|^https?://open.spotify.com/(track|album|artist)/)?[[:alnum:]]+(\?.+)?$ ]]; then
echo "Invalid URI provided: $uri" >&2
return 1
fi
if [[ "$uri" =~ open.spotify.com/|^spotify: ]]; then
if ! [[ "$uri" =~ open.spotify.com/${uri_type:-track}|^spotify:${uri_type:-track} ]]; then
echo "Invalid URI type '${uri_type:-track}' vs URI '$uri'" >&2
return 1
fi
fi
uri="${uri##*[:/]}"
uri="${uri%%\?*}"
echo "$uri"
}