Skip to content

Instantly share code, notes, and snippets.

@awerlang
Forked from streetturtle/sp
Last active May 14, 2020 22:34
Show Gist options
  • Save awerlang/6dbacd4b53efd390d711c99458be8047 to your computer and use it in GitHub Desktop.
Save awerlang/6dbacd4b53efd390d711c99458be8047 to your computer and use it in GitHub Desktop.

Revisions

  1. awerlang revised this gist May 14, 2020. 1 changed file with 15 additions and 2 deletions.
    17 changes: 15 additions & 2 deletions sp
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,9 @@ require tr

    function sp-dbus {
    # Sends the given method to Spotify over dbus.
    dbus-send --print-reply --dest="$SP_DEST" "$SP_PATH" "$SP_MEMB"."$1" "${*:2}" > /dev/null
    local command="$1"
    shift
    dbus-send --print-reply --dest="$SP_DEST" "$SP_PATH" "$SP_MEMB"."$command" "${@}" > /dev/null
    }

    function sp-open {
    @@ -237,7 +239,18 @@ function sp-lucky {
    )

    sp-open "$SPTFY_URI"
    sp-current
    sp-current-oneline
    }

    function sp-search {
    # Searches for tracks, plays the first result.

    require curl

    # ask for access token from api
    access_token=$(curl -X "POST" -u "$SP_CLIENT_ID:$SP_CLIENT_SECRET" -d grant_type=client_credentials https://accounts.spotify.com/api/token 2>/dev/null | jq -r '.access_token')

    curl -s -G --data-urlencode "q=$*" -H "Authorization: Bearer $access_token" https://api.spotify.com/v1/search\?type=artist,track
    }

    function sp-version {
  2. awerlang revised this gist May 14, 2020. 2 changed files with 35 additions and 32 deletions.
    4 changes: 4 additions & 0 deletions clientrc.example
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    # copy to ~/.config/spotify/clientrc and fill these settings
    # generate from https://developer.spotify.com/dashboard/applications
    SP_CLIENT_ID=""
    SP_CLIENT_SECRET=""
    63 changes: 31 additions & 32 deletions sp
    Original file line number Diff line number Diff line change
    @@ -49,13 +49,13 @@
    # CONSTANTS

    SP_VERSION="0.1"
    SP_DEST="org.mpris.MediaPlayer2.spotify"
    SP_DEST="org.mpris.MediaPlayer2.spotifyd"
    SP_PATH="/org/mpris/MediaPlayer2"
    SP_MEMB="org.mpris.MediaPlayer2.Player"

    # generate these from https://developer.spotify.com/dashboard/applications
    SP_CLIENT_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    SP_CLIENT_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    # shellcheck source=.config/spotify/clientrc
    source "$HOME"/.config/spotify/clientrc

    # SHELL OPTIONS

    @@ -64,7 +64,7 @@ shopt -s expand_aliases
    # UTILITY FUNCTIONS

    function require {
    hash $1 2>/dev/null || {
    hash "$1" 2>/dev/null || {
    echo >&2 "Error: '$1' is required, but was not found."; exit 1;
    }
    }
    @@ -84,12 +84,12 @@ require tr

    function sp-dbus {
    # Sends the given method to Spotify over dbus.
    dbus-send --print-reply --dest=$SP_DEST $SP_PATH $SP_MEMB.$1 ${*:2} > /dev/null
    dbus-send --print-reply --dest="$SP_DEST" "$SP_PATH" "$SP_MEMB"."$1" "${*:2}" > /dev/null
    }

    function sp-open {
    # Opens the given spotify: URI in Spotify.
    sp-dbus OpenUri string:$1
    sp-dbus OpenUri string:"$1"
    }

    function sp-metadata {
    @@ -109,7 +109,7 @@ function sp-metadata {
    | sed -E 's/(xesam:)|(mpris:)//' `# Remove ns prefixes.` \
    | sed -E 's/^"//' `# Strip leading...` \
    | sed -E 's/"$//' `# ...and trailing quotes.` \
    | sed -E 's/"+/|/' `# Regard "" as seperator.` \
    | sed -E 's/"+/|/' `# Regard "" as separator.` \
    | sed -E 's/ +/ /g' `# Merge consecutive spaces.`
    }

    @@ -128,15 +128,15 @@ function sp-current-oneline {
    }

    function sp-status {
    dbus-send \
    --print-reply \
    --dest=$SP_DEST \
    $SP_PATH \
    org.freedesktop.DBus.Properties.Get \
    string:"$SP_MEMB" string:'PlaybackStatus' \
    | tail -1 \
    | cut -d "\"" -f2
    dbus-send --print-reply \
    --dest=$SP_DEST \
    $SP_PATH \
    org.freedesktop.DBus.Properties.Get \
    string:"$SP_MEMB" string:'PlaybackStatus' \
    | tail -1 \
    | cut -d "\"" -f2
    }

    function sp-eval {
    # Prints the currently playing track as shell variables, ready to be eval'ed
    require sort
    @@ -160,14 +160,14 @@ function sp-display {
    # Calls display on the artUrl.

    require display
    display $(sp-art)
    display "$(sp-art)"
    }

    function sp-feh {
    # Calls feh on the artURl.

    require feh
    feh $(sp-art)
    feh "$(sp-art)"
    }

    function sp-url {
    @@ -188,7 +188,7 @@ function sp-http {
    # xdg-opens the HTTP url.

    require xdg-open
    xdg-open $(sp-url)
    xdg-open "$(sp-url)"
    }

    function sp-help {
    @@ -215,30 +215,29 @@ function sp-help {
    echo " sp http - Open the HTTP URL in a web browser"
    echo ""
    echo " sp open <uri> - Open a spotify: uri"
    echo " sp search <q> - Start playing the best search result for the given query"
    echo " sp lucky <q> - Start playing the best search result for the given query"
    echo ""
    echo " sp version - Show version information"
    echo " sp help - Show this information"
    echo ""
    echo "Any other argument will start a search (i.e. 'sp foo' will search for foo)."
    echo "Any other argument will start a I'm feeling lucky search (i.e. 'sp foo' will search for foo & play)."
    }

    function sp-search {
    function sp-lucky {
    # Searches for tracks, plays the first result.

    require curl

    # ask for access token from api
    access_token=$(curl -X "POST" -u $SP_CLIENT_ID:$SP_CLIENT_SECRET -d grant_type=client_credentials https://accounts.spotify.com/api/token 2>/dev/null | jq -r '.access_token')
    access_token=$(curl -X "POST" -u "$SP_CLIENT_ID:$SP_CLIENT_SECRET" -d grant_type=client_credentials https://accounts.spotify.com/api/token 2>/dev/null | jq -r '.access_token')

    # fixed busted token issue
    Q="$@"
    SPTFY_URI=$( \
    curl -s -G --data-urlencode "q=$Q" -H "Authorization: Bearer $access_token" https://api.spotify.com/v1/search\?type=artist,track \
    curl -s -G --data-urlencode "q=$*" -H "Authorization: Bearer $access_token" https://api.spotify.com/v1/search\?type=artist,track \
    | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    )

    sp-open $SPTFY_URI
    sp-open "$SPTFY_URI"
    sp-current
    }

    function sp-version {
    @@ -262,14 +261,14 @@ alias sp-prev=" sp-dbus Previous"
    # when running locally, but is crucial when we don't have an X display handy
    # (for instance, when running sp over ssh.)

    SPOTIFY_PID="$(pidof -s spotify)"
    SPOTIFY_PID="$(pidof -s spotifyd)"

    if [[ -z "$SPOTIFY_PID" ]]; then
    echo "Error: Spotify is not running."
    exit 1
    fi

    QUERY_ENVIRON="$(cat /proc/${SPOTIFY_PID}/environ | tr '\0' '\n' | grep "DBUS_SESSION_BUS_ADDRESS" | cut -d "=" -f 2-)"
    QUERY_ENVIRON=$(tr '\0' '\n' </proc/"${SPOTIFY_PID}"/environ | grep DBUS_SESSION_BUS_ADDRESS | cut -d "=" -f 2-)
    if [[ "${QUERY_ENVIRON}" != "" ]]; then
    export DBUS_SESSION_BUS_ADDRESS="${QUERY_ENVIRON}"
    fi
    @@ -283,12 +282,12 @@ if [[ -z "$subcommand" ]]; then
    sp-help
    else
    # Arguments given, check if it's a command.
    if $(type sp-$subcommand > /dev/null 2> /dev/null); then
    if type sp-"$subcommand" &>/dev/null; then
    # It is. Run it.
    shift
    eval "sp-$subcommand $@"
    eval "sp-$subcommand" "$@"
    else
    # It's not. Try a search.
    eval "sp-search $@"
    # It's not. Try a feeling lucky search.
    eval "sp-lucky" "$@"
    fi
    fi
  3. awerlang revised this gist May 11, 2020. 1 changed file with 8 additions and 31 deletions.
    39 changes: 8 additions & 31 deletions sp
    Original file line number Diff line number Diff line change
    @@ -53,16 +53,13 @@ SP_DEST="org.mpris.MediaPlayer2.spotify"
    SP_PATH="/org/mpris/MediaPlayer2"
    SP_MEMB="org.mpris.MediaPlayer2.Player"

    # To get SP_ID and SP_SECRET register at
    # https://beta.developer.spotify.com/documentation/general/guides/app-settings/
    SP_ID="<yout id>"
    SP_SECRET="<your secret>"
    # generate these from https://developer.spotify.com/dashboard/applications
    SP_CLIENT_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    SP_CLIENT_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

    # SHELL OPTIONS

    shopt -s expand_aliases
    SP_B64ID=$(echo -n "$SP_ID:$SP_SECRET"|base64)
    SP_B64ID=$(echo $SP_B64ID | sed 's/ //g')

    # UTILITY FUNCTIONS

    @@ -140,7 +137,6 @@ function sp-status {
    | tail -1 \
    | cut -d "\"" -f2
    }

    function sp-eval {
    # Prints the currently playing track as shell variables, ready to be eval'ed
    require sort
    @@ -231,39 +227,20 @@ function sp-search {
    # Searches for tracks, plays the first result.

    require curl
    #send request for token with ID and SecretID encoded to base64->grep take only token from reply->trim reply down to token-> modified request to include token in header
    Q="$@"
    ST=$(curl -H "Authorization: Basic $SP_B64ID" -d grant_type=client_credentials https://accounts.spotify.com/api/token --silent \
    | grep -E -o "access_token\":\"[a-zA-Z0-9_-]+\"" -m 1 )

    echo $Q
    # ask for access token from api
    access_token=$(curl -X "POST" -u $SP_CLIENT_ID:$SP_CLIENT_SECRET -d grant_type=client_credentials https://accounts.spotify.com/api/token 2>/dev/null | jq -r '.access_token')

    ST2=${ST:15:86}}
    # fixed busted token issue
    Q="$@"
    SPTFY_URI=$( \
    curl -H "Authorization: Bearer $ST2" -s -G --data-urlencode "q=$Q" --data type=artist,track https://api.spotify.com/v1/search/ \
    curl -s -G --data-urlencode "q=$Q" -H "Authorization: Bearer $access_token" https://api.spotify.com/v1/search\?type=artist,track \
    | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    )

    sp-open $SPTFY_URI
    }


    #function sp-search {
    # # Searches for tracks, plays the first result.
    #
    # require curl

    #curl -s -G --data-urlencode "q=enjoy the silence" --data type=track "https://api.spotify.com/v1/search/" -H "Accept: application/json" -H "Authorization: Bearer BQCk-QAOp4r2hHf6bMY1B4WSfWnBnLXbYlLn7OJi0iGzR5JNg6uaMtNzokhCLTr3ETljtLb1KqhHGokfyLj9Fq3JkDz6yqwqM9NCa9RbGa7_ovJ0n9XZgev0bJ8r-N7hrF3TNN-PKY6YIKpOoWM"
    #
    # Q="$@"
    #SPTFY_URI=$( \
    # curl -s -G --data-urlencode "q=$Q" --data type=artist,track https://api.spotify.com/v1/search/ -H "Accept: application/json" -H "Authorization: Bearer $USER_TOKEN" \
    # | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    # )
    #
    # sp-open $SPTFY_URI
    #}

    function sp-version {
    # Prints version information.

  4. @streetturtle streetturtle revised this gist Jan 21, 2018. 1 changed file with 32 additions and 2 deletions.
    34 changes: 32 additions & 2 deletions sp
    Original file line number Diff line number Diff line change
    @@ -53,9 +53,16 @@ SP_DEST="org.mpris.MediaPlayer2.spotify"
    SP_PATH="/org/mpris/MediaPlayer2"
    SP_MEMB="org.mpris.MediaPlayer2.Player"

    # To get SP_ID and SP_SECRET register at
    # https://beta.developer.spotify.com/documentation/general/guides/app-settings/
    SP_ID="<yout id>"
    SP_SECRET="<your secret>"

    # SHELL OPTIONS

    shopt -s expand_aliases
    SP_B64ID=$(echo -n "$SP_ID:$SP_SECRET"|base64)
    SP_B64ID=$(echo $SP_B64ID | sed 's/ //g')

    # UTILITY FUNCTIONS

    @@ -224,16 +231,39 @@ function sp-search {
    # Searches for tracks, plays the first result.

    require curl

    #send request for token with ID and SecretID encoded to base64->grep take only token from reply->trim reply down to token-> modified request to include token in header
    Q="$@"
    ST=$(curl -H "Authorization: Basic $SP_B64ID" -d grant_type=client_credentials https://accounts.spotify.com/api/token --silent \
    | grep -E -o "access_token\":\"[a-zA-Z0-9_-]+\"" -m 1 )

    echo $Q

    ST2=${ST:15:86}}
    SPTFY_URI=$( \
    curl -s -G --data-urlencode "q=$Q" ws.spotify.com/search/1/track \
    curl -H "Authorization: Bearer $ST2" -s -G --data-urlencode "q=$Q" --data type=artist,track https://api.spotify.com/v1/search/ \
    | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    )

    sp-open $SPTFY_URI
    }


    #function sp-search {
    # # Searches for tracks, plays the first result.
    #
    # require curl

    #curl -s -G --data-urlencode "q=enjoy the silence" --data type=track "https://api.spotify.com/v1/search/" -H "Accept: application/json" -H "Authorization: Bearer BQCk-QAOp4r2hHf6bMY1B4WSfWnBnLXbYlLn7OJi0iGzR5JNg6uaMtNzokhCLTr3ETljtLb1KqhHGokfyLj9Fq3JkDz6yqwqM9NCa9RbGa7_ovJ0n9XZgev0bJ8r-N7hrF3TNN-PKY6YIKpOoWM"
    #
    # Q="$@"
    #SPTFY_URI=$( \
    # curl -s -G --data-urlencode "q=$Q" --data type=artist,track https://api.spotify.com/v1/search/ -H "Accept: application/json" -H "Authorization: Bearer $USER_TOKEN" \
    # | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    # )
    #
    # sp-open $SPTFY_URI
    #}

    function sp-version {
    # Prints version information.

  5. @streetturtle streetturtle revised this gist Dec 1, 2017. 1 changed file with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions sp
    Original file line number Diff line number Diff line change
    @@ -123,6 +123,17 @@ function sp-current-oneline {
    sp-metadata | grep -E "(title|artist)" | sed 's/^\(.\)*|//' | sed ':a;N;$!ba;s/\n/ | /g'
    }

    function sp-status {
    dbus-send \
    --print-reply \
    --dest=$SP_DEST \
    $SP_PATH \
    org.freedesktop.DBus.Properties.Get \
    string:"$SP_MEMB" string:'PlaybackStatus' \
    | tail -1 \
    | cut -d "\"" -f2
    }

    function sp-eval {
    # Prints the currently playing track as shell variables, ready to be eval'ed
    require sort
  6. @streetturtle streetturtle revised this gist Feb 23, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion sp
    Original file line number Diff line number Diff line change
    @@ -120,7 +120,7 @@ function sp-current {
    }

    function sp-current-oneline {
    sp-metadata | grep -E "(title|artist)" | sed 's/^\(.\)*|//' | sed ':a;N;$!ba;s/\n/ /g'
    sp-metadata | grep -E "(title|artist)" | sed 's/^\(.\)*|//' | sed ':a;N;$!ba;s/\n/ | /g'
    }

    function sp-eval {
  7. Pavel Makhov revised this gist Feb 22, 2016. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions sp
    Original file line number Diff line number Diff line change
    @@ -119,6 +119,10 @@ function sp-current {
    | column -t -s'|'
    }

    function sp-current-oneline {
    sp-metadata | grep -E "(title|artist)" | sed 's/^\(.\)*|//' | sed ':a;N;$!ba;s/\n/ /g'
    }

    function sp-eval {
    # Prints the currently playing track as shell variables, ready to be eval'ed
    require sort
  8. @wandernauta wandernauta created this gist Oct 2, 2013.
    272 changes: 272 additions & 0 deletions sp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,272 @@
    #!/bin/bash

    #
    # This is sp, the command-line Spotify controller. It talks to a running
    # instance of the Spotify Linux client over dbus, providing an interface not
    # unlike mpc.
    #
    # Put differently, it allows you to control Spotify without leaving the comfort
    # of your command line, and without a custom client or Premium subscription.
    #
    # As an added bonus, it also works with ssh, at and cron.
    #
    # Example:
    # $ sp weather girls raining men
    # $ sp current
    # Album 100 Hits Of The '80s
    # Artist The Weather Girls
    # Title It's Raining Men
    # $ sp pause
    #
    # Alarm clock example:
    # $ at 7:45 <<< 'sp bangarang'
    #
    # Remote example:
    # $ ssh [email protected] 'sp imperial march'
    #
    #
    # Copyright (C) 2013 Wander Nauta
    #
    # Permission is hereby granted, free of charge, to any person obtaining a copy
    # of this software, to deal in the Software without restriction, including
    # without limitation the rights to use, copy, modify, merge, publish,
    # distribute, sublicense, and/or sell copies of the Software, and to permit
    # persons to whom the Software is furnished to do so, subject to the following
    # conditions:
    #
    # The above copyright notice and this permission notice shall be included in
    # all copies or substantial portions of the Software.
    #
    # The software is provided "as is", without warranty of any kind, express or
    # implied, including but not limited to the warranties of merchantability,
    # fitness for a particular purpose and noninfringement. In no event shall the
    # authors or copyright holders be liable for any claim, damages or other
    # liability, whether in an action of contract, tort or otherwise, arising from,
    # out of or in connection with the software or the use or other dealings in the
    # software.
    #

    # CONSTANTS

    SP_VERSION="0.1"
    SP_DEST="org.mpris.MediaPlayer2.spotify"
    SP_PATH="/org/mpris/MediaPlayer2"
    SP_MEMB="org.mpris.MediaPlayer2.Player"

    # SHELL OPTIONS

    shopt -s expand_aliases

    # UTILITY FUNCTIONS

    function require {
    hash $1 2>/dev/null || {
    echo >&2 "Error: '$1' is required, but was not found."; exit 1;
    }
    }

    # COMMON REQUIRED BINARIES

    # We need dbus-send to talk to Spotify.
    require dbus-send

    # Assert standard Unix utilities are available.
    require grep
    require sed
    require cut
    require tr

    # 'SPECIAL' (NON-DBUS-ALIAS) COMMANDS

    function sp-dbus {
    # Sends the given method to Spotify over dbus.
    dbus-send --print-reply --dest=$SP_DEST $SP_PATH $SP_MEMB.$1 ${*:2} > /dev/null
    }

    function sp-open {
    # Opens the given spotify: URI in Spotify.
    sp-dbus OpenUri string:$1
    }

    function sp-metadata {
    # Prints the currently playing track in a parseable format.

    dbus-send \
    --print-reply `# We need the reply.` \
    --dest=$SP_DEST \
    $SP_PATH \
    org.freedesktop.DBus.Properties.Get \
    string:"$SP_MEMB" string:'Metadata' \
    | grep -Ev "^method" `# Ignore the first line.` \
    | grep -Eo '("(.*)")|(\b[0-9][a-zA-Z0-9.]*\b)' `# Filter interesting fiels.`\
    | sed -E '2~2 a|' `# Mark odd fields.` \
    | tr -d '\n' `# Remove all newlines.` \
    | sed -E 's/\|/\n/g' `# Restore newlines.` \
    | sed -E 's/(xesam:)|(mpris:)//' `# Remove ns prefixes.` \
    | sed -E 's/^"//' `# Strip leading...` \
    | sed -E 's/"$//' `# ...and trailing quotes.` \
    | sed -E 's/"+/|/' `# Regard "" as seperator.` \
    | sed -E 's/ +/ /g' `# Merge consecutive spaces.`
    }

    function sp-current {
    # Prints the currently playing track in a friendly format.
    require column

    sp-metadata \
    | grep --color=never -E "(title)|(album)|(artist)" \
    | sed 's/^\(.\)/\U\1/' \
    | column -t -s'|'
    }

    function sp-eval {
    # Prints the currently playing track as shell variables, ready to be eval'ed
    require sort

    sp-metadata \
    | grep --color=never -E "(title)|(album)|(artist)|(trackid)|(trackNumber)" \
    | sort -r \
    | sed 's/^\([^|]*\)\|/\U\1/' \
    | sed -E 's/\|/="/' \
    | sed -E 's/$/"/' \
    | sed -E 's/^/SPOTIFY_/'
    }

    function sp-art {
    # Prints the artUrl.

    sp-metadata | grep "artUrl" | cut -d'|' -f2
    }

    function sp-display {
    # Calls display on the artUrl.

    require display
    display $(sp-art)
    }

    function sp-feh {
    # Calls feh on the artURl.

    require feh
    feh $(sp-art)
    }

    function sp-url {
    # Prints the HTTP url.

    TRACK=$(sp-metadata | grep "url" | cut -d'|' -f2 | cut -d':' -f3)
    echo "http://open.spotify.com/track/$TRACK"
    }

    function sp-clip {
    # Copies the HTTP url.

    require xclip
    sp-url | xclip
    }

    function sp-http {
    # xdg-opens the HTTP url.

    require xdg-open
    xdg-open $(sp-url)
    }

    function sp-help {
    # Prints usage information.

    echo "Usage: sp [command]"
    echo "Control a running Spotify instance from the command line."
    echo ""
    echo " sp play - Play/pause Spotify"
    echo " sp pause - Pause Spotify"
    echo " sp next - Go to next track"
    echo " sp prev - Go to previous track"
    echo ""
    echo " sp current - Format the currently playing track"
    echo " sp metadata - Dump the current track's metadata"
    echo " sp eval - Return the metadata as a shell script"
    echo ""
    echo " sp art - Print the URL to the current track's album artwork"
    echo " sp display - Display the current album artwork with \`display\`"
    echo " sp feh - Display the current album artwork with \`feh\`"
    echo ""
    echo " sp url - Print the HTTP URL for the currently playing track"
    echo " sp clip - Copy the HTTP URL to the X clipboard"
    echo " sp http - Open the HTTP URL in a web browser"
    echo ""
    echo " sp open <uri> - Open a spotify: uri"
    echo " sp search <q> - Start playing the best search result for the given query"
    echo ""
    echo " sp version - Show version information"
    echo " sp help - Show this information"
    echo ""
    echo "Any other argument will start a search (i.e. 'sp foo' will search for foo)."
    }

    function sp-search {
    # Searches for tracks, plays the first result.

    require curl

    Q="$@"
    SPTFY_URI=$( \
    curl -s -G --data-urlencode "q=$Q" ws.spotify.com/search/1/track \
    | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
    )

    sp-open $SPTFY_URI
    }

    function sp-version {
    # Prints version information.

    echo "sp $SP_VERSION"
    echo "Copyright (C) 2013 Wander Nauta"
    echo "License MIT"
    }

    # 'SIMPLE' (DBUS-ALIAS) COMMANDS

    alias sp-play=" sp-dbus PlayPause"
    alias sp-pause=" sp-dbus Pause"
    alias sp-next=" sp-dbus Next"
    alias sp-prev=" sp-dbus Previous"

    # DISPATCHER

    # First, we connect to the dbus session spotify is on. This isn't really needed
    # when running locally, but is crucial when we don't have an X display handy
    # (for instance, when running sp over ssh.)

    SPOTIFY_PID="$(pidof -s spotify)"

    if [[ -z "$SPOTIFY_PID" ]]; then
    echo "Error: Spotify is not running."
    exit 1
    fi

    QUERY_ENVIRON="$(cat /proc/${SPOTIFY_PID}/environ | tr '\0' '\n' | grep "DBUS_SESSION_BUS_ADDRESS" | cut -d "=" -f 2-)"
    if [[ "${QUERY_ENVIRON}" != "" ]]; then
    export DBUS_SESSION_BUS_ADDRESS="${QUERY_ENVIRON}"
    fi

    # Then we dispatch the command.

    subcommand="$1"

    if [[ -z "$subcommand" ]]; then
    # No arguments given, print help.
    sp-help
    else
    # Arguments given, check if it's a command.
    if $(type sp-$subcommand > /dev/null 2> /dev/null); then
    # It is. Run it.
    shift
    eval "sp-$subcommand $@"
    else
    # It's not. Try a search.
    eval "sp-search $@"
    fi
    fi