Checking minimal JSON submission

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
2 Likes