I like to listen to soma.fm at work. I also like to do everything (as much as possible) in the command line so I don’t have to context switch between applications too much. For years I’ve used mplayer to listen in. I eventually got tired of forgetting the playlist URL and wrote the following bash function so that I’d only have to remember the name of the playlist I wanted.
soma() {
mplayer -playlist http://somafm.com/"$1"
}
This worked well for a couple of years, really. I usually only listen to one or two stations and can easily remember the name of the station’s playlist file. Today I decided that I wanted to be able to explore new stations with this shell function as well. Enter the new bash function and a bash completion script.
The new bash function parses https://somafm.com/listen for the MP3 streams and prints them to STDOUT:
somalist() {
curl -s https://somafm.com/listen/ | awk -F '[<>]' '/MP3:/ { print $4 }' | awk -F '"' '{print $2}' | tr -d \/
}
This is not great but it works, for now. Parsing html with awk/bash/sed or any other generic interpreter is always hit or miss. Right now this works. In the future, maybe it won’t work so great. I’m prepared to accept this and fix it as needed. Now that we have a command that can play our playlists and one that can list them, we need tie it all together with bash completion.
Bash completion scripts are what automatically tab complete options and
arguments. These can be static or dynamic. In our case, we want to provide the
output of somalist()
to the user when they type soma
and press the <tab> key.
On MacOS the following file should be placed in /usr/local/etc/bash_completion.d
(assuming you’re using Homebrew). If you’re on Linux, it will likely be
/etc/bash_completion.d
. Consult your distribution specific documentation for
more details:
#!/usr/bin/env bash
_soma_completion() {
if [ "${#COMP_WORDS[@]}" != "2" ]; then
return
fi
COMPREPLY=($(compgen -W "$(somalist)" -- "${COMP_WORDS[1]}"))
}
complete -F _soma_completion soma
Source this file with source /usr/local/etc/bash_completion.d/soma
and try it
out by typing soma
followed by the key. As an added bonus, it will give
you the most closely matching result if you type a partial name in.
Conclusion
This works for me. It’s a little fragile but I found it useful enough that I’d share it. Check out my Github if you’re interested in some of the other scripts I whip up and updates to this if I decide to make improvements in the future.