#author("2020-04-07T12:18:53+09:00","","")
#author("2020-04-07T12:25:17+09:00","","")
** fahstats.inc.php [#l210053c]
|RIGHT:100|LEFT:360|c
|~サマリ|Folding@home の統計情報を表示|
|~リビジョン|1.1|
|~対応バージョン|1.5.3|
|~投稿者|[[M.Taniguchi]]|
|~投稿日|&new{2020-04-05 (日) 10:38:06};|

**概要 [#y413f247]
Folding@home の統計情報を表示するプラグイン。~

ユーザー(ドナー)個人統計とチーム統計の2種類を表示できます。

統計情報は公式APIから取得します。~
負荷軽減のためと、API側の情報更新頻度が低いうえ応答を返さないこともあるため、結果はキャッシュして一定時間使い回します。~
リアルタイム性は低いものとご理解ください。

PukiWiki 1.5.3/PHP 7.4 で動作確認済み。旧バージョンでもおそらく動くと思いますが、PHPは5.2以上が必要です。また、外部のAPIサーバーに接続するためcURLを使います。

※セキュリティホールがあったため修正しました。お使いの方はお手数ですが最新版に更新してください。

~

**使い方 [#e6f9146e]

-#fahstats(ユーザー名)
-#fahstats(チームID)

~
''引数''

-ユーザー名 … ユーザー名を表す文字列
-チームID … チームIDを表す数字

~
''使用例・出力例''

 #fahstats(FahstatsSample)

|LEFT:310||c
|~Donor|FahstatsSample|
|~Date of last Work Unit|2020-04-04 20:17:39|
|~Total score|20,403,714|
|~Total WUs|272|
|~Overall rank (if points are combined)|16,076 of 2,506,022|
|~Active clients (within 50 days)|2|
|~Active clients (within 7 days)|2|

 #fahstats(999999)

|LEFT:310||c
|~Team|FahstatsSampleTeam|
|~Date of last Work Unit|2020-04-04 23:21:25|
|~Active CPUs within 50 days|18,791|
|~Team ID|999999|
|~Grand score|1,066,046,605,865|
|~Work Unit count|18,246,554|
|~Team ranking|1 of 248,004|

~
**コード [#c2352d1c]

fahstats.inc.php~
(下記のコードをコピーして、plugin ディレクトリに fahstats.inc.php というファイル名で保存してください)

 <?php
 /*
 PukiWiki - Yet another WikiWikiWeb clone.
 fahstats.inc.php, v1.1 2020 M.Taniguchi
 License: GPL v3 or (at your option) any later version
 
 Folding@home の統計情報を表示するプラグイン。
 
 ユーザー(ドナー)個人統計とチーム統計の2種類を表示できます。
 
 統計情報は公式APIから取得します。
 負荷軽減のためと、もとよりAPI側の情報更新頻度が低いうえ応答を返さないこともあるため、結果はキャッシュして一定時間使い回します。
 リアルタイム性は低いものとご理解ください。
 
 【使い方】
 #fahstats(ユーザー名)
 #fahstats(チームID)
 &fahstats(ユーザー名){テキスト};
 &fahstats(チームID){テキスト};
 
 【引数】
 ユーザー名 … ユーザー名を表す文字列
 チームID … チームIDを表す数字
 テキスト … 表示する文字列。文字列内の「%キー名%」が対応する値に置換される。キー/値について詳しくは、本プラグイン実行後に生成されるキャッシュファイル cache/fahstats.*.dat 内を参照
 
 【使用例】
 #fahstats(FahstatsSample)
 #fahstats(999999)
 &fahstats(FahstatsSample){%name%さんのポイントは%credit%、処理したワークユニット数は%wus%です。};
 &fahstats(999999){%name%チームのポイントは%credit%、処理したワークユニット数は%wus%です。};
 */
 
 define('PLUGIN_FAHSTATS_URL', 'https:/'.'/stats.foldingathome.org/');		// Folding@home統計情報ドメイン
 define('PLUGIN_FAHSTATS_URL_DONOR', PLUGIN_FAHSTATS_URL . 'api/donor/');	// Folding@homeドナー情報APIのURL
 define('PLUGIN_FAHSTATS_URL_TEAM',  PLUGIN_FAHSTATS_URL . 'api/team/');		// Folding@homeチーム情報APIのURL
 
 define('PLUGIN_FAHSTATS_API_INTERVAL', (4 * 60 * 60));	// APIアクセス間隔(秒)※短くしすぎてサーバーに負荷をかけないよう注意。もとよりAPI側の情報更新頻度は低く(公式には1時間毎)、あまり短くしても無駄
 define('PLUGIN_FAHSTATS_API_TIMEOUT', 30);	// APIタイムアウト時間(秒)
 
 define('PLUGIN_FAHSTATS_RECURSIVE', false);	// trueなら入れ子の情報を再帰的に走査する。テキスト引数でより詳細な情報を表示したいときに使う
 
 
 function plugin_fahstats_convert() {
 	list($id) = func_get_args();
 	return plugin_fahstats_exec($id);
 }
 
 function plugin_fahstats_inline() {
 	$args = func_get_args();
 	$id = $args[0];
 	$text = array_pop($args);
 	return plugin_fahstats_exec($id, $text);
 }
 
 // 実行
 function plugin_fahstats_exec($id, $text = null) {
 	$id = trim((string)$id);
 	if ($id === '') return;
 	$team = is_numeric($id);	// 第1引数が数字ならチームIDとみなす(数字だけの名前のユーザーは勘弁…)
 
 	$cacheFile = CACHE_DIR . 'fahstats' . (($id != '')? '.' . encode($id) : '') . '.dat';	// キャッシュファイルパス
 	$data = null;
 
 	// キャッシュファイルがない、またはキャッシュが古くなっていたらAPIから最新情報を取得
 	if (!file_exists($cacheFile) || (filemtime($cacheFile) < (time() - max(PLUGIN_FAHSTATS_API_INTERVAL, 600)))) {
 		// APIアクセス
 		$ch = curl_init();
 		curl_setopt($ch, CURLOPT_URL, (($team)? PLUGIN_FAHSTATS_URL_TEAM : PLUGIN_FAHSTATS_URL_DONOR) . rawurlencode($id));
 		curl_setopt($ch, CURLOPT_HEADER, false);
 		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 		curl_setopt($ch, CURLOPT_TIMEOUT, PLUGIN_FAHSTATS_API_TIMEOUT);
 		$data = curl_exec($ch);
 		curl_close($ch);
 
 		// 成功?
 		if ($data) {
 			// JSONデコード
 			$data = json_decode($data);
 			if (!$data || isset($data->error)) return;
 			$data = plugin_fahstats_readdata($data);	// 情報を走査
 
 			// キャッシュファイル書き込み
 			$fp = fopen($cacheFile, 'w');
 			flock($fp, LOCK_EX);
 			rewind($fp);
 			fwrite($fp, json_encode($data));
 			flock($fp, LOCK_UN);
 			fclose($fp);
 		}
 	}
 
 	// 情報がなければキャッシュファイル読み込み
 	if (!$data) {
 		$fp = fopen($cacheFile, 'r');
 		$data = json_decode(fread($fp, filesize($cacheFile)));
 		fclose($fp);
 	}
 	if (!$data) return;
 
 	// デフォルト表示:表形式
 	$url = PLUGIN_FAHSTATS_URL;
 	$thStyle = ' style="text-align:left;width:21em"';
 	$tdStyle = ' style="text-align:left;width:14em"';
 	if (!$text) {
 		if (!$team) {
 			// ドナー情報
 			$text = <<<EOT
 <table class="style_table" cellspacing="1" border="0">
 	<tbody>
 		<tr><th class="style_th"${thStyle}">Donor</th><td class="style_td"${tdStyle}><a href="${url}%path%" rel="noopener nofollow external">%name%</a></td></tr>
 		<tr><th class="style_th"${thStyle}>Date of last Work Unit</th><td class="style_td"${tdStyle}>%last%</td></tr>
 		<tr><th class="style_th"${thStyle}>Total score</th><td class="style_td"${tdStyle}>%credit%</td></tr>
 		<tr><th class="style_th"${thStyle}>Total WUs</th><td class="style_td"${tdStyle}>%wus%</td></tr>
 		<tr><th class="style_th"${thStyle}>Overall rank (if points are combined)</th><td class="style_td"${tdStyle}>%rank% of %total_users%</td></tr>
 		<tr><th class="style_th"${thStyle}>Active clients (within 50 days)</th><td class="style_td"${tdStyle}>%active_50%</td></tr>
 		<tr><th class="style_th"${thStyle}>Active clients (within 7 days)</th><td class="style_td"${tdStyle}>%active_7%</td></tr>
 	</tbody>
 </table>
 EOT;
 		} else {
 			// チーム情報
 			$text = <<<EOT
 <table class="style_table" cellspacing="1" border="0">
 	<tbody>
 		<tr><th class="style_th"${thStyle}>Team</th><td class="style_td"${tdStyle}><a href="${url}%path%" rel="noopener nofollow external">%name%</a></td></tr>
 		<tr><th class="style_th"${thStyle}>Date of last Work Unit</th><td class="style_td"${tdStyle}>%last%</td></tr>
 		<tr><th class="style_th"${thStyle}>Active CPUs within 50 days</th><td class="style_td"${tdStyle}>%active_50%</td></tr>
 		<tr><th class="style_th"${thStyle}>Team ID</th><td class="style_td"${tdStyle}>%team%</td></tr>
 		<tr><th class="style_th"${thStyle}>Grand score</th><td class="style_td"${tdStyle}>%credit%</td></tr>
 		<tr><th class="style_th"${thStyle}>Work Unit count</th><td class="style_td"${tdStyle}>%wus%</td></tr>
 		<tr><th class="style_th"${thStyle}>Team ranking</th><td class="style_td"${tdStyle}>%rank% of %total_teams%</td></tr>
 	</tbody>
 </table>
 EOT;
 		}
 	}
 
 	// テキスト置換
 	$search = array();
 	$replace = array();
 	foreach ($data as $key => $val) {
 		$search[] = $key;
 		$replace[] = $val;
 	}
 	$text = str_replace($search, $replace, $text);
 
 	return $text;
 }
 
 // 情報を走査
 function plugin_fahstats_readdata($data, $prefix = null) {
 	if ($prefix) $prefix .= ':';
 
 	$result = array();
 	foreach ($data as $key => $val) {
 		if (is_array($val) || is_Object($val)) {
 			// 入れ子を再帰的に走査
 			if (PLUGIN_FAHSTATS_RECURSIVE) {
 				$result = array_merge($result, plugin_fahstats_readdata($val, $prefix . $key));
 			}
 		} else {
 			if (is_numeric($val) && strpos($key, 'id') === false && $key != 'team' && $key != 'year') $val = number_format($val);
 			$result['%' . $prefix . $key . '%'] = $val;
 		}
 	}
 
 	return $result;
 }
 

~

**高度な使い方:表形式ではなく、任意の文字列で表示 [#z3729e77]

-&fahstats(ユーザー名){テキスト};
-&fahstats(チームID){テキスト};

~
''引数''

-テキスト … 表示する文字列。文字列内の「%キー名%」が対応する値に置換される。主なキー/値は下表の通り。

~

|~キー|~値|h
|name|名前|
|credit|ポイント|
|wus|ワークユニット数|
|last|最終処理日時|
|rank|順位|
|active_50|過去50日間の使用クライアント数|
|active_7|過去7日間の使用クライアント数|
|team|チームID|
|total_users|総ユーザー数|
|total_teams|総チーム数|

※ドナー統計時のみ有効、チーム統計時のみ有効な値もあります。他のキー/値など、詳しくは本プラグイン実行後に生成されるキャッシュファイル cache/fahstats.*.dat 内を参照してください。

~
''使用例・出力例''

 &fahstats(FahstatsSample){%name%さんのポイントは%credit%、処理したワークユニット数は%wus%です。};

FahstatsSampleさんのポイントは20,403,714、処理したワークユニット数は272です。

~

 &fahstats(999999){%name%チームのポイントは%credit%、処理したワークユニット数は%wus%です。};

FahstatsSampleTeamチームのポイントは1,066,046,605,865、処理したワークユニット数は18,246,554です。

~

**ライセンス [#sbbfcb71]

GPL v3

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u12. HTML convert time: 0.053 sec.

OSDN