From b7e75a72e3bdf86ce16e565f3da64100f2018529 Mon Sep 17 00:00:00 2001 From: Adriaan Groenenboom Date: Sat, 25 Mar 2017 19:55:47 +0100 Subject: [PATCH 01/11] Add Github release date integration - Badge shows readable format of release date of latest version - Color fades with age of release --- package.json | 2 ++ server.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/package.json b/package.json index 73d71cb4563d3..66e2094bf673e 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,11 @@ "bower": "~1.7.9", "camp": "~16.2.3", "chrome-web-store-item-property": "~1.1.2", + "color": "^1.0.3", "dot": "~1.0.3", "gm": "^1.23.0", "json-autosave": "~1.1.2", + "moment": "^2.18.1", "pdfkit": "~0.8.0", "redis": "~2.6.2", "request": "~2.75.0", diff --git a/server.js b/server.js index a51801018a7f7..e523eebb0c37d 100644 --- a/server.js +++ b/server.js @@ -23,6 +23,9 @@ var loadLogos = require('./load-logos.js'); var githubAuth = require('./lib/github-auth.js'); var querystring = require('querystring'); var xml2js = require('xml2js'); +var moment = require('moment'); +moment().format(); +var Color = require('color'); var serverSecrets; try { // Everything that cannot be checked in but is useful server-side @@ -3092,6 +3095,55 @@ cache(function(data, match, sendBadge, request) { }); })); +// GitHub release date integration. +camp.route(/^\/github\/release-date\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, +cache(function(data, match, sendBadge, request) { + var user = match[1]; // eg, qubyte/rubidium + var repo = match[2]; + var format = match[3]; + var apiUrl = githubApiUrl + '/repos/' + user + '/' + repo + '/releases/latest'; + var badgeData = getBadgeData('release date', data); + if (badgeData.template === 'social') { + badgeData.logo = badgeData.logo || logos.github; + } + githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { + if (err != null) { + badgeData.text[1] = 'inaccessible'; + sendBadge(format, badgeData); + return; + } + try { + var data = JSON.parse(buffer); + + if (typeof data.created_at !== 'string') throw 'Project has no releases'; + + // Pretty print release date + var releaseDate = moment(data.created_at); + var dateString = releaseDate.calendar(null, { + lastDay : '[Yesterday]', + sameDay : '[Today]', + lastWeek : '[last] dddd', + sameElse: 'D MMM YYYY' + }); + // Trim current year from date string + var currentYear = moment().year(); + badgeData.text[1] = dateString.replace(' ' + currentYear, ''); + + // Calculate color (older release is lighter/greyer color) + const colorB = '#007ec6'; // blue + const baseColor = Color(colorB); + const weeksSinceRelease = moment().diff(releaseDate, 'weeks'); + const factor = Math.max(Math.min(weeksSinceRelease / 25, 0.9), 0.1); + badgeData.colorB = baseColor.lighten(factor).desaturate(factor / 2).hex(); + + sendBadge(format, badgeData); + } catch(e) { + badgeData.text[1] = 'none'; + sendBadge(format, badgeData); + } + }); +})); + // GitHub commits since integration. camp.route(/^\/github\/commits-since\/([^\/]+)\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, cache(function(data, match, sendBadge, request) { From 5e2fa13c4615e19192958d28e931ae1b23ee1c8c Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 00:50:28 +0530 Subject: [PATCH 02/11] fixed breaking logo on last commit --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 4204651c8763e..34a38bc82cb0e 100644 --- a/server.js +++ b/server.js @@ -3334,7 +3334,7 @@ cache(function(data, match, sendBadge, request) { var apiUrl = githubApiUrl + '/repos/' + user + '/' + repo + '/releases/latest'; var badgeData = getBadgeData('release date', data); if (badgeData.template === 'social') { - badgeData.logo = badgeData.logo || logos.github; + badgeData.logo = getLogo('github', data); } githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { if (err != null) { From 2d54ae428bcd5e3cb0b4a201ef4aa64db8636550 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 02:04:07 +0530 Subject: [PATCH 03/11] code separated & few simplification --- lib/github-provider.js | 55 ++++++++++++++++++++++++++++++++++++++++-- server.js | 53 +++------------------------------------- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/lib/github-provider.js b/lib/github-provider.js index b1a190621dfa7..7229a9bf2413f 100644 --- a/lib/github-provider.js +++ b/lib/github-provider.js @@ -1,10 +1,13 @@ 'use strict'; +const moment = require('moment'); +const Color = require('color'); const { handleRequest: cache } = require('./request-handler'); const { + makeColorB, makeBadgeData: getBadgeData, makeLabel: getLabel, - getLogo + makeLogo: getLogo } = require('./badge-data'); // GitHub commits since integration. @@ -68,9 +71,57 @@ function mapGithubCommitsSince(camp, githubApiUrl, githubAuth) { })); } +function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { + camp.route(/^\/github\/release-date\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, + cache(function(data, match, sendBadge, request) { + const user = match[1]; // eg, microsoft + const repo = match[2]; // eg, vscode + const format = match[3]; + const apiUrl = `${githubApiUrl}/repos/${user}/${repo}/releases/latest`; + const badgeData = getBadgeData('release date', data); + if (badgeData.template === 'social') { + badgeData.logo = getLogo('github', data); + } + githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { + if (err != null) { + badgeData.text[1] = 'inaccessible'; + sendBadge(format, badgeData); + return; + } + try { + const data = JSON.parse(buffer); + + if (!data.created_at) throw 'Project has no releases'; + + const releaseDate = moment(data.created_at); + + // Pretty print release date + badgeData.text[1] = releaseDate.calendar(null, { + lastDay : '[Yesterday]', + sameDay : '[Today]', + lastWeek : '[last] dddd', + sameElse : now => releaseDate.year() == now.year() ? 'D MMM' : 'D MMM YYYY' + }); + + // Calculate color (older release is lighter/greyer color) + const colorB = makeColorB('#007ec6', data ); // blue + const baseColor = Color(colorB); + const weeksSinceRelease = moment().diff(releaseDate, 'weeks'); + const factor = Math.max(Math.min(weeksSinceRelease / 25, 0.9), 0.1); + badgeData.colorB = baseColor.lighten(factor).desaturate(factor / 2).hex(); + sendBadge(format, badgeData); + } catch(e) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + } + }); + })); +} + module.exports = { - mapGithubCommitsSince + mapGithubCommitsSince, + mapGithubReleaseDate }; diff --git a/server.js b/server.js index 34a38bc82cb0e..88aa9f1182c6c 100644 --- a/server.js +++ b/server.js @@ -27,8 +27,6 @@ var githubAuth = require('./lib/github-auth'); var querystring = require('querystring'); var prettyBytes = require('pretty-bytes'); var xml2js = require('xml2js'); -var moment = require('moment'); -var Color = require('color'); var serverSecrets = require('./lib/server-secrets'); if (serverSecrets && serverSecrets.gh_client_id) { githubAuth.setRoutes(camp); @@ -117,7 +115,8 @@ const { } = require('./lib/github-helpers'); const { - mapGithubCommitsSince + mapGithubCommitsSince, + mapGithubReleaseDate } = require("./lib/github-provider"); var semver = require('semver'); @@ -3326,53 +3325,7 @@ cache(function(data, match, sendBadge, request) { })); // GitHub release date integration. -camp.route(/^\/github\/release-date\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, -cache(function(data, match, sendBadge, request) { - var user = match[1]; // eg, qubyte/rubidium - var repo = match[2]; - var format = match[3]; - var apiUrl = githubApiUrl + '/repos/' + user + '/' + repo + '/releases/latest'; - var badgeData = getBadgeData('release date', data); - if (badgeData.template === 'social') { - badgeData.logo = getLogo('github', data); - } - githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; - sendBadge(format, badgeData); - return; - } - try { - var data = JSON.parse(buffer); - - if (typeof data.created_at !== 'string') throw 'Project has no releases'; - - // Pretty print release date - var releaseDate = moment(data.created_at); - var dateString = releaseDate.calendar(null, { - lastDay : '[Yesterday]', - sameDay : '[Today]', - lastWeek : '[last] dddd', - sameElse: 'D MMM YYYY' - }); - // Trim current year from date string - var currentYear = moment().year(); - badgeData.text[1] = dateString.replace(' ' + currentYear, ''); - - // Calculate color (older release is lighter/greyer color) - const colorB = '#007ec6'; // blue - const baseColor = Color(colorB); - const weeksSinceRelease = moment().diff(releaseDate, 'weeks'); - const factor = Math.max(Math.min(weeksSinceRelease / 25, 0.9), 0.1); - badgeData.colorB = baseColor.lighten(factor).desaturate(factor / 2).hex(); - - sendBadge(format, badgeData); - } catch(e) { - badgeData.text[1] = 'none'; - sendBadge(format, badgeData); - } - }); -})); +mapGithubReleaseDate(camp, githubApiUrl, githubAuth) // GitHub commits since integration. mapGithubCommitsSince(camp, githubApiUrl ,githubAuth); From c09aa83a8454c5b295a1adc7284973d1fa374a57 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 12:12:20 +0530 Subject: [PATCH 04/11] code cleaned --- lib/github-provider.js | 82 +++++++++++++++++++----------------------- server.js | 2 +- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/lib/github-provider.js b/lib/github-provider.js index 7229a9bf2413f..b7ac8dbbab1cf 100644 --- a/lib/github-provider.js +++ b/lib/github-provider.js @@ -1,14 +1,19 @@ 'use strict'; const moment = require('moment'); -const Color = require('color'); const { handleRequest: cache } = require('./request-handler'); const { - makeColorB, makeBadgeData: getBadgeData, makeLabel: getLabel, - makeLogo: getLogo + makeLogo: getLogo, } = require('./badge-data'); +const { + formatDate +} = require('./text-formatters'); + +const { + age +} = require('./color-formatters'); // GitHub commits since integration. function mapGithubCommitsSince(camp, githubApiUrl, githubAuth) { @@ -73,52 +78,37 @@ function mapGithubCommitsSince(camp, githubApiUrl, githubAuth) { function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { camp.route(/^\/github\/release-date\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, - cache(function(data, match, sendBadge, request) { - const user = match[1]; // eg, microsoft - const repo = match[2]; // eg, vscode - const format = match[3]; - const apiUrl = `${githubApiUrl}/repos/${user}/${repo}/releases/latest`; - const badgeData = getBadgeData('release date', data); - if (badgeData.template === 'social') { - badgeData.logo = getLogo('github', data); - } - githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; - sendBadge(format, badgeData); - return; - } - try { - const data = JSON.parse(buffer); - - if (!data.created_at) throw 'Project has no releases'; - - const releaseDate = moment(data.created_at); - - // Pretty print release date - badgeData.text[1] = releaseDate.calendar(null, { - lastDay : '[Yesterday]', - sameDay : '[Today]', - lastWeek : '[last] dddd', - sameElse : now => releaseDate.year() == now.year() ? 'D MMM' : 'D MMM YYYY' - }); - - // Calculate color (older release is lighter/greyer color) - const colorB = makeColorB('#007ec6', data ); // blue - const baseColor = Color(colorB); - const weeksSinceRelease = moment().diff(releaseDate, 'weeks'); - const factor = Math.max(Math.min(weeksSinceRelease / 25, 0.9), 0.1); - badgeData.colorB = baseColor.lighten(factor).desaturate(factor / 2).hex(); - sendBadge(format, badgeData); - } catch(e) { - badgeData.text[1] = 'invalid'; - sendBadge(format, badgeData); + cache(function (data, match, sendBadge, request) { + const user = match[1]; // eg, microsoft + const repo = match[2]; // eg, vscode + const format = match[3]; + const apiUrl = `${githubApiUrl}/repos/${user}/${repo}/releases/latest`; + const badgeData = getBadgeData('release date', data); + if (badgeData.template === 'social') { + badgeData.logo = getLogo('github', data); } - }); - })); -} + githubAuth.request(request, apiUrl, {}, function (err, res, buffer) { + if (err != null) { + badgeData.text[1] = 'inaccessible'; + sendBadge(format, badgeData); + return; + } + try { + const data = JSON.parse(buffer); + if (!data.created_at) throw 'Project has no releases'; + const releaseDate = moment(data.created_at); + badgeData.text[1] = formatDate(releaseDate); + badgeData.colorscheme = age(releaseDate); + sendBadge(format, badgeData); + } catch (e) { + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + } + }); + })); +} module.exports = { diff --git a/server.js b/server.js index 88aa9f1182c6c..e76863f58f4ad 100644 --- a/server.js +++ b/server.js @@ -3325,7 +3325,7 @@ cache(function(data, match, sendBadge, request) { })); // GitHub release date integration. -mapGithubReleaseDate(camp, githubApiUrl, githubAuth) +mapGithubReleaseDate(camp, githubApiUrl, githubAuth); // GitHub commits since integration. mapGithubCommitsSince(camp, githubApiUrl ,githubAuth); From 52cbb8a3388a12b16efee2d3ab6e3e73ee5f8e2b Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 12:43:48 +0530 Subject: [PATCH 05/11] test added --- service-tests/github.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/service-tests/github.js b/service-tests/github.js index 1005985b64e49..ace07da3a4061 100644 --- a/service-tests/github.js +++ b/service-tests/github.js @@ -165,6 +165,20 @@ t.create('(pre-)Release') value: Joi.string() })); +t.create('Release Date. e.g release date|today') +.get('/release-date/microsoft/vscode.json') +.expectJSONTypes(Joi.object().keys({ + name: Joi.equal('release date'), + value: validDateString +})); + +t.create('Release Date - Custom Label. e.g myRelease|today') +.get('/release-date/microsoft/vscode.json?label=myRelease') +.expectJSONTypes(Joi.object().keys({ + name: Joi.equal('myRelease'), + value: validDateString +})); + t.create('Tag') .get('/tag/photonstorm/phaser.json') .expectJSONTypes(Joi.object().keys({ From 1914656fc678defbac2b822bee18b7215ac206fb Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 19:27:49 +0530 Subject: [PATCH 06/11] throw statement removed & one extra test added --- lib/github-provider.js | 12 +++++++++--- service-tests/github.js | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/github-provider.js b/lib/github-provider.js index b7ac8dbbab1cf..54389cc7dd8d1 100644 --- a/lib/github-provider.js +++ b/lib/github-provider.js @@ -76,6 +76,7 @@ function mapGithubCommitsSince(camp, githubApiUrl, githubAuth) { })); } +//Github Release Date Integration function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { camp.route(/^\/github\/release-date\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, cache(function (data, match, sendBadge, request) { @@ -93,11 +94,16 @@ function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { sendBadge(format, badgeData); return; } - try { - const data = JSON.parse(buffer); - if (!data.created_at) throw 'Project has no releases'; + //github return 404 if repo not found or no release + if(res.statusCode === 404) { + badgeData.text[1] = 'not found'; + sendBadge(format, badgeData); + return; + } + try { + const data = JSON.parse(buffer); const releaseDate = moment(data.created_at); badgeData.text[1] = formatDate(releaseDate); badgeData.colorscheme = age(releaseDate); diff --git a/service-tests/github.js b/service-tests/github.js index ace07da3a4061..9e1da236748ea 100644 --- a/service-tests/github.js +++ b/service-tests/github.js @@ -179,6 +179,14 @@ t.create('Release Date - Custom Label. e.g myRelease|today') value: validDateString })); +t.create('Release Date - Should return not found for invalid repo') +.get('/release-date/not-valid-name/not-valid-repo.json') +.expectJSONTypes(Joi.object().keys({ + name: Joi.equal('release date'), + value: "not found" +})); + + t.create('Tag') .get('/tag/photonstorm/phaser.json') .expectJSONTypes(Joi.object().keys({ From 92f12b4d29ee9d29257ae3cf66080af9deca9d49 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 19:32:11 +0530 Subject: [PATCH 07/11] lint --- service-tests/github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service-tests/github.js b/service-tests/github.js index 9e1da236748ea..c04f4fd1d8b19 100644 --- a/service-tests/github.js +++ b/service-tests/github.js @@ -183,7 +183,7 @@ t.create('Release Date - Should return not found for invalid repo') .get('/release-date/not-valid-name/not-valid-repo.json') .expectJSONTypes(Joi.object().keys({ name: Joi.equal('release date'), - value: "not found" + value: 'not found' })); From 0968b0d4f128a47b2cd7a32dfc2177db183634a8 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Tue, 3 Oct 2017 19:46:13 +0530 Subject: [PATCH 08/11] rename --- lib/github-provider.js | 2 +- service-tests/github.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/github-provider.js b/lib/github-provider.js index 54389cc7dd8d1..678a1becb8ce8 100644 --- a/lib/github-provider.js +++ b/lib/github-provider.js @@ -97,7 +97,7 @@ function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { //github return 404 if repo not found or no release if(res.statusCode === 404) { - badgeData.text[1] = 'not found'; + badgeData.text[1] = 'no releases or repo not found'; sendBadge(format, badgeData); return; } diff --git a/service-tests/github.js b/service-tests/github.js index c04f4fd1d8b19..ad46485e48016 100644 --- a/service-tests/github.js +++ b/service-tests/github.js @@ -179,11 +179,11 @@ t.create('Release Date - Custom Label. e.g myRelease|today') value: validDateString })); -t.create('Release Date - Should return not found for invalid repo') +t.create('Release Date - Should return `no releases or repo not found` for invalid repo') .get('/release-date/not-valid-name/not-valid-repo.json') .expectJSONTypes(Joi.object().keys({ name: Joi.equal('release date'), - value: 'not found' + value: 'no releases or repo not found' })); From 618c6758831894962cee6b1de27f22aede2dc4b9 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Wed, 4 Oct 2017 10:06:56 +0530 Subject: [PATCH 09/11] unnecessary package removed --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 79b37aabd9312..2a17e1b554d1d 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "dependencies": { "camp": "~16.2.3", "chrome-web-store-item-property": "~1.1.2", - "color": "^1.0.3", "dot": "~1.0.3", "gm": "^1.23.0", "json-autosave": "~1.1.2", From 31e58c0995c07f0485bb771eb89cd78802869d97 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Wed, 4 Oct 2017 10:14:00 +0530 Subject: [PATCH 10/11] test simplified --- service-tests/github.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/service-tests/github.js b/service-tests/github.js index ad46485e48016..95100e445eaa4 100644 --- a/service-tests/github.js +++ b/service-tests/github.js @@ -168,23 +168,20 @@ t.create('(pre-)Release') t.create('Release Date. e.g release date|today') .get('/release-date/microsoft/vscode.json') .expectJSONTypes(Joi.object().keys({ - name: Joi.equal('release date'), + name: 'release date', value: validDateString })); t.create('Release Date - Custom Label. e.g myRelease|today') .get('/release-date/microsoft/vscode.json?label=myRelease') .expectJSONTypes(Joi.object().keys({ - name: Joi.equal('myRelease'), + name: 'myRelease', value: validDateString })); t.create('Release Date - Should return `no releases or repo not found` for invalid repo') .get('/release-date/not-valid-name/not-valid-repo.json') -.expectJSONTypes(Joi.object().keys({ - name: Joi.equal('release date'), - value: 'no releases or repo not found' -})); +.expectJSON({ name: 'release date', value: 'no releases or repo not found' }); t.create('Tag') From d72723100427f4393fd8a9ec86b2b97221e4b9a1 Mon Sep 17 00:00:00 2001 From: Ritwick Dey Date: Wed, 4 Oct 2017 10:49:19 +0530 Subject: [PATCH 11/11] html added --- try.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/try.html b/try.html index 92b07a8c06cf3..df1b7db6206ef 100644 --- a/try.html +++ b/try.html @@ -912,6 +912,10 @@

Miscellaneous

https://img.shields.io/github/issues/detail/last-update/badges/shields/979.svg + GitHub Release Date: + + https://img.shields.io/github/release-date/SubtitleEdit/subtitleedit.svg + GitHub pull request check state: https://img.shields.io/github/status/s/pulls/badges/shields/1110.svg