« MovableTypeのPHP化 | Home | ファイルシステムをext3からext2へ戻す »

[Movable Type]   今聴いている音楽を動的に紹介する

Audioscrobblerとプラグインを使えば今現在WMPやiTunesで聴いている音楽をRSS配信できる。これを動的にMovableTypeで紹介する。

前提
PHPが使えるサーバーでMovableTypeが動作してる
MovableTypeをPHP化してる

前準備
  • Audioscrobblerでアカウントを取得する
  • 使っているメディアプレイヤーのプラグインを入手してインストールする
インストール
  • XML_RSSを使うのでコンソールに入れるのなら
    pear install XML_RSS
    
    入れなければここからダウンロードしてBlog公開ディレクトリに保存する
  • 以下をaudioscrobbler.phpとして保存する
    <?php
    require_once("RSS.php");
    
    $user = "USER_NAME";
    $encode = "utf-8";
    $truncate = 20;
    $dateformat = "M j, Y G:i:s";
    $rdf = "http://ws.audioscrobbler.com/rdf/history/$user";
    $user_page = "http://www.audioscrobbler.com/user/$user/";
    $rdf_file = "temp/audioscrobbler.rdf";
    $cache_time = "10";
    $timeout = "5";
    
    if(!file_exists($rdf_file) || (filectime($rdf_file) < (time() - $cache_time))) {
        $array = parse_url ($rdf);
        $host = $array['host'];
        $cache = true;
        if (isset($array['port'])) {
            $port = $array['port'];
        } else {
            $port = 80;
        }
        $path = $array['path'];
    
        error_reporting (0);
        $fp = fsockopen ($host, $port, $errno, $errstr, $timeout);
        if (!$fp) {
            echo "server is busy: $errstr($errno)";
        } else {
            fputs ($fp, "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n");
            $response = null;
            while (!feof($fp)) {
                $response .= fgets ($fp, 4096);
            }
            fclose ($fp);
            $cache = false;
    
            $data = split("\r\n\r\n", $response, 2);
    
            if ($data != null) {
                $temp = @fopen($rdf_file,"w") or die("ファイルが開けません");
                flock($temp, LOCK_EX);
                fputs($temp, $data[1]);
                fclose ($temp);
            }
        }
    }
    
    $rss =& new XML_RSS($rdf_file);
    $rss->parse('utf-8');
    
    $lastget = date($dateformat, filectime($rdf_file));
    
    $lastplay = null;
    echo "<ul>\n";
    foreach ($rss->getItems() as $item) {
        if ($lastplay==null) {
            $lastplay = date($dateformat, parse_w3cdtf($item['dc:date']));
        }
    
        $link = $item['link'];
        $description = mb_convert_encoding($item['description'], $encode, 'auto');
        list($artist, $title) = split(' - ', $description);
        if ($truncate > 0) {
            if (mb_strlen($title, $encode) > $truncate) {
                    $title = mb_substr($title, 0, $truncate, $encode).'...';
            }
            if (mb_strlen($artist, $encode) > $truncate) {
                    $artist = mb_substr($artist, 0, $truncate, $encode).'...';
            }
        }
        
        $artist = htmlspecialchars($artist);
        $title = htmlspecialchars($title);
    
        echo "<li class=\"track\">\n";
        echo "<div class=\"title\"><a href=\"" . $link . "\">" . $title . "</a></div>\n";
        echo "<div class=\"artist\">" . $artist . "</div>\n";
        echo "</li>\n";
    }
    echo "</ul>\n";
    echo "<p class=\"link\"><a href=\"" . $user_page . "\">my Audioscrobbler</a></p>\n";
    echo "<p class=\"lastplay\">last play:". $lastplay . "</p>\n";
    echo "<p class=\"lastupdate\">last update:". $lastget . "</p>\n";
    
    function parse_w3cdtf ( $date_str ) {
        # regex to match wc3dtf
        $pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
        if ( preg_match( $pat, $date_str, $match ) ) {
            list( $year, $month, $day, $hours, $minutes, $seconds) =
            array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
    
            # calc epoch for current date assuming GMT
            $epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
    
            $offset = 0;
            $tz_mod = "";
            $tz_hour = 0;
            $tz_min = 0;
            if ( isset($match[10]) && $match[10] == 'Z' ) {
                # zulu time, aka GMT
            } else {
                if (isset($match[8])) {
                    $tz_mod = $match[8];
                }
                if (isset($match[9])) {
                    $tz_hour = $match[9];
                }
                if (isset($match[10])) {
                    $tz_min = $match[10];
                }
                //list( $tz_mod, $tz_hour, $tz_min ) =
                //array( $match[8], $match[9], $match[10]);
                # zero out the variables
                if ( ! $tz_hour ) { $tz_hour = 0; }
                if ( ! $tz_min ) { $tz_min = 0; }
                $offset_secs = (($tz_hour*60)+$tz_min)*60;
                # is timezone ahead of GMT?  then subtract offset
                if ( $tz_mod == '+' ) {
                    $offset_secs = $offset_secs * -1;
                }
                $offset = $offset_secs;
            }
            $epoch = $epoch + $offset;
            return $epoch;
        }
        else {
            return -1;
        }
    }
    ?>
    

    XML_RSSをpearコマンドでインストールしていなければ

    require_once("XML/RSS.php");
    

    require_once("RSS.php");
    

    に変更

    $user = "USER_NAME";
    

    を自分のアカウントに変更

    audioscrobblerのサイトが非常に重いのでキャッシュファイルを使うようにしてる。キャッシュファイルを保存するディレクトリtempを新規作成してパーミッションを777としておく
  • インデックスなり表示したいページに
    <?php include("audioscrobbler.php") ?>
    
    で埋め込む

追記: 2004/09/15 18:34 文字列をhtmlentities()でエンコードし忘れ。

追記: 2004/09/16 09:59 htmlentities()じゃ文字化けするのでhtmlspecialchars()でエンコード。

Trackbacks:

このエントリーのトラックバックURL:

コメントを投稿