Last.fm AJAXový RSS agregátor
12. září 2006
Web design
I v Česku se rozmohla móda nechávat si indexovat vámi právě poslouchané skladby na serveru Last.fm, který dokáže poskytovat zajímavé statistiky a nabízet možnosti tvorby virtuálního přátelství s lidmi, kteří sdílejí váš hudební vkus. I já jsem se zhruba před měsícem rozhodl, že se podělím o svůj hudební (ne)vkus a když jsem tvořil nový design tohoto webu, tak jsem jej obohatil o desítku nejaktuálnějších skladeb z Last.fm.
Člověk se může spokojit s kusem kódu, který generuje statistiku v podobě obrázku (styl obrázku lze editovat), ale já jsem chtěl něco jiného, něco co bude dokonalou součástí designu, proto jsem se jal využít možnosti Last.fm RSS kanálu. Nebyl by problém podobnou statistiku načítat pomocí PHP a kešovat, optimální platnost keše mi přijde tak čtvrthodinka. Jenže někdy se musí data obnovit a to se stane po přístupu návštěvníka webu – systém zjistí, že nemá platný seznam písní, zahrabe na Last.fm, hrabe, hrabe – server může být v ten moment nedostupný, potencionální čtenář odchází, protože se mu stránka nenačte. Proto jsem přistoupil k problému z druhé strany – využil jsem JavaScriptu a dolování informací o hudbě až po načtení stránky – moderní je tomu říkat AJAX.. ;o) Jde o to, že se volá funkce např. getLastFmTracks()
pomocí události onLoad
a následně dojde k dotazu serveru na seznam, pokud je v keši načte se ihned, pokud je keš neplatná, tak se načte z Last.fm, výsledek se předá JavaScriptu, který pomocí innerHTML
funkce přidá do stránky informace, jak prosté.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>LastFM Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="getLastFmTracks('lastFM', 'xomax');">
<ul id="lastFM">
<li>Sem načteme statistiku</li>
</ul>
</body>
</html>
JavaScript
Událostí OnLoad
na elementu body
voláme funkci getLastFmTracks
s dvěma parametry, kterými definuje stránkový element, do kterého budeme vkládat výsledek, a uživatele, jehož statistika nás zajímá.
var i;
var x;
var artist;
var name;
var url;
var date;
function getLastFmTracks (block, user) {
if (document.getElementById) {
var last = "http://pinion.xom-tom.com/skript/last.fm/lastFM.php?user="+user;
x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
x.open("GET", last, true);
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
x.onreadystatechange = function () {
if (x.readyState == 4 && x.status == 200) {
var artist1 = x.responseXML.getElementsByTagName("artist");
var name1 = x.responseXML.getElementsByTagName("name");
var url1 = x.responseXML.getElementsByTagName("url");
var date1 = x.responseXML.getElementsByTagName("date");
var output = "";
var n = 1;
for (i=0; i < name1.length; i++) {
artist = (artist1.length == "0" ? "" : artist1[i].firstChild.nodeValue);
name = (name1.length == "0" ? "" : name1[i].firstChild.nodeValue);
url = (url1.length == "0" ? "" : url1[i].firstChild.nodeValue);
date = (date1.length == "0" ? "" : date1[i].firstChild.nodeValue);
output += '<li><a href="' + url + '" title="Detail o interpretovi ' + artist + ' | Hrál mi ' + date + '">' + n + ' | ' + artist + ' – ' + name + '</a></li>\n';
n++;
}
var el = document.getElementById(block);
el.innerHTML = output;
}
}
x.send(null);
}
}
PHPko
JavaScript volá PHP stránku, na které se provádí následující skript. Pokud nechcete informace kešovat, můžete rovnou volat XML výstup z Last.fm. Kešování provádím podobně jako DGX ukládá Gravatary, prakticky jsem použil jeho kód, pouze upravil k potřebám mého hostingu (zákaz fopen na místa mimo localhost).
header("Content-Type: text/xml");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, no-store, must-revalidate");
$user = $_GET["user"];
$expire = 60*10;
$file = 'lastFM'.$user.'.xml';
$url = 'http://ws.audioscrobbler.com/1.0/user/'.$user.'/recenttracks.xml';
$cached = is_file($file);
$expired = $cached && (time() - filemtime($file) > $expire);
$return = '';
if (!$cached || $expired) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_GET, 1);
$return = curl_exec($ch);
curl_close($ch);
if ($return != '') {
fwrite(fopen($file, 'wb'), $return);
}
}
$return = file_get_contents($file);
echo $return;
Co s tím?
Zdrojové soubory s popsaným kódem jsem vám sbalil, ať si je můžete stáhnout. Implementace na stránkách je snadná – stačí nakopírovat obsah <script>
do <head>
nebo umístit do externího souboru, který budete načítat. V JavaScriptové části to chce ještě změnit cestu k PHP souboru (dle toho, kam ho nakopírujete.) <body>
obohatit o definici onload="getLastFmTracks(cilovy_element, 'vas_nick_na_last_fm');"
a nakonec nastavit práva zápisu na adresář, kam se budou ukládat keše..
Tradá a teď sdílíte s celým světem svou náladu, která se leskne z výběru vašich písní..
Andrew 17.9.06 17:57
Mám takovou paranoidní teorii. Nikdo neví, co přesně ten jejich klient posílá, takže může třeba poslat název souboru, crc32,… a protože po netu (DC/Torrent/…) obíhá omezená množství RIPů jednotlivých alb, jde takhle relativně snadno poznat, kdo je pirát (a to dokonce s jeho vlastní pomocí). No a Last.fm provozuje RIAA a je vymalováno. Tohle by byl od RIAA vážně geniální tah :)