/* appjet:version 0.1 */

import('storage');
import('lib-json');

function _trim(s) {
  return s?s.replace(/^\s+|\s+$/g,""):s;
}

function _extract(s, prefix, suffix) {
  var i = s.indexOf(prefix);
  if (i >= 0) { s = s.substring(i + prefix.length); }
  else { return ''; }
  if (suffix) {
    i = s.indexOf(suffix);
    if (i >= 0) { s = s.substring(0, i); }
    else { return ''; }
  }
  return s;
}

function _padLead0(s,n) {
  s = '000000000' + s;
  return s.substring(s.length - n);
}

function _calcpct(a, b, n) {
  var pct = Math.round(a / b * 100 * Math.pow(10, n)) / Math.pow(10, n);

  var pad = '';
  for (var i=0;i<n;i++) pad += '0';

  if (("" + pct).indexOf('.') < 0) return pct + '.' + pad; 
  else return (pct + pad).match("(\\d+\\.\\d{" + n + "})\\d*$")[1];
}

function _gchartdata(n, m) {
  var data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.";
  var v = m>0?Math.round(n / m * 4095):n;
  var v1 = parseInt(v / 64, 10);
  var v2 = v % 64;
  var r = '' + data[v1] + data[v2];
  return r;
}

function _gchartdata_s(n, m) {
  var data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  var v = m>0?Math.round(n / m * 61):n;

  return data[v];
}

function _mapcountry(s) {
  var map = new Array();
  map["People's Republic of China"] = "China";
  map["Republic of China (Taiwan)"] = "Taiwan";
  map["Republic of China"] = "Taiwan";
  map["Syria"] = "Syrian Arab Republic";
  map["Brunei"] = "Brunei Darussalam";
  map["Faroe Islands"] = "Faeroe Islands";
  map["Dem. Rep. of Congo"] = "The Democratic Republic Of The Congo";
  map["Republic of the Congo"] = "Republic Of Congo";
  map["Laos"] = "Lao People's Democratic Republic";
  map["East Timor"] = "Timor-leste";
  map["British Virgin Islands"] = "Virgin Islands, British";
  map["Macedonia"] = "Republic of Macedonia";
  map["Réunion"] = "Reunion";
  map["São Tomé and Príncipe"] = "Sao Tome And Principe";
  map["Gambia"] = "Gambia, The";

  var mapped = map[s];
  return mapped || s;
}

