2011-07-07

Rockbox has the abil­ity to gen­er­ate Audioscrobbler logs for later sub­mis­sion to Last.fm. A cus­tom udev rule can be com­bined with a com­mand-line Last.fm scrob­bler to au­to­mate the process of sub­mit­ting tracks every time the dig­i­tal au­dio player is con­nected to the com­puter.

notify-send

The udev rule is de­signed to call a script when­ever a Rockbox device is con­nected:

# /etc/udev/rules.d/80-custom.rules

ACTION=="add", SUBSYSTEM=="block", ATTR{partition}=="1", ATTRS{vendor}=="Rockbox", ATTRS{model}=="Internal Storage", RUN+="/opt/rockbox/upload-scrobbler-log"

Last.fm cre­den­tials can be stored in GNOME Keyring and ac­cessed us­ing gkeyring:

gkeyring.py --set \
--name 'http://www.last.fm/' \
--password 'YOUR_PASSWORD_HERE' \
-p 'username_value=YOUR_USERNAME_HERE,origin_url=http://www.last.fm/'

The script will wait for the de­vice to be mounted, re­trieve the Last.fm credentials from GNOME Keyring, dis­play a graph­i­cal no­ti­fi­ca­tion us­ing no­tify-send, call Laspyt to sub­mit the scrob­bler log, and then dis­play a re­port:

#!/bin/bash
# Note: This script must finish quickly because udev is effectively paused while it is running

{
ubuntuuser="ak"
logfile="/tmp/upload-scrobbler-log.log"
backupscrobblerlog="/tmp/scrobbler.log.backup"
gkeyring="/opt/rockbox/gkeyring.py"
laspyt="/opt/rockbox/laspyt.py"

echo "Script starting at $(date)" >> "$logfile"

dapdescription="$(echo -e "$ID_FS_LABEL_ENC")"
echo "Detected $dapdescription at $DEVNAME" >> "$logfile"

# Wait for filesystem to be automounted
echo "Waiting up to 20 seconds for automount..." >> "$logfile"
counter=0
while [ $counter -lt 20 ]; do
grep -q "$DEVNAME" /proc/mounts && break
sleep 1
let counter++
done

# Abort if timed out
if [ $counter -ge 20 ]; then
echo "Unable to locate mountpoint; aborting" >> "$logfile"
exit 1
fi

# Determine mountpoint
mountpoint="$(echo -e "$(grep $DEVNAME /proc/mounts | awk '{print $2}')")"
echo "
Detected mountpoint at $mountpoint" >> "$logfile"

# Identify log file
scrobblerlog="
$mountpoint/.scrobbler.log"
echo "
Using scrobbler log file $scrobblerlog" >> "$logfile"

# Get credentials from keyring
echo "
Getting credentials from keyring..." >> "$logfile"
credentials="
$(sudo -H -u $ubuntuuser \
env $(grep -v "^#" /home/$ubuntuuser/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0)
\
$gkeyring -p origin_url=http://www.last.fm/ --output username_value,secret)"
username="
$(echo "$credentials" | awk '{print $1}')"
password="
$(echo "$credentials" | awk '{print $2}')"
if [ -z "
$username" -o -z "$password" ]; then
echo "
Failed to get credentials; aborting" >> "$logfile"
exit 1
else
echo "
Got credentials for $username" >> "$logfile"
fi

# Back up scrobbler log
echo "
Backing up scrobbler log to $backupscrobblerlog" >> "$logfile"
cp "
$scrobblerlog" "$backupscrobblerlog"

# Upload scrobbler log
timezone="
$(date +%:::z)"
echo "
Uploading scrobbler log file with timezone offset $timezone..." >> "$logfile"
sudo -H -u $ubuntuuser \
env DISPLAY=$(w -s $ubuntuuser | grep -m 1 " :" | awk "{print \$3}") \
notify-send --icon "
/usr/share/icons/Humanity/devices/48/multimedia-player.svg" \
"
Uploading scrobbler log" \
"
Submitting $(grep -v "^#" "$scrobblerlog" | wc -l) tracks from $dapdescription to Last.fm as $username"
sudo -H -u $ubuntuuser \
$laspyt --file "
$scrobblerlog" --timezone "$timezone" --clear \
--user "
$username" --password "$password" \
2>&1 | sed 's/\x1B\[[0-9;]*[mK]//g' >> "
$logfile"

# Report
echo "
Done" >> "$logfile"
sudo -H -u $ubuntuuser \
env DISPLAY=$(w -s $ubuntuuser | grep -m 1 " :" | awk "{print \$3}") \
zenity --text-info --title "
Scrobbler log upload" --filename "$logfile" &

} & disown

exit 0

Details from a run:

zenity

and con­fir­ma­tion on Last.fm:

Last.fm