-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add stakepoolfinder and caching infrastructure (#5)
- Loading branch information
Showing
29 changed files
with
576 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
<?php | ||
|
||
$GLOBALS["clearcache"] = 0; | ||
$GLOBALS["debug"] = 0; | ||
|
||
if ($GLOBALS["clearcache"]) { | ||
apcu_clear_cache(); | ||
} | ||
|
||
$spdata = array( | ||
"Bravo" => array( | ||
"launchedEpoch" => strtotime("Sun May 22 17:54:00 CDT 2016"), | ||
"lastAttempt" => 0, | ||
"lastUpdated" => 0, | ||
"url" => "https://dcr.stakepool.net", | ||
), | ||
"Delta" => array( | ||
"launchedEpoch" => strtotime("Thu May 19 10:19:00 CDT 2016"), | ||
"lastAttempt" => 0, | ||
"lastUpdated" => 0, | ||
"url" => "https://dcr.stakeminer.com", | ||
), | ||
"Echo" => array( | ||
"launchedEpoch" => strtotime("Mon May 23 12:59:00 CDT 2016"), | ||
"lastAttempt" => 0, | ||
"lastUpdated" => 0, | ||
"url" => "http://pool.d3c.red", | ||
), | ||
"Golf" => array( | ||
"launchedEpoch" => strtotime("Wed May 25 04:09:00 CDT 2016"), | ||
"lastAttempt" => 0, | ||
"lastUpdated" => 0, | ||
"url" => "https://stakepool.dcrstats.com", | ||
), | ||
"India" => array( | ||
"launchedEpoch" => strtotime("Sun May 22 13:58:00 CDT 2016"), | ||
"lastAttempt" => 0, | ||
"lastUpdated" => 0, | ||
"url" => "http://stakepool.eu", | ||
) | ||
); | ||
|
||
foreach ($spdata as $i => $d) { | ||
apcu_add("spcache-{$i}", $d); | ||
} | ||
|
||
switch ($_REQUEST["c"]) { | ||
// clear cache | ||
case "cc": | ||
if ($_SERVER["REMOTE_ADDR"] == "127.0.0.1" || $_SERVER["REMOTE_ADDR"] == "::1") { | ||
apcu_clear_cache(); | ||
print "cache cleared\n"; | ||
} else { | ||
print "unauthorized\n"; | ||
} | ||
break; | ||
// get insight status; | ||
case "gis": | ||
$status = getInsightStatus(); | ||
print $status; | ||
break; | ||
// get downloads image | ||
case "gdi": | ||
header("Content-type: image/png"); | ||
$png = getDownloadsImage(); | ||
print $png; | ||
break; | ||
// get stakepool data | ||
case "gsd": | ||
getStakepoolData($spdata); | ||
$allpooldata = array(); | ||
foreach (array_keys($spdata) as $i) { | ||
$allpooldata[$i] = apcu_fetch("spcache-{$i}"); | ||
} | ||
print json_encode($allpooldata); | ||
break; | ||
} | ||
|
||
function debugLog($s) { | ||
if ($GLOBALS["debug"]) { | ||
error_log($s); | ||
} | ||
} | ||
|
||
function getDownloadsImage() { | ||
$cacheTTL = 24 * 60 * 60; | ||
$timeOut = 3; | ||
$png = file_get_contents("../content/images/total.png"); | ||
$url = "https://img.shields.io/github/downloads/decred/decred-release/total.png"; | ||
|
||
$curPng = apcu_fetch("gdi"); | ||
if (empty($curPng)) { | ||
$c = curl_init($url); | ||
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, $timeOut); | ||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); | ||
curl_setopt($c, CURLOPT_TIMEOUT, $timeOut); | ||
$r = curl_exec($c); | ||
if ($r === false) { | ||
error_log("curl error: " . curl_error($c) . " (errno: " . curl_errno($c) . ") while scraping {$url}"); | ||
} else { | ||
// XXX PHP image validation functions seem to require a file | ||
if (!empty($r)) { | ||
apcu_store("gdi", $r, $cacheTTL); | ||
} | ||
$png = $r; | ||
} | ||
} else { | ||
$png = $curPng; | ||
} | ||
|
||
return $png; | ||
} | ||
|
||
function getInsightStatus() { | ||
$cacheTTL = 60; | ||
$timeOut = 1; | ||
$status = '{"info":{"blocks":"-"}}'; | ||
$url = "https://mainnet.decred.org/api/status"; | ||
|
||
$curStatus = apcu_fetch("gsi"); | ||
|
||
if (empty($curStatus)) { | ||
$c = curl_init($url); | ||
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, $timeOut); | ||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); | ||
curl_setopt($c, CURLOPT_TIMEOUT, $timeOut); | ||
$r = curl_exec($c); | ||
if ($r === false) { | ||
error_log("curl error: " . curl_error($c) . " (errno: " . curl_errno($c) . ") while scraping {$url}"); | ||
} else { | ||
$jd = json_decode($r, true); | ||
if (!empty($jd)) { | ||
apcu_store("gsi", $r, $cacheTTL); | ||
} | ||
$status = $r; | ||
} | ||
} else { | ||
$status = $curStatus; | ||
} | ||
|
||
return $status; | ||
} | ||
|
||
function getStakepoolData($spdata) { | ||
$interval = 20 * 60; | ||
$timeOut = 2; | ||
|
||
foreach (array_keys($spdata) as $i) { | ||
$d = apcu_fetch("spcache-{$i}"); | ||
if (isset($d["lastUpdated"]) && time() - $d["lastUpdated"] > $interval && time() - $d["lastAttempt"] > $interval) { | ||
debugLog("updating $i: {$d["url"]}"); | ||
$d["lastAttempt"] = time(); | ||
$c = curl_init("{$d["url"]}/stats"); | ||
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, $timeOut); | ||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); | ||
// XXX if getstakeinfo isn't cached then this takes a long time | ||
// XXX should probably be parallelized | ||
curl_setopt($c, CURLOPT_TIMEOUT, $timeOut*3); | ||
$r = curl_exec($c); | ||
curl_close($c); | ||
if ($r === false) { | ||
apcu_store("spcache-{$i}", $d); | ||
error_log("curl error: " . curl_error($c) . " (errno: " . curl_errno($c) . ") while scraping {$d["url"]}/stats"); | ||
} else { | ||
$nd = array( | ||
"Immature" => "", | ||
"Live" => "", | ||
"Voted" => "", | ||
"Missed" => "", | ||
"PoolFees" => "", | ||
"UserCount" => "", | ||
"PoolStatus" => "", | ||
); | ||
foreach (array_keys($nd) as $k) { | ||
if (preg_match("/\<span id=\"{$k}\"\>(.*?)\<\/span\>/m", $r, $m)) { | ||
$nd[$k] = $m[1]; | ||
} | ||
} | ||
foreach ($nd as $k => $v) { | ||
if ($v == "") { | ||
$nd[$k] = "N/A"; | ||
$nd["PoolStatus"] = "Unknown"; | ||
} | ||
} | ||
foreach ($nd as $k => $v) { | ||
// don't cache failed reads | ||
if (array_key_exists($k, $d) && $d[$k] != "N/A" && $v == "N/A") { | ||
continue; | ||
} | ||
$d[$k] = $v; | ||
} | ||
$d["lastAttempt"] = time(); | ||
$d["lastUpdated"] = time(); | ||
apcu_store("spcache-{$i}", $d); | ||
debugLog("updated $i"); | ||
} | ||
} else { | ||
debugLog("no updates required for {$i}"); | ||
} | ||
} | ||
} | ||
|
||
?> |
Large diffs are not rendered by default.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,130 @@ | ||
document.onload = ajaxGet(null,"ghcommits","https://api.github.com/repos/decred/dcrd/stats/commit_activity"); | ||
|
||
function ajaxGet(param,container,page){ | ||
var xmlhttp; | ||
|
||
if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari | ||
xmlhttp=new XMLHttpRequest(); | ||
}else{// code for IE6, IE5 | ||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); | ||
} | ||
|
||
xmlhttp.onreadystatechange=function(){ | ||
if(xmlhttp.readyState==4 && xmlhttp.status==200){ | ||
var jsonResult = JSON.parse(xmlhttp.responseText); | ||
var commits = 0; | ||
|
||
for(var j in jsonResult){ | ||
commits += jsonResult[j]['total']; | ||
console.log(commits); | ||
} | ||
|
||
document.getElementById(container).innerHTML=commits; | ||
} | ||
} | ||
|
||
xmlhttp.open("GET",page,true); | ||
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); | ||
xmlhttp.send(null); | ||
} | ||
(function ($) { | ||
$.fn.styleTable = function (options) { | ||
var defaults = { | ||
css: 'styleTable' | ||
}; | ||
options = $.extend(defaults, options); | ||
|
||
return this.each(function () { | ||
|
||
input = $(this); | ||
input.addClass(options.css); | ||
|
||
input.find("tr").on('mouseover mouseout', function (event) { | ||
if (event.type == 'mouseover') { | ||
$(this).children("td").addClass("ui-state-hover"); | ||
} else { | ||
$(this).children("td").removeClass("ui-state-hover"); | ||
} | ||
}); | ||
|
||
input.find("th").addClass("ui-state-default"); | ||
input.find("td").addClass("ui-widget-content"); | ||
|
||
input.find("tr").each(function () { | ||
$(this).children("td:not(:first)").addClass("first"); | ||
$(this).children("th:not(:first)").addClass("first"); | ||
}); | ||
}); | ||
}; | ||
})(jQuery); | ||
|
||
var stakepoolFinder = function() { | ||
var fields = ["PoolFees", "PoolStatus", "Voted", "Missed", "Live", "Immature", "UserCount"]; | ||
|
||
tableMarkup = '<table id="pooldata" class="datatables ui-widget ui-widget-content">' + | ||
'<thead>' + | ||
'<tr class="ui-widget-header">' + | ||
'<th>Launch Date</th>' + | ||
'<th>Pool ID</th>' + | ||
'<th>URL</th>' + | ||
'<th>Last Updated</th>'; | ||
$.each(fields, function(i, field) { | ||
tableMarkup += '<th>' + field + '</th>'; | ||
}); | ||
|
||
tableMarkup += '</tr></thead><tbody>'; | ||
|
||
$("#stakepool-data").html("Loading..."); | ||
$.ajax({ | ||
url: "./api/", | ||
data: { c: "gsd"}, | ||
dataType: "json", | ||
error: function (jqXHR, textStatus, errorThrown) { | ||
errorMarkup ='<div class="ui-widget"><div class="ui-state-error ui-corner-all">' + | ||
'<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>' + | ||
'<strong>Error:</strong> ' + textStatus + ": " + errorThrown + '</p></div></div>'; | ||
}, | ||
success: function(data, textStatus) { | ||
$.each(data, function(poolName, poolData ) { | ||
tableMarkup += '<tr>'; | ||
tableMarkup += '<td><span>' + moment.unix(poolData["launchedEpoch"]).format("MMMM Do YYYY, HH:mm:ss") + '</span></td>'; | ||
tableMarkup += '<td>' + poolName + '</td>'; | ||
tableMarkup += '<td><a href="' + poolData["url"] + '">' + poolData["url"] + '</a></td>'; | ||
tableMarkup += '<td>' + moment.unix(poolData["lastUpdated"]).format("MMMM Do YYYY, HH:mm:ss") + '</td>'; | ||
|
||
$.each(fields, function(i, field) { | ||
if (poolData.hasOwnProperty(field)) { | ||
var value = poolData[field] | ||
if (field == "PoolFees") { | ||
if (value.substr(-1) != "%") { | ||
value += "%"; | ||
} | ||
} | ||
tableMarkup += '<td>' + value + '</td>'; | ||
} else { | ||
tableMarkup += '<td>N/A</td>'; | ||
} | ||
}); | ||
|
||
tableMarkup += '</tr>'; | ||
}); | ||
|
||
tableMarkup += '</tbody></table>'; | ||
$("#stakepool-data").html(tableMarkup); | ||
$("#pooldata").DataTable({ | ||
"jQueryUI": true, | ||
"order": [[ 5, 'asc' ], [ 0, 'asc' ]], | ||
"paging": false, | ||
"searching": false, | ||
}); | ||
$("#pooldata").styleTable(); | ||
}, | ||
}); | ||
|
||
$("#stakepool-dialog").dialog({ | ||
height: 400, | ||
width: $(window).width() - 180, | ||
modal: false, | ||
buttons: { | ||
Close: function() { | ||
$(this).dialog("close"); | ||
} | ||
} | ||
}); | ||
}; | ||
|
||
$(document).ready(function() { | ||
var blockexplorer = $.PeriodicalUpdater("./api/?c=gis", { | ||
method: 'get', | ||
maxCalls: 0, | ||
autoStop: 0, | ||
minTimeout: 5000, | ||
maxTimeout: 60000, | ||
multiplier: 2, | ||
runatonce: true, | ||
type: "text", | ||
verbose: 0 | ||
}, function(response, success, xhr, handle) { | ||
if (success) { | ||
var json = $.parseJSON(response); | ||
$("#blockheight").text(json["info"]["blocks"]); | ||
// just use connections until we have a proper node counter | ||
//$("#nodes").text(json["info"]["connections"]); | ||
} else { | ||
$("#blockheight").text("-"); | ||
$("#nodes").text("-"); | ||
blockexplorer.stop(); | ||
} | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.