From 4fe65e167563db4d1a44befea8e7455c9f9557d1 Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Tue, 23 Feb 2016 23:14:45 -0800 Subject: [PATCH] [PATCH v3] Add support for issuestats.com This commit adds support for issuestats.com, as requested in #351. The implementation is straight-forward, with the exception of the handling of 'not found' which currently returns text/html with code 200 (see hstove/issue_stats#38). The URL parsing is somewhat lax to allow future support for other hosting platforms which may not follow GitHub's user/repo URL scheme. It also passes through the `concise` query parameter, if present, which shortens the text a bit. Changes in v3: - Fix `concise` option assignment holdover missed in v2 changes. - Make `label` check null/undefined rather than falsey. Changes in v2: - Move type to first parameter and shorten to 1 character. - Change `concise` option from query param to optional path component - Make `color` check null/undefined rather than falsey. - Add try-catch around JSON value extraction and response, by request. Fixes: #351 Signed-off-by: Kevin Locke --- server.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ try.html | 8 +++++++ 2 files changed, 73 insertions(+) diff --git a/server.js b/server.js index 2b65b56..6be99ee 100644 --- a/server.js +++ b/server.js @@ -5122,6 +5122,71 @@ cache(function(data, match, sendBadge, request) { }); })); +// Issue Stats integration. +camp.route(/^\/issuestats\/([^\/]+)(\/concise)?\/([^\/]+)\/(.+)\.(svg|png|gif|jpg|json)$/, +cache(function(data, match, sendBadge, request) { + var type = match[1]; // e.g. `i` for Issue or `p` for PR + var options = match[2]; // `concise` + var host = match[3]; // e.g. `github` + var userRepo = match[4]; // e.g. `ruby/rails` + var format = match[5]; + + var badgeData = getBadgeData('Issue Stats', data); + + // Maps type name from URL to JSON property name prefix for badge data + var typeToPropPrefix = { + i: 'issue', + p: 'pr' + }; + var typePropPrefix = typeToPropPrefix[type]; + if (typePropPrefix === undefined) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + return; + } + + var url = 'http://issuestats.com/' + host + '/' + userRepo; + var qs = {format: 'json'}; + if (options === '/concise') { + qs.concise = true; + } + var options = { + method: 'GET', + url: url, + qs: qs, + gzip: true, + json: true + }; + request(options, function(err, res, json) { + if (err != null || res.statusCode >= 500) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + return; + } + + if (res.statusCode >= 400 || !json || typeof json !== 'object') { + badgeData.text[1] = 'not found'; + sendBadge(format, badgeData); + return; + } + + try { + var label = json[typePropPrefix + '_badge_preamble']; + var value = json[typePropPrefix + '_badge_words']; + var color = json[typePropPrefix + '_badge_color']; + + if (label != null) badgeData.text[0] = label; + badgeData.text[1] = value || 'invalid'; + if (color != null) badgeData.colorscheme = color; + + sendBadge(format, badgeData); + } catch (e) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + } + }); +})); + // Any badge. camp.route(/^\/(:|badge\/)(([^-]|--)*?)-(([^-]|--)*)-(([^-]|--)+)\.(svg|png|gif|jpg)$/, function(data, match, end, ask) { diff --git a/try.html b/try.html index a728acc..25bf048 100644 --- a/try.html +++ b/try.html @@ -845,6 +845,14 @@ Pixel-perfect   Retina-ready   Fast   Consistent   Hackable https://img.shields.io/stackexchange/stackoverflow/t/augeas.svg + Issue Stats: + + https://img.shields.io/issuestats/i/github/strongloop/express.svg + + Issue Stats: + + https://img.shields.io/issuestats/p/github/strongloop/express.svg +

Your Badge