P2HttpExt::activate(); switch ($spmode) { case 'fav': P2HttpRequestPool::fetchSubjectTxt($_conf['favlist_idx']); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; break; case 'recent': P2HttpRequestPool::fetchSubjectTxt($_conf['recent_idx']); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; break; case 'res_hist': P2HttpRequestPool::fetchSubjectTxt($_conf['res_hist_idx']); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; break; case 'merge_favita': P2HttpRequestPool::fetchSubjectTxt($favitas); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; break; } } elseif ($_conf['expack.use_pecl_http'] == 2) { if (P2CommandRunner::fetchSubjectTxt($spmode, $_conf)) { $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } } } //============================================================ // メイン //============================================================ $aThreadList = new ThreadList(); // {{{ 板とモードのセット $spmode_without_palace_or_favita = false;
if ($_conf['expack.use_pecl_http'] == 1) { P2HttpRequestPool::fetchSubjectTxt($_conf['recent_idx']); } elseif ($_conf['expack.use_pecl_http'] == 2) { P2CommandRunner::fetchSubjectTxt('recent', $_conf); } // 新着数を初期化 initMenuNewSp('recent'); echo <<<EOP <a href="{$_conf['subject_php']}?spmode=recent{$norefresh_q}" onclick="chMenuColor({$matome_i});" accesskey="h">最近読んだスレ</a> (<a href="{$_conf['read_new_php']}?spmode=recent" target="read" id="un{$matome_i}" onclick="chUnColor({$matome_i});"{$class_newres_num}>{$shinchaku_num}</a>)<br> EOP; flush(); // }}} // {{{ 書き込み履歴 // ダウンロード if ($_conf['expack.use_pecl_http'] == 1) { P2HttpRequestPool::fetchSubjectTxt($_conf['res_hist_idx']); } elseif ($_conf['expack.use_pecl_http'] == 2) { P2CommandRunner::fetchSubjectTxt('res_hist', $_conf); } // 新着数を初期化 initMenuNewSp('res_hist'); echo <<<EOP <a href="{$_conf['subject_php']}?spmode=res_hist{$norefresh_q}" onclick="chMenuColor({$matome_i});">書込履歴</a> <a href="read_res_hist.php" target="read">ログ</a> (<a href="{$_conf['read_new_php']}?spmode=res_hist" target="read" id="un{$matome_i}" onclick="chUnColor({$matome_i});"{$class_newres_num}>{$shinchaku_num}</a>)<br> EOP; flush(); // }}} // 新着数を表示しない場合 } else { echo <<<EOP <a href="{$_conf['subject_php']}?spmode=fav{$norefresh_q}" accesskey="f">お気にスレ</a><br> <a href="{$_conf['subject_php']}?spmode=recent{$norefresh_q}" accesskey="h">最近読んだスレ</a><br>
/** * お気に板をHTML表示する * * @access public * @return void */ function printFavItaHtml() { global $_conf, $matome_i, $STYLE; // favita読み込み $favitas = array(); if (file_exists($_conf['favita_path'])) { if ($lines = file($_conf['favita_path'])) { foreach ($lines as $l) { if (preg_match("/^\t?(.+)\t(.+)\t(.+)\$/", trim($l), $matches)) { $favitas[] = array('host' => $matches[1], 'bbs' => $matches[2], 'itaj' => $matches[3]); } } } } // 空っぽなら if (!$favitas) { echo <<<EOP <div class="menu_cate"><b>お気に板</b> [<a href="editfavita.php" target="subject">編集</a>]<br> <div class="itas" id="c_favita">(空っぽ)</div> </div> EOP; return; } // 新着数を表示する場合・まとめてプリフェッチ if ($_conf['enable_menu_new'] && !empty($_GET['shownew'])) { if ($_conf['expack.use_pecl_http'] == 1) { require_once P2_LIB_DIR . '/P2HttpExt.php'; P2HttpRequestPool::fetchSubjectTxt($favitas); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } } $csrfid = P2Util::getCsrfId(); echo <<<EOP <div class="menu_cate"><b><a class="menu_cate" href="javascript:void(0);" onClick="showHide('c_favita', 'itas_hide');" target="_self">お気に板</a></b> [<a href="editfavita.php" target="subject">編集</a>]<br> <div class="itas" id="c_favita"> EOP; foreach ($favitas as $favita) { extract($favita); // $host, $bbs, $itaj $itaj_en = base64_encode($itaj); $uri = UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'setfavita' => '0', 'csrfid' => $csrfid)); $star_atag = P2View::tagA($uri, '★', array('target' => '_self', 'class' => 'fav', 'title' => "「{$itaj}」をお気に板から外す", 'onClick' => "return confirmSetFavIta('" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $itaj) . "');")); // 新着数を表示する場合 if ($_conf['enable_menu_new'] && !empty($_GET['shownew'])) { $matome_i++; // $host, $bbs $spmode = ''; $shinchaku_num = 0; $_newthre_num = 0; include './subject_new.php'; // $shinchaku_num, $_newthre_num がセットされる $newthre_ht = ''; if ($_newthre_num) { $newthre_ht = "{$_newthre_num}"; } $subject_uri = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en)); $subject_atag = P2View::tagA($subject_uri, hs($itaj), array('onClick' => "chMenuColor('{$matome_i}');")); $read_new_uri = UriUtil::buildQueryUri($_conf['read_new_php'], array('host' => $host, 'bbs' => $bbs)); $read_new_attr = array('target' => 'read', 'id' => "un{$matome_i}", 'onClick' => "chUnColor('{$matome_i}');"); if ($shinchaku_num > 0) { $read_new_attr['class'] = 'newres_num'; } else { $read_new_attr['class'] = 'newres_num_zero'; } $read_new_atag = P2View::tagA($read_new_uri, hs($shinchaku_num), $read_new_attr); echo <<<EOP {$star_atag} {$subject_atag} <span id="newthre{$matome_i}" class="newthre_num">{$newthre_ht}</span> ({$read_new_atag})<br> EOP; // 新着数を表示しない場合 } else { $subject_uri = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en)); $subject_atag = P2View::tagA($subject_uri, hs($itaj)); echo "{$star_atag} {$subject_atag}<br>"; } ob_flush(); flush(); } // foreach echo " </div>\n"; echo "</div>\n"; }
/** * お気に板をプリントする */ public function printFavIta() { global $_conf, $matome_i, $STYLE; $menu_php_ht = p2h(isset($GLOBALS['menu_php_self']) ? $GLOBALS['menu_php_self'] : $_SERVER['SCRIPT_NAME']); echo <<<EOP <div class="menu_cate"> <b><a class="menu_cate" href="javascript:void(0);" onclick="showHide('c_favita');" target="_self">お気に板</a></b> [<a href="editfavita.php" target="subject">編集</a>] EOP; // お気に板切り替え if ($_conf['expack.misc.multi_favs']) { echo "<br>\n"; echo FavSetManager::makeFavSetSwitchElem('m_favita_set', 'お気に板', true, "replaceMenuItem('c_favita', 'm_favita_set', this.options[this.selectedIndex].value);"); } if ($_conf['expack.misc.multi_favs']) { $favset_title = FavSetManager::getFavSetPageTitleHt('m_favita_set', 'お気に板'); } else { $favset_title = 'お気に板'; } echo " <div class=\"itas\" id=\"c_favita\">\n"; if ($_conf['merge_favita']) { echo <<<EOP <a href="{$_conf['subject_php']}?spmode=merge_favita{$_conf['m_favita_set_at_a']}">{$favset_title} (まとめ)</a><br> EOP; } // favita読み込み $favitas = array(); if ($lines = FileCtl::file_read_lines($_conf['favita_brd'], FILE_IGNORE_NEW_LINES)) { foreach ($lines as $l) { if (preg_match("/^\t?(.+)\t(.+)\t(.+)\$/", $l, $matches)) { $favitas[] = array('host' => $matches[1], 'bbs' => $matches[2], 'itaj' => $matches[3]); } } } if ($favitas) { // 新着数を表示する場合・まとめてプリフェッチ if ($_conf['enable_menu_new'] && !empty($_GET['new'])) { if ($_conf['expack.use_pecl_http'] == 1) { P2HttpExt::activate(); P2HttpRequestPool::fetchSubjectTxt($favitas); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } elseif ($_conf['expack.use_pecl_http'] == 2) { if (P2CommandRunner::fetchSubjectTxt('merge_favita', $_conf)) { $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } } } foreach ($favitas as $favita) { extract($favita); $itaj_view = p2h($itaj); $itaj_en = UrlSafeBase64::encode($itaj); $itaj_js = addslashes($itaj_view); $p_htm['star'] = <<<EOP <a href="{$menu_php_ht}?host={$host}&bbs={$bbs}&setfavita=0{$_conf['m_favita_set_at_a']}" target="_self" class="fav" title="「{$itaj_view}」をお気に板から外す" onclick="return window.confirm('「{$itaj_js}」をお気に板から外してよろしいですか?');">★</a> EOP; // onclick="return confirmSetFavIta('{$itaj_ht}');" // 新着数を表示する場合 if ($_conf['enable_menu_new'] && !empty($_GET['new'])) { $matome_i++; $spmode = null; // $shinchaku_num, $_newthre_num をセット include P2_LIB_DIR . '/subject_new.inc.php'; if ($shinchaku_num > 0) { $class_newres_num = ' class="newres_num"'; } else { $class_newres_num = ' class="newres_num_zero"'; } if ($_newthre_num) { $newthre_ht = "{$_newthre_num}"; } else { $newthre_ht = ''; } echo <<<EOP {$p_htm['star']} <a href="{$_conf['subject_php']}?host={$host}&bbs={$bbs}&itaj_en={$itaj_en}" onclick="chMenuColor({$matome_i});">{$itaj_view}</a> <span id="newthre{$matome_i}" class="newthre_num">{$newthre_ht}</span> (<a href="{$_conf['read_new_php']}?host={$host}&bbs={$bbs}" target="read" id="un{$matome_i}" onclick="chUnColor({$matome_i});"{$class_newres_num}>{$shinchaku_num}</a>)<br> EOP; // 新着数を表示しない場合 } else { echo <<<EOP {$p_htm['star']} <a href="{$_conf['subject_php']}?host={$host}&bbs={$bbs}&itaj_en={$itaj_en}">{$itaj_view}</a><br> EOP; } flush(); } // foreach // 空っぽなら } else { echo ' (空っぽ)'; } echo " </div>\n</div>\n"; }
fwrite(STDERR, 'Permission denied: cannot write directory ' . $_conf['dat_dir'] . PHP_EOL); exit(1); } if ($mode == 'merge_favita') { $favitas = array(); foreach (file($source, FILE_IGNORE_NEW_LINES) as $l) { if (preg_match('/^\\t?(.+?)\\t(.+?)\\t.+?$/', $l, $matches)) { $_host = $matches[1]; $_bbs = $matches[2]; $_id = $_host . '/' . $_bbs; $favitas[$_id] = array('host' => $_host, 'bbs' => $_bbs); } } P2HttpRequestPool::fetchSubjectTxt($favitas); } else { P2HttpRequestPool::fetchSubjectTxt($source); } // }}} // {{{ 後処理 // エラーメッセージの取得 if (P2Util::hasInfoHtml()) { $errmsg = str_replace("\n", PHP_EOL, P2Util::getInfoHtml()); } else { $errmsg = null; } // デバッグ用ログファイルに書き込む if (P2_FETCH_SUBJECT_TXT_DEBUG) { $debug_output = '====================' . PHP_EOL; $debug_output .= __FILE__ . PHP_EOL; $debug_output .= 'date: ' . date('Y-m-d H:i:s') . PHP_EOL; if (extension_loaded('posix')) {
/** * ■ readList メソッド */ public function readList() { global $_conf; //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('readList()'); switch ($this->spmode) { // ローカルの履歴ファイル 読み込み case 'recent': if ($lines = FileCtl::file_read_lines($_conf['recent_idx'])) { //P2Util::pushInfoHtml('<p>履歴は空っぽです</p>'); //return false; } break; // ローカルの書き込み履歴ファイル 読み込み // ローカルの書き込み履歴ファイル 読み込み case 'res_hist': if ($lines = FileCtl::file_read_lines($_conf['res_hist_idx'])) { //P2Util::pushInfoHtml('<p>書き込み履歴は空っぽです</p>'); //return false; } break; //ローカルのお気にファイル 読み込み //ローカルのお気にファイル 読み込み case 'fav': if ($lines = FileCtl::file_read_lines($_conf['favlist_idx'])) { //P2Util::pushInfoHtml('<p>お気にスレは空っぽです</p>'); //return false; } break; // お気に板をまとめて読み込み // お気に板をまとめて読み込み case 'merge_favita': $favitas = array(); if (file_exists($_conf['favita_brd'])) { foreach (file($_conf['favita_brd']) as $l) { if (preg_match("/^\t?(.+?)\t(.+?)\t.+?\$/", rtrim($l), $m)) { $favitas[] = array('host' => $m[1], 'bbs' => $m[2]); } } } if (empty($_REQUEST['norefresh']) && !(empty($_REQUEST['refresh']) && isset($_REQUEST['word']))) { if ($_conf['expack.use_pecl_http'] == 1) { P2HttpExt::activate(); P2HttpRequestPool::fetchSubjectTxt($favitas); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } elseif ($_conf['expack.use_pecl_http'] == 2) { if (P2CommandRunner::fetchSubjectTxt('merge_favita', $_conf)) { $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } } } $lines = array(); $i = 0; foreach ($favitas as $ita) { $aSubjectTxt = new SubjectTxt($ita['host'], $ita['bbs']); $k = (double) sprintf('0.%d', ++$i); if (is_array($aSubjectTxt->subject_lines)) { $j = 0; foreach ($aSubjectTxt->subject_lines as $l) { if (preg_match('/^([0-9]+)\\.(?:dat|cgi)(?:,|<>)(.+) ?(?:\\(|()([0-9]+)(?:\\)|))/', $l, $m)) { $lines[] = array('key' => $m[1], 'ttitle' => rtrim($m[2]), 'rescount' => (int) $m[3], 'host' => $ita['host'], 'bbs' => $ita['bbs'], 'torder' => ++$j + $k); } } } } break; // p2_threads_aborn.idx 読み込み // p2_threads_aborn.idx 読み込み case 'taborn': $taborn_file = $this->getIdxDir() . 'p2_threads_aborn.idx'; $lines = FileCtl::file_read_lines($taborn_file); break; // spmodeがdat倉庫の場合 // spmodeがdat倉庫の場合 case 'soko': $dat_host_bbs_dir = $this->getDatDir(false); $idx_host_bbs_dir = $this->getIdxDir(false); $lines = array(); //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('dat'); // datログディレクトリを走査して孤立datにidx付加 if ($cdir = dir($dat_host_bbs_dir)) { // or die ("ログディレクトリがないよ!"); // ディレクトリ走査 while ($entry = $cdir->read()) { if (preg_match('/([0-9]+)\\.dat$/', $entry, $matches)) { $theidx = $idx_host_bbs_dir . DIRECTORY_SEPARATOR . $matches[1] . '.idx'; if (!file_exists($theidx)) { $thedat = $dat_host_bbs_dir . DIRECTORY_SEPARATOR . $entry; if ($datlines = FileCtl::file_read_lines($thedat, FILE_IGNORE_NEW_LINES)) { $firstdatline = $datlines[0]; if (strpos($firstdatline, '<>') !== false) { $datline_sepa = '<>'; } else { $datline_sepa = ','; } $d = explode($datline_sepa, $firstdatline); $atitle = $d[4]; $gotnum = sizeof($datlines); $readnum = $gotnum; $anewline = $readnum + 1; $data = array($atitle, $matches[1], '', $gotnum, '', $readnum, '', '', '', $anewline, '', '', ''); P2Util::recKeyIdx($theidx, $data); } } // array_push($lines, $idl[0]); } } $cdir->close(); } //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('dat'); //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('idx'); // {{{ idxログディレクトリを走査してidx情報を抽出してリスト化 if ($cdir = dir($idx_host_bbs_dir)) { // or die ("ログディレクトリがないよ!"); // ディレクトリ走査 while ($entry = $cdir->read()) { if (preg_match('/([0-9]+)\\.idx$/', $entry)) { $thedix = $idx_host_bbs_dir . DIRECTORY_SEPARATOR . $entry; $idl = FileCtl::file_read_lines($thedix); if (is_array($idl)) { array_push($lines, $idl[0]); } } } $cdir->close(); } // }}} //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('idx'); break; // スレの殿堂の場合 // p2_palace.idx 読み込み // スレの殿堂の場合 // p2_palace.idx 読み込み case 'palace': if ($lines = FileCtl::file_read_lines($_conf['palace_idx'])) { //P2Util::pushInfoHtml('<p>殿堂はがらんどうです</p>'); //return false; } break; // オンライン上の subject.txt を読み込む(spmodeでない場合) // オンライン上の subject.txt を読み込む(spmodeでない場合) default: if (!$this->spmode) { $aSubjectTxt = new SubjectTxt($this->host, $this->bbs); $lines = $aSubjectTxt->subject_lines; } } //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('readList()'); return $lines; }