Next Image
Make the current image sticky.
Previous Image
randys.org - randys.org

Scrobble This: last.fm recent tracks AJAX style

So, I’ve been reading up a bit on prototype.js and its Ajax helpers. It’s an amazing tool and helped me write the bit of info at the top of the page. It’s pretty basic, but here’s the code that does most of the work:

function lastfm()
{
    new Ajax.Request('/as/recenttracks.xml',
    {
        method: 'get',
        onLoading: function() {

    },
    onLoaded: function(transport) {
        if (transport.overrideMimeType) {
            transport.overrideMimeType('application/xml');
        }
    },
    onSuccess: function(transport) {
        var response = transport.responseXML.documentElement;
        updateLastfm(response);
    },
    onFailure: failedLastfm()
});

}

The only issue I ran into was that I was originally using the RSS flavor of recent tracks, however it didn’t split up the artist and track information. It displays it as <title>[artist] – [track]</title>. That en-dash in the middle was preventing me from using title.split() on the JavaScript side of things. Really weird.

Also, since I’m a complete newbie with Ruby, I couldn’t figure out how (read: didn’t take the time to learn) to grab the content from a remote server and serve it up to the JavaScript. I’m sure it’s pretty simple… but I was at work and in a hurry. So, being that I know PHP, I just created a script to download the file and save it to the local disk and setup a cronjob.

Here’s the PHP script:

class lastfm
{
    private $user;
    private $reports;
    private $basews;
    public $saveto;

function __construct($user)
{
    $this-&gt;user = $user;
    $this-&gt;basews = 'http://ws.audioscrobbler.com/1.0/user/';
    $this-&gt;reports = array(
        'recenttracks.xml',
        'weeklyartistchart.xml',
        'weeklytrackchart.xml',
        'topartists.xml'
    );
    $this-&gt;saveto = '.';
}

public function go()
{
    for ($i = 0; $i &lt; count($this-&gt;reports); $i++)
    {
        try
        {
            $opts = array('http' =&gt; array('method' =&gt; 'GET', 'header' =&gt; 'Content-type: text/plain; charset=utf-8'));
            $context = stream_context_create($opts);

            $fp = fopen($this-&gt;saveto.DIRECTORY_SEPARATOR.$this-&gt;reports[$i], 'w+');
            $stream = fopen($this-&gt;basews.$this-&gt;user.'/'.$this-&gt;reports[$i], 'r', false, $context);
            $string = stream_get_contents($stream);
            fwrite($fp, $string);
            fclose($fp);
            fclose($stream);
            echo 'Saved ' . $this-&gt;saveto.DIRECTORY_SEPARATOR.$this-&gt;reports[$i] . "\n";
        }
        catch (Exception $e)
        {
            echo $e-&gt;getMessage() . "\n";
        }
    }
}

public function setSaveto($path)
{
    if (is_dir($path))
    {
        if (ereg('\/$', $path))
        {
            $path = ereg_replace('\/$', '', $path);
        }
        $this-&gt;saveto = $path;
    }
    else
    {
        $this-&gt;createDir($path);
        $this-&gt;setSaveto($path);
    }
}

private function createDir($path)
{
    if (!is_dir($path))
    {
        $res = `mkdir -p $path`;
    }
}

}

I’ll hit up the Rails API Docs one of these days and write a simple Ruby script that does all the work of the PHP script. Even better would be to process the XML document using ruby that just returns a string of HTML and use Ajax.PeriodicalUpdater($(e), ...).

All content Copyright © 1999 — 2010 Randy Sesser | Happily Hosted by WebFaction
Entries (RSS) | Comments (RSS)