d3pipes sf.net tracker parser

1週間ほど、XOOPS Cube のトラッカ代理上げ(どっかの掲示板でバグ報告があった場合に、sourceforge.net に転載する)を担当することになりました。現在募集中です

今まで sf.net のトラッカのチェックをしていなかったんですが、代理上げの際に「すでに報告されているバグか」を判断しなければならないため、まあ今からですがチェックすることにしました。

そこで知ったのが、「sf.net のトラッカには RSS フィードが無い」という事実。「確かフィードのアイコンが出てたよな〜」と思って中身を見たら、新バージョンやドキュメント更新の RSS は提供されているみたいなんですがトラッカのは無い。

というわけで、無理やり作りました。d3pipes 用のパーサです。前に作ったはてなコメントと違って、適当な class 等は存在しないため、かなり無理やり取ってきています。sf.net のHTMLデザインが変わると機能停止してしまいます(^ ^;。

また、なぜか sf.net のトラッカ上の日付から16時間ずれます。見たけど分かりませんでした。*1

それでもいい、という方のみご利用ください(原因が分かる方がいらっしゃいましたら教えてください m(_ _)m)。

html の table からデータを取得してきていますので、同じように他の table からパースしたいという方の参考にもなるかもしれません。

ここからデータを取得するという想定で作っています。
http://sourceforge.net/tracker/?group_id=159211&atid=943471

ファイル名は,D3pipesParseSfnettracker.class.php にしてください。

<?php

#Sourceforge.net Tracker Parser for d3pipes
#HIKAWA Kilica  2007-06-16
#http://d.hatena.ne.jp/kilica or http://www.trpg-labo.com/


require_once dirname(dirname(__FILE__)).'/D3pipesParseAbstract.class.php' ;

class D3pipesParseSfnettracker extends D3pipesParseAbstract {

  function execute($html_source, $max_entries='')
  {
    
    $item = array();
    //Extract a Tracker List Table.
    preg_match('#\<table width\=\"100%\" border\=\"0\" cellspacing\=\"2\" cellpadding\=\"3\"\>(.*)?\</table\>#siU', $html_source, $trtable);

    if(! $trtable){
      $this->errors[] = 'NO tracker table in this page, or invalid pattern';
      return array();
    }

    //Split the table into rows(tr).
    preg_match_all('@\<tr bgcolor\=\"#da.*\>(.*)?\</tr\>@siU', $trtable[1], $tr, PREG_SET_ORDER);
      if(! $tr){
        $this->errors[] = 'Invalid tr pattern for this Parser';
      }
    //Deal with each row(tr)
    foreach($tr as $row){
      if(! $row){
        $this->errors[] = 'Invalid tr pattern for this Parser('.array_keys($row).')';
      }
      //Divide a row into items(td)
      preg_match_all('#\<td.*\>(.*)\</td\>#siU', $row[1], $td, PREG_SET_ORDER);
      if(! $td){
        $this->errors[] = 'Invalid td pattern for this Parser';
      }
      //Extract link and title
      preg_match('#\<a href\=\"(.*)?\"\>.*\<\!-- google_ad_section_start --\>(.*)?\<\!-- google_ad_section_end --\>.*\</a\>#siU', $td[1][1], $title);
      if(! $title){
        $this->errors[] = 'Invalid pattern for this Parser:title';
      }
      //Extract user name
      preg_match('#\<a href\=\"(.*)?\"\>(.*)?\</a\>#siU', $td[5][1], $user);
      if(! $user){
        $this->errors[] = 'Invalid pattern for this Parser:user';
      }
      $linka = str_replace('&amp;', '&', $title[1]);
      //set RSS items
      $link = "http://sourceforge.net/" .$linka;
      $headline = $title[2]. ' (submitted by ' .$user[2]. ')';
      //pubtime
      preg_match('#[0-9]+-[0-9]+-[0-9]+ [0-9]+\:[0-9]+#si', $td[2][1], $posttime);
      $pubtime = strtotime( $posttime[0] ) + 16 * 3600 ;
      //Set RSS items
      $items[] = array(
        'headline' => $headline,
        'pubtime' => $pubtime,
        'link' => $link,
        'fingerprint' => $td[1][1]
      );
    }
    return $items;
  }
}

?>

*1:GIJOE さんから、ログインしているかどうかでずれると教えてきただきました。RSSで取ってきたデータに16時間足すようにしました。→参考