2011-07-07

Rockbox has the ability to generate Audioscrobbler logs for later submission to Last.fm. A custom udev rule can be combined with a command-line Last.fm scrobbler to automate the process of submitting tracks every time the digital audio player is connected to the computer.

notify-send

The udev rule is designed to call a script whenever a Rockbox device is connected:

# /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 credentials can be stored in Gnome Keyring and accessed using 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 device to be mounted, retrieve the Last.fm credentials from Gnome Keyring, display a graphical notification using notify-send, call Laspyt to submit the scrobbler log, and then display a report:

#!/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 confirmation on Last.fm:

Last.fm