function _getPopFromWiki() {
  var popt = wget('http://en.wikipedia.org/wiki/List_of_countries_by_population');
  popt = _extract(popt, 'UN estimate</a></td>', '</table>');
  popt = _extract(popt, '</tr>');
  var pop = new Array();
  while (true) {
    var tr = _extract(popt, '<tr>', '</tr>');
    if (!tr) break;

    var flag = tr.match(/<img alt="[^"]*" src="([^"]*)"/);
    flag = flag?flag[1]:'';

    tr = _extract(tr, '&#160;');

    var wikilink = _extract(tr, '<a href="', '"');

    var country = tr.match(/title="[^"]*">([^<]*)</);
    country = country?country[1]:'';
  
    tr = _extract(tr, 'title="');
    var popnum = tr.match(/<td>([\d,]*)</);
    popnum = popnum?popnum[1]:'0';
    pop.push({country:_mapcountry(country).toLowerCase(), fmtpop:popnum, pop:parseInt(popnum.replace(/,/g,''), 10), flag:flag, wikilink:wikilink });
  
    popt = _extract(popt, '</tr>');
  }
  pop.push({country:"Aland Islands".toLowerCase(), fmtpop:"27,153", pop:27153, flag:'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Flag_of_Aaland.svg/22px-Flag_of_Aaland.svg.png', wikilink:'/wiki/Åland'});
  pop.push({country:"Svalbard And Jan Mayen".toLowerCase(), fmtpop:"2,321", pop:2321, wikilink:'/wiki/Svalbard_and_Jan_Mayen'});
  pop.push({country:"South Georgia And The South Sandwich Islands".toLowerCase(), fmtpop:'', flag:'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Flag_of_South_Georgia_and_the_South_Sandwich_Islands.svg/22px-Flag_of_South_Georgia_and_the_South_Sandwich_Islands.svg.png', wikilink:'/wiki/South_Georgia_and_the_South_Sandwich_Islands'});
  
  //storage.wikipop = pop;

  return pop;
}

function _findpop(pop, region) {
  region = region.toLowerCase();

  for (var i=0;i<pop.length;i++) {
    if (pop[i].country == region) return pop[i];
  }
  return null;
}

function getPledgeFromSpreadFirefox(pop) {
  var fullt = wget('http://www.spreadfirefox.com/en-US/worldrecord/');
  var t = fullt;
  var totalPledge = t.match(/<dd id="pledge_count">\s*([\d|,]*)/m)[1];
  t = _extract(t, '<caption>Number of pledges per region</caption>', '</table>');
  t = _extract(t, '</tr>');
  var res = t.match(/<tr>\s*<td>[^<]*<\/td>\s*<td>[^<]*<\/td>/gm);
  var data = new Array();
  for (var i=0;res&&i<res.length;i++) {
    var res2 = res[i].match(/<tr>\s*<td>([^<]*)<\/td>\s*<td>([^<]*)<\/td>/m);
    var region = _trim(res2[1]);
    var fmtcount = _trim(res2[2]);
    var count = parseInt(fmtcount.replace(/,/g,''), 10);
    popobj = _findpop(pop, region);
    countrycode = fullt.match('<option value="([A-Z]{2})">' + region + '</option>');
    countrycode = countrycode?countrycode[1]:'';
    data.push({region:region,
               countrycode:countrycode,
               fmtcount:fmtcount,
               count:count,
               pop:popobj?popobj.pop:0,
               fmtpop:popobj?popobj.fmtpop:'',
               poppct:(popobj?_calcpct(count, popobj.pop, 6):0), flag:popobj?popobj.flag:'',wikilink:popobj?popobj.wikilink:''});
  }
  
  // sort by pledge
  data.sort(function(a, b) {return a.count==b.count?(a.region<b.region?-1:1):b.count-a.count;});
  // set pledge_rank
  for (var i=0;i<data.length;i++) {
    data[i].pledge_rank = i+1;
  }
  
  // sort by poppct
  data.sort(function(a, b) {
    if (a.pop && !b.pop) return -1;
    if (!a.pop && b.pop) return 1;
    var result = 0;
    if (a.pop && b.pop) result = b.poppct - a.poppct;
    if (result == 0) result = a.pledge_rank - b.pledge_rank;
    return result;
  });
  var maxPopPct = data[0].poppct;

  // set poppct_rank
  for (var i=0;i<data.length;i++) {
    data[i].poppct_rank = i+1;
  }
  // set poppct_rank_1m
  var poppct_rank_1m_currank = 1;
  for (var i=0;i<data.length;i++) {
    if (data[i].pop >= 1000000) data[i].poppct_rank_1m = poppct_rank_1m_currank++;
  }
  for (var i=0;i<data.length;i++) {
    if (data[i].pop < 1000000) data[i].poppct_rank_1m = poppct_rank_1m_currank++;
  }
  // set poppct_rank_1m
  var poppct_rank_10m_currank = 1;
  for (var i=0;i<data.length;i++) {
    if (data[i].pop >= 10000000) data[i].poppct_rank_10m = poppct_rank_10m_currank++;
  }
  for (var i=0;i<data.length;i++) {
    if (data[i].pop < 10000000) data[i].poppct_rank_10m = poppct_rank_10m_currank++;
  }
  
  data.sort(function(a, b) {return a.pledge_rank-b.pledge_rank;});

  return {totalPledge:totalPledge, data:data, maxPopPct:maxPopPct};
}

function printHTML(data, totalPledge, pop, maxPopPct) {
  var pietop = parseInt(request.params.p, 10) || 10;
  var bartop = parseInt(request.params.b, 10) || 30;
  
  var total = 0;
  var pie_otherstotal = 0;
  var bar_otherstotal = 0;
  for (var i=0;i<data.length;i++) {
    total += data[i].count;
    if (i>=pietop) pie_otherstotal += data[i].count;
    if (i>=bartop) bar_otherstotal += data[i].count;
  }
  
  // pie chart
  var pie_chd = '';
  var pie_chl = '';
  for (var i=0;i<Math.min(data.length, pietop);i++) {
    var pct = _calcpct(data[i].count, total, 1);
    pie_chd += _gchartdata(pct, 100);
    pie_chl += (i>0?'|':'') + encodeURIComponent(data[i].region) + ' ' + pct + '%25';
  }
  var pie_otherspct = _calcpct(pie_otherstotal, total, 1);
  var pie_url = 'http://chart.apis.google.com/chart?cht=p3&chd=e:' + pie_chd + _gchartdata(pie_otherspct,100) + '&chl=' + pie_chl + '|Others ' + pie_otherspct + '%25&chs=500x200&chco=ff9900&chtt=Top ' + pietop + ' Regions';
  
  // bar chart
  var bar_chd = '';
  var bar_chl = '';
  var bar_max = Math.max(data[0].count, bar_otherstotal) * 1.1;
  for (var i=0;i<Math.min(data.length, bartop);i++) {
    bar_chd += _gchartdata(data[i].count, bar_max);
    bar_chl = encodeURIComponent(data[i].region) + ' (' + data[i].fmtcount + ')' + (i>0?'|':'') + bar_chl;
  }
  var bar_url = 'http://chart.apis.google.com/chart?cht=bhs&chd=e:' + bar_chd + _gchartdata(bar_otherstotal, bar_max) + '&chxt=y&chxl=0:|Others|' + bar_chl + '&chs=400x400&chco=ff9900&chbh=' + Math.round(370/bartop-4) + '&chtt=Top ' + bartop + ' Regions';
  
  // map chart
  var map_chld = '';
  var map_chd = '';
  var chd_map = [0.01, 0.1, 0.5, 1, 2, 10];
  for (var i=0;i<data.length;i++) {
    var poppct = parseFloat(data[i].poppct) || 0;
    var j=0;
    while(j<chd_map.length && poppct >= chd_map[j]) j++;
    if (j > 0) {
      map_chld += data[i].countrycode;
      map_chd += _gchartdata_s(j, chd_map.length);
      //map_chd += _gchartdata_s(poppct, maxPopPct);
    }
  }  
  var map_url = 'http://chart.apis.google.com/chart?cht=t&chs=440x220&chco=ffffff,ffffff,ff3300&chf=bg,s,eaf7fe&chtm=world&chd=s:' + map_chd + '&chld=' + map_chld;
  page.setMode('plain');
  print(raw("""
<html>
<head>
<title>Firefox Download Day 2008 Stats</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
<script src="http://tablesorter.com/jquery.tablesorter.js"></script>
<link rel="stylesheet" href="http://tablesorter.com/themes/blue/style.css" type="text/css" media="print, projection, screen" />
<style>
body, td { font-family:Tahoma,Verdana; font-size:10pt; }
body { background:url(http://www.spreadfirefox.com/files/images/affiliates_banners/dday_badge_fox.png) no-repeat; background-position: -30 10; }
table.tablesorter thead tr .header { padding-right:21px; }
table.tablesorter tbody td { vertical-align:middle; }
#fulllist { width:930px; }
#title { font-size:18pt; font-weight:bold; margin-left:190px; }
#author { font-size:10pt; margin:10px 0px 0px 190px; }
#totalpledge { font-size:16pt; font-weight:bold; margin:60px 0px 0px 190px; }
#piechart { margin-top: 70px; margin-bottom:0px; vertical-align: top; }
#barchart { position: absolute; top: 80px; left: 530px; }
#mapchartdiv { margin: 10px 0px 10px 50px;}
#mapcharttitle { font-size:12pt; }
#mapchart { float:left; margin: 10px 0px 10px 0px; }
#mapchartmenu { margin-top:50px; margin-left:450px; font-soze:12pt; line-height:1.5em; }
#mapchartmenu a { color:blue; text-decoration:none; }
#mapchartmenu a:visited { color:blue; }
#mapchartmenu a:hover { color:orange; text-decoration:underline; }
#remarks { font-size:10pt; margin-top:10px; }
#toprightad { float:right; }
</style>
<script language="Javascript1.3">
$(document).ready(function() { 
  $("#fulllist").tablesorter({
    textExtraction: function(node) {
      if (node.innerHTML.match(/^[\d,]+%?$/))
        return node.innerHTML.replace(/[,|%]/g, '');
      else
        return node.innerHTML;
    }
  }); 
});
function change_map(region) {
  var img = document.getElementById('mapchart');
  img.src = img.src.replace(/&chtm=[a-z_]*&/, '&chtm=' + region + '&');
}
</script>
</head>
<body>
<div>
<div id='toprightad'>
<script type="text/javascript"><!--
google_ad_client = "pub-1084893836817541";
/* 234x60, created 6/12/08 */
google_ad_slot = "5896424608";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<script type="text/javascript"><!--
google_ad_client = "pub-1084893836817541";
google_ad_width = 180;
google_ad_height = 60;
google_ad_format = "180x60_as_rimg";
google_cpa_choice = "CAAQsbOgnAIaCM1E33mDHXcnKI3ml3Q";
google_ad_channel = "3754998402";
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</div>
<div id='title'><a href="http://www.spreadfirefox.com/en-US/worldrecord/">Firefox Download Day 2008</a></div>
<div id='author'>This page is designed by <a href="http://angusdev.mysinablog.com/" title="Angus's blog">angus</a><br/>Leave comments on my Blog (<a href='http://ellaborg.blogspot.com/2008/06/some-stats-from-firefox-3-download-day.html'>English</a> | <a href='http://angusdev.mysinablog.com/index.php?op=ViewArticle&articleId=1203708'>Chinese</a>)</div>
</div>
<div id='totalpledge'>""" + totalPledge + """ Downloads</div>
<img id='piechart' src='""" + pie_url + """' width='500' height='200' alt='Top """ + pietop + """ regions' />
<img id='barchart' src='""" + bar_url + """' width='400' height='400' alt='Top """ + bartop + """ regions' />
<div id='mapchartdiv'>
<div id='mapcharttitle'>Download / Population (darker = higher)</div>
<img id='mapchart' src='""" + map_url + """' width='440' height='220'/>
<div id='mapchartmenu'>
<a href='javascript:void(0)' onclick='change_map("world")'>World</a><br/>
<a href='javascript:void(0)' onclick='change_map("africa")'>Africa</a><br/>
<a href='javascript:void(0)' onclick='change_map("asia")'>Asia</a><br/>
<a href='javascript:void(0)' onclick='change_map("europe")'>Europe</a><br/>
<a href='javascript:void(0)' onclick='change_map("middle_east")'>Middle East</a><br/>
<a href='javascript:void(0)' onclick='change_map("south_america")'>South America</a><br/>
</div>
</div>
<h3 style='clear:left;'>Full list</h3>
<table id="fulllist" class='tablesorter' border='0' cellspacing='1'>
<thead><tr><th>Rank by<br/>Downloads</th><th>Region</th><th>Downloads</th><th>Pct</th><th>Population</th><th>Downloads/Pop</th><th>Rank by <br/>Downloads/Pop</th><th>Rank by <br/>Downloads/Pop<br/>(Pop &gt;= 1M)</th><th>Rank by <br/>Downloads/Pop<br/>(Pop &gt;= 10M)</th></tr></thead>
<tbody>
"""));
for (var i=0;i<data.length;i++) {
  var item = data[i];
  var region = item.region;
  if (item.wikilink) {
    region = '<a href="http://en.wikipedia.org' + item.wikilink + '" title="Wikipedia entry of ' + region + '">' + region + '</a>';
  }
  print(raw("<tr><td align='center'>" + (i + 1) + "</td><td style='background-image:url(" + item.flag + "); background-repeat: no-repeat; background-position: 3px; padding-left:28px;'>" + region + "</td><td align='right'>" + item.fmtcount + "</td><td align='right'>" + _calcpct(item.count, total, 2) + "%</td><td align='right'>" + item.fmtpop + "</td><td align='right'>" + (item.pop?(item.poppct+"%"):"") + "</td><td align='center'><!--" + _padLead0(item.poppct_rank, 3) + "-->" + (item.pop?item.poppct_rank:'') + "</td><td align='center'><!--" + _padLead0(item.poppct_rank_1m, 3) + "-->" + (item.pop>1000000?item.poppct_rank_1m:'') + "</td><td align='center'><!--" + _padLead0(item.poppct_rank_10m, 3) + "-->" + (item.pop>=10000000?data[i].poppct_rank_10m:'') + "</td></tr>"));
}
//print(raw("<tr><td></td><td align='right'>Total:</td><td align='right'>" + totalPledge + "</td><td align='right'>100.00%</td><td colspan='5'></td></tr>"));
print(raw("""
<tbody>
</table>
<div id='remarks'>
<b>Remarks:</b>
<ol>
<li>Source of pledges count: <a href='http://www.spreadfirefox.com/en-US/worldrecord/' title='Spread Firefox | Download Day 2008:'>SpreadFirefox.com</a>
<li>
Source of populations: Wikipedia &quot;<a href='http://en.wikipedia.org/wiki/List_of_countries_by_population' title='List of countries by population'>List of countries by population</a>&quot;, &quot;<a href='http://en.wikipedia.org/wiki/Åland' title='Wikipedia's entry of Åland Islands'>Åland Islands</a>&quot;, &quot;<a href='http://en.wikipedia.org/wiki/Svalbard_and_Jan_Mayen' title='Wikipedia's entry of Svalbard and Jan Mayen'>Svalbard and Jan Mayen</a>&quot;.
<!--
<li>
The population of South Georgia And The South Sandwich Islands is not listed because, according to <a href='http://en.wikipedia.org/wiki/South_Georgia_and_the_South_Sandwich_Islands' title="Wikipedia's entry of South Georgia And The South Sandwich Islands">Wikipedia</a>, the population was 20 estimated in 2006, which belows the pledges count.  
-->
</div>
</body>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-3184137-4");
pageTracker._initData();
pageTracker._trackPageview();
</script>
</html>"""));
}

// Get Populations
function makePop() {
  var pop = null;
  if (storage.wikipop) {
    pop = JSON.parse(storage.wikipop);
  }
  else {
    pop = _getPopFromWiki();
    storage.wikipop = JSON.stringify(pop);
  }

  return pop;
}

var pop = makePop();
//storage.wikipop_backup_20080617 = storage.wikipop;
var data = null;
try {
  data = getPledgeFromSpreadFirefox(pop);
  if (!data || data.totalPledge == 0 || !data.data || data.data.length == 0) {
    data = null;
  }
  else {
    storage.downloaddata = JSON.stringify(data);
  }
}
catch (ex) {
}
if (!data) {
  data = JSON.parse(storage.downloaddata);
}
//storage.downloaddata_backup_20080617 = storage.downloaddata;
//storage.downloaddata_backup_20080618 = storage.downloaddata;
//storage.downloaddata_backup_20080619 = storage.downloaddata;

//storage.pledgedata = JSON.stringify(data);
//var data = JSON.parse(storage.pledgedata);
//storage.pledgedata_backup_20080617b = storage.pledgedata_backup_20080617;
//storage.pledgedata_backup_20080617 = storage.pledgedata;

printHTML(data.data, data.totalPledge, pop, data.maxPopPct);

© Copyright 2007-2008 AppJet Inc.