2006/02/28(Tue)AjaxでAudioscrobbler表示

はてブ数 2006/02/28 1:47 サイト運営::JavaScript つーさ

とりあえずこのカテに置いておこうか。

うちのサイドバーのプロフィールの下に表示してるヤツね。
続きは、JavaScriptが弄れる人向け。

XMLHttpRequestは便利ねぇ。
IEのビヘイビアみたいなのがどのブラウザでも動きますよー! みたいな(笑

Audioscrobblerってのは今更説明要らないと思いますが、
再生した曲が自動的にそこに表示されるってヤツです。
一時期あちこちのブログで流行っていましたね。
今はもうあまり姿を見かけない気がしないでもないですが。

しかし、どーすっかなー。
結構ローカライズしちゃってあるんだよなぁ。
自分のサイトに都合のいいように書いてあるというか。

まー、そんな長くねーし、てけとーに読んでもらえりゃいーか。
まー、どーせ、誰も参考にはしねそーw

まずはJavaScriptファイル。

/* audioscrobbler.js */

// 串のパス
// Ajaxでは、データ入出力対象のCGIは同じホストに置く必要がある。
// これは、ただのプロキシCGI。この下のPerlスクリを参照のこと。
var as_proxycgi = "/nph-asproxy.cgi"; 

// タグとID。ここで指定したIDを持つタグの中身が書き換えられる。
// 以下は ulが対象。JavaScriptがOFFだと、
// そもそもこのタグが出力されないことになるので、
// その時にXMLの整合性を乱さないよう考慮すること。
var as_tagid = 'nowplaying'; 
var as_tag  = '<div class="list"><div class="listname">';
    as_tag += '<a target="_blank" href="http://www.last.fm/user/tu-sa/">http://www.last.fm/user/tu-sa/">最近の再生メディア</a></div>';
    as_tag += '<ul id="'+as_tagid+'"><li>非対応ブラウザかも</li></ul></div>';

// XMLHttpRequest のオブジェクトを作る
var xmlhttp = createXmlHttp();
function createXmlHttp()
{
  if (window.XMLHttpRequest)
  { // Mozilla, Firefox, Safari, IE7
    return new XMLHttpRequest(); 
  }

  else if (window.ActiveXObject)
  { // IE5, IE6
    try {
      return new ActiveXObject("Msxml2.XMLHTTP");  // MSXML3
    } catch(e) {
      return new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2
    }
  }
  else
  { // だめぽ
    return null;
  }
}

function audioscrobblerLoad()
{
  // ブラウザが非対応のとき何もしない
  if (xmlhttp == null)
    return;

  // "読み込み開始" に書き換える
  onData("_load");

  // リクエストの準備。
  xmlhttp.onreadystatechange = onHttpEvent;
  xmlhttp.open("GET", as_proxycgi , true);
  xmlhttp.send("");
}

function onHttpEvent()
{
  if (xmlhttp.readyState == 4) // とりあえず完了
  {
    if (xmlhttp.status == 200) // HTTP 200 OK!
      onData(xmlhttp.responseText);
    else // なんかエラー
      onData("_error");
  }
}

function fmt_02d(n){ return (n<10) ? "0"+n : n }

// 表示書き換え関数
function onData(s)
{
  // この変数にtag_idで指定したタグの中身を代入すればOK。
  var html = ""; 

  // ロード開始
  if( s == "_load" )
    html = "<li>読み込み中...</li>";

  // 何らかのエラーが発生
  else if( s == "_error" )
    html = "<li>エラー</li>";

  // 正常
  else
  {
    var songlist = s.split("\\n");
    
    if(songlist.length-1 > 0) // 1曲以上の情報がある
    {
      var objDate = new Date();

      // 最大5曲まで。
      for(var i=0; i<Math.min(songlist.length-1,5); i++)
      {
        // 時刻(songdata[0])と曲名(songdata[1])に分割。
        var songdata = songlist[i].split(",");

        // 時刻を適当にフォーマットする。
        objDate.setTime(eval("songdata[0]")*1000);
        var dtfmt = "("+objDate.getHours()+":"+fmt_02d(objDate.getMinutes())+")";

        // 連結。
        html+= "<li>"+dtfmt+" "+songdata[1]+"</li>";
      }
      objDate = null;
    }
    
    else // データなし
      html = "<li>オフライン</li>";
  }

  // 実際のHTMLを置き換え
  document.getElementById(as_tagid).innerHTML = html;
}

// 最初にタグしておく。
document.write(as_tag);

// ロード開始
audioscrobblerLoad();

 

次に示すのがaudioscrobbler用のプロキシ。
内容については特に説明不要な気がします。
ファイル名は nph- で始めること。
んで、そのcgiのパスを、↑スクリプトの最初の変数に格納すること。

#!/usr/local/bin/perl

#  nph-asproxy.cgi

$id = "tu-sa";

# 踏み台にされる危険性が出るため、URLをクエリーに頼らない。
$host = 'ws.audioscrobbler.com';
$path = '/1.0/user/'.$id.'/recenttracks.txt';

# サーバに繋いで結果をそのまま返す。
use Socket;
socket(S, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
connect(S, sockaddr_in(80, inet_aton($host)));
select(S); $|=1; select(STDOUT);
print S "GET $path HTTP/1.1\\r\\nHost: $host\\r\\n\\r\\n";
print STDOUT <S>;
close(S);

後は、タグを挿入したい位置に、

なんて書くだけかね。