Awesome. Love it.
Here’s the script if anyone is interested. Very basic. Currently it just logs offline listens to a TSV file. I’ll have to figure out how to loop through that and build a single JSON blob rather than making multiple API calls. Any feedback welcome!
#!/bin/sh
api_host=https://api.listenbrainz.org
api_path=/1/submit-listens
api_url="$api_host$api_path"
token=$(cat $HOME/.keys/listenbrainz)
offline_db="$XDG_CONFIG_HOME/cmus/offline.tsv"
# print_json(time, artist, album, title, mbid)
# returns: JSON
print_json() {
cat <<EOF
{
"listen_type": "single",
"payload": [
{
"listened_at": "$1",
"track_metadata": {
"artist_name": "$2",
"release_name": "$3",
"track_name": "$4",
"additional_info": {
"recording_mbid": "$5"
}
}
}
]
}
EOF
}
# scrobble(time, artist, album, title, mbid)
# returns: 0
scrobble() {
print_json "$1" "$2" "$3" "$4" "$5" |
curl -X POST \
-H "Authorization: Token $token" \
-H "Content-Type: application/json" \
-d "@-" \
"$api_url" >> $HOME/.cache/cmus_mb.log
}
# log_offline(time, artist, album, title, mbid)
# returns: 0
log_offline() {
printf "%s\t%s\t%s\t%s\t%s\n" "$1" "$2" "$3" "$4" "$5" >> "$offline_db"
}
main() {
cmus_stat=$(cmus-remote -Q)
starttime=$(echo "$cmus_stat" | grep "^position " | cut -d" " -f2)
[ "$starttime" -eq 0 ] || exit 0
mbid=$(echo "$cmus_stat" | grep "^tag musicbrainz_trackid " | cut -d" " -f3)
[ -n "$mbid" ] || exit 1
duration=$(echo "$cmus_stat" | grep "^duration " | cut -d" " -f2)
scrobtime=$(( duration / 2 ))
[ "$scrobtime" -gt 240 ] && scrobtime=240
while true; do
cmus_stat=$(cmus-remote -Q)
status=$(echo "$cmus_stat" | grep "^status " | cut -d" " -f2)
[ "$status" == stopped ] && exit 0
mbid_cur=$(echo "$cmus_stat" | grep "^tag musicbrainz_trackid " | cut -d" " -f3)
[ "$mbid_cur" == "$mbid" ] || exit 0
curtime=$(echo "$cmus_stat" | grep "^position " | cut -d" " -f2)
if [ "$curtime" -ge "$scrobtime" ]; then
time=$(date +%s)
artist=$(echo "$cmus_stat" | grep "^tag artist " | cut -d" " -f3-)
album=$(echo "$cmus_stat" | grep "^tag album " | cut -d" " -f3-)
title=$(echo "$cmus_stat" | grep "^tag title " | cut -d" " -f3-)
if ! scrobble "$time" "$artist" "$album" "$title" "$mbid"; then
log_offline "$time" "$artist" "$album" "$title" "$mbid"
fi
exit 0
fi
sleep $(( scrobtime - curtime ))
done
}
main