diff --git a/server.js b/server.js index 87b935b..90ef3fa 100644 --- a/server.js +++ b/server.js @@ -1300,6 +1300,44 @@ cache(function(data, match, sendBadge, request) { }) })); + +// Gem ranking +camp.route(/^\/gem\/(rt|rd)\/(.*)\.(svg|png|gif|jpg|json)$/, +cache(function(data, match, sendBadge, request) { + var info = match[1]; // either rt or rd + var repo = match[2]; // eg, "rspec-puppet-facts" + var format = match[3]; + var url = 'http://bestgems.org/api/v1/gems/' + repo; + if (info === 'rt') { + url += '/total_ranking.json'; + } else if (info === 'rd') { + url += '/daily_ranking.json'; + } + var badgeData = getBadgeData('rank', data); + request(url, function(err, res, buffer) { + if (err != null) { + badgeData.text[1] = 'inaccessible'; + sendBadge(badgeData, format); + } + try { + var data = JSON.parse(buffer); + if (info == 'rt') { + var rank = data[0].total_ranking; + } else if (info === 'rd') { + var rank = data[0].daily_ranking; + } + var count = Math.floor(100000/rank); + badgeData.colorscheme = floorCountColor(count, 10, 50, 100); + badgeData.text[1] = ordinalNumber(rank); + badgeData.text[1] += (info === 'rt') ? ' total' : ' daily'; + sendBadge(format, badgeData); + } catch (e) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + } + }) +})); + // PyPI integration. camp.route(/^\/pypi\/([^\/]+)\/(.*)\.(svg|png|gif|jpg|json)$/, cache(function(data, match, sendBadge, request) { @@ -3662,6 +3700,11 @@ function fetchFromSvg(request, url, cb) { }); } +function ordinalNumber(n) { + var s=["ᵗʰ","ˢᵗ","ⁿᵈ","ʳᵈ"], v=n%100; + return n+(s[(v-20)%10]||s[v]||s[0]); +} + function coveragePercentageColor(percentage) { return floorCountColor(percentage, 80, 90, 100); } diff --git a/try.html b/try.html index 13c2df6..72af700 100644 --- a/try.html +++ b/try.html @@ -581,6 +581,14 @@ Pixel-perfect Retina-ready Fast Consistent Hackable
https://img.shields.io/gem/u/raphink.svg
https://img.shields.io/gem/rt/puppet.svg
https://img.shields.io/gem/rd/facter.svg
https://img.shields.io/dub/l/vibe-d.svg