Beispiel #1
0
 /**
  * 2ch公式メニューをパースし、板-ホストの対応表を作成する
  *
  * @return  array   site/bbs/(host,itaj) の多次元連想配列
  *                  ダウンロードに失敗したときは false
  */
 private static function _getMapping()
 {
     global $_conf;
     // {{{ 設定
     $bbsmenu_url = 'http://menu.2ch.net/bbsmenu.html';
     // 公式メニューの URL
     $altmenu_url = 'http://www.2ch.se/bbsmenu.html';
     // 代替メニューの URL
     $map_cache_path = $_conf['cache_dir'] . '/host_bbs_map.txt';
     $map_cache_lifetime = 600;
     // TTLは少し短めに
     $err_fmt = '<p>rep2 error: BbsMap: %s - %s をダウンロードできませんでした。</p>';
     $use_alt = false;
     // }}}
     // {{{ キャッシュ確認
     if (!is_null(self::$_map)) {
         return self::$_map;
     } elseif (file_exists($map_cache_path)) {
         $mtime = filemtime($map_cache_path);
         $expires = $mtime + $map_cache_lifetime;
         if (time() < $expires) {
             $map_cahce = file_get_contents($map_cache_path);
             self::$_map = unserialize($map_cahce);
             return self::$_map;
         }
     } else {
         FileCtl::mkdirFor($map_cache_path);
     }
     touch($map_cache_path);
     clearstatcache();
     // }}}
     // {{{ メニューをダウンロード
     if (!class_exists('HTTP_Request', false)) {
         require 'HTTP/Request.php';
     }
     $params = array();
     $params['timeout'] = $_conf['http_conn_timeout'];
     $params['readTimeout'] = array($_conf['http_read_timeout'], 0);
     if (isset($mtime)) {
         $params['requestHeaders'] = array('If-Modified-Since' => http_date($mtime));
     }
     if ($_conf['proxy_use']) {
         $params['proxy_host'] = $_conf['proxy_host'];
         $params['proxy_port'] = $_conf['proxy_port'];
     }
     $req = new HTTP_Request($bbsmenu_url, $params);
     $req->setMethod('GET');
     $err = $req->sendRequest(true);
     // エラーのとき、代わりのメニューを使ってみる
     if (PEAR::isError($err) && $use_alt) {
         P2Util::pushInfoHtml(sprintf($err_fmt, htmlspecialchars($err->getMessage(), ENT_QUOTES), htmlspecialchars($bbsmenu_url, ENT_QUOTES)));
         P2Util::pushInfoHtml(sprintf("<p>代わりに %s をダウンロードします。</p>", htmlspecialchars($altmenu_url, ENT_QUOTES)));
         $bbsmenu_url = $altmenu_url;
         unset($req, $err);
         $req = new HTTP_Request($bbsmenu_url, $params);
         $req->setMethod('GET');
         $err = $req->sendRequest(true);
     }
     // エラーを検証
     if (PEAR::isError($err)) {
         P2Util::pushInfoHtml(sprintf($err_fmt, htmlspecialchars($err->getMessage(), ENT_QUOTES), htmlspecialchars($bbsmenu_url, ENT_QUOTES)));
         if (file_exists($map_cache_path)) {
             return unserialize(file_get_contents($map_cache_path));
         } else {
             return false;
         }
     }
     // レスポンスコードを検証
     $code = $req->getResponseCode();
     if ($code == 304) {
         $map_cahce = file_get_contents($map_cache_path);
         self::$_map = unserialize($map_cahce);
         return self::$_map;
     } elseif ($code != 200) {
         P2Util::pushInfoHtml(sprintf($err_fmt, htmlspecialchars(strval($code), ENT_QUOTES), htmlspecialchars($bbsmenu_url, ENT_QUOTES)));
         if (file_exists($map_cache_path)) {
             return unserialize(file_get_contents($map_cache_path));
         } else {
             return false;
         }
     }
     $res_body = $req->getResponseBody();
     // }}}
     // {{{ パース
     $regex = '!<A HREF=http://(\\w+\\.(?:2ch\\.net|bbspink\\.com|machi\\.to|mathibbs\\.com))/(\\w+)/(?: TARGET=_blank)?>(.+?)</A>!';
     preg_match_all($regex, $res_body, $matches, PREG_SET_ORDER);
     $map = array();
     foreach ($matches as $match) {
         $host = $match[1];
         $bbs = $match[2];
         $itaj = $match[3];
         $type = self::_detectHostType($host);
         if (!isset($map[$type])) {
             $map[$type] = array();
         }
         $map[$type][$bbs] = array('host' => $host, 'itaj' => $itaj);
     }
     // }}}
     // {{{ キャッシュする
     $map_cache = serialize($map);
     if (FileCtl::file_write_contents($map_cache_path, $map_cache) === false) {
         p2die("cannot write file. ({$map_cache_path})");
     }
     // }}}
     return self::$_map = $map;
 }