##JavaSript / Soapi.JS (V2)
using Soapi.JS (V2)
yes, this is a teaser - v2 will be released before the weekend.
var apiKey = "my-foo-bar-fu-is-strong";
var ctx = new Soapi.ApiContext(apiKey);
ctx.initialize(function() {
// all available sites have been loaded from stackauth
// to track loading of stats
var counter = 0;
// now we load the .stats property of the Site object
for (var i = 0; i < ctx.sites.length; i++) {
var site = ctx.sites[i];
if (!site.stats) {
counter++;
site.get_stats(function(data, site_as_context) {
// keep the user informed
document.getElementById("output")
.innerHTML = "loaded stats for "
+ site_as_context.name;
/* is it */soupYet()/*?*/;
},
function(error, site_as_context) { // site sent as userContext
// keep the user informed
document.getElementById("output")
.innerHTML = "failed to loaded stats for "
+ site_as_context.name;
// the request failed but we must decrement the counter
/* is it */soupYet()/*?*/;
}, site /* as context */);
};
};
// that's all the code it takes to get all sites from stackauth and
// the statistics for each. More then half of it is exception handling
// and progress updates.
// the rest is the code to render the /sites and /stats data to HTML
function soupYet(/*?*/) {
// check to see if all sites have been loaded
if (--counter == 0) {
// dump all to table
var output = "<table cellpadding='0' cellspacing='0' style='border:solid 1px silver;'> \
<tr class='header'><td>Site</td><td>State</td><td>Tags</td><td>Logo</td><td>API</td> \
<td>v.p.d</td><td>users</td><td>questions</td><td>q.p.m.</td><td>accepted</td> \
<td>unanswered</td><td>answers</td><td>a.p.m</td><td>comments</td><td>votes</td> \
<td>badges</td><td>b.p.m.</td></tr>";
for (var i = 0; i < ctx.sites.length; i++) {
var site = Soapi.Domain.Site(ctx.sites[i]);
output += "<tr>"
+ "<td><img src='" + site.icon_url + "' style='width:32px;height:32px;'/>"
+ "<a href='" + site.site_url + "' style='color:" + site.styling.link_color
+ ";' target='_blank' title='" + site.description.replace("'", "`") + "'>" + site.name + "</a></td>"
+ "<td class='stats'>" + site.state + "</td>"
+ "<td class='stats'><span style='color:" + site.styling.tag_foreground_color + ";background-color:"
+ site.styling.tag_background_color + ";'>[tags]</span></td>"
+ "<td class='stats'> <a href='" + site.logo_url + "' target='_blank'>logo</a></td>"
+ "<td class='stats'> <a href='" + site.api_endpoint + "/" + site.stats.api_version.version
+ "/help' target='_blank'>" + site.stats.api_version.version + " " + site.stats.api_version.revision + "</a></td>"
+ "<td class='stats'>" + Math.ceil(site.stats.views_per_day) + "</td>"
+ "<td class='stats'>" + site.stats.total_users + "</td>"
+ "<td class='stats'>" + site.stats.total_questions + "</td>"
+ "<td class='stats'>" + Math.ceil(site.stats.questions_per_minute) + "</td>"
+ "<td class='stats'>" + site.stats.total_accepted + "</td>"
+ "<td class='stats'>" + site.stats.total_unanswered + "</td>"
+ "<td class='stats'>" + site.stats.total_answers + "</td>"
+ "<td class='stats'>" + Math.ceil(site.stats.answers_per_minute) + "</td>"
+ "<td class='stats'>" + site.stats.total_comments + "</td>"
+ "<td class='stats'>" + site.stats.total_votes + "</td>"
+ "<td class='stats'>" + site.stats.total_badges + "</td>"
+ "<td class='stats'>" + Math.ceil(site.stats.badges_per_minute) + "</td>"
+ "</tr>";
};
output += "</table>";
document.getElementById("output").innerHTML = output;
}
};
}, function(error) {
alert(error.message);
});
Output: