Skip to content

Commit

Permalink
[gem cdnjs appveyor clojars] refactor clojars, establish BaseJsonServ…
Browse files Browse the repository at this point in the history
…ice (#1702)

* refactor clojars integration

* DRY up services that request data from JSON endpoints
  • Loading branch information
chris48s authored Jun 16, 2018
1 parent 20b8d0c commit f78e6f1
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 88 deletions.
4 changes: 0 additions & 4 deletions lib/all-badge-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,10 +893,6 @@ const allBadgeExamples = [
title: 'Maven metadata URI',
previewUri: '/maven-metadata/v/http/central.maven.org/maven2/com/google/code/gson/gson/maven-metadata.xml.svg'
},
{
title: 'Clojars',
previewUri: '/clojars/v/prismic.svg'
},
{
title: 'CocoaPods',
previewUri: '/cocoapods/v/AFNetworking.svg'
Expand Down
32 changes: 0 additions & 32 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2067,38 +2067,6 @@ cache(function(data, match, sendBadge, request) {
});
}));

// Clojars version integration
camp.route(/^\/clojars\/v\/(.+)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
const clojar = match[1]; // eg, `prismic` or `foo/bar`.
const format = match[2];
const apiUrl = 'https://clojars.org/' + clojar + '/latest-version.json';
const badgeData = getBadgeData('clojars', data);
request(apiUrl, function(err, res, buffer) {
if (err !== null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
return;
}
try {
const json = JSON.parse(buffer);
if (Object.keys(json).length === 0) {
/* Note the 'not found' response from clojars is:
status code = 200, body = {} */
badgeData.text[1] = 'not found';
sendBadge(format, badgeData);
return;
}
badgeData.text[1] = "[" + clojar + " \"" + json.version + "\"]";
badgeData.colorscheme = versionColor(json.version);
sendBadge(format, badgeData);
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));

// iTunes App Store version
camp.route(/^\/itunes\/v\/(.+)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
Expand Down
13 changes: 3 additions & 10 deletions services/appveyor/appveyor.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
'use strict';

const BaseService = require('../base');
const {
checkErrorResponse,
asJson,
} = require('../../lib/error-helper');
const { BaseJsonService } = require('../base');

module.exports = class AppVeyor extends BaseService {
module.exports = class AppVeyor extends BaseJsonService {
async handle({repo, branch}) {
let apiUrl = 'https://ci.appveyor.com/api/projects/' + repo;
if (branch != null) {
apiUrl += '/branch/' + branch;
}
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/json' }
}).then(checkErrorResponse.asPromise({ notFoundMessage: 'project not found or access denied' }))
.then(asJson);
const json = await this._requestJson(apiUrl, {}, 'project not found or access denied');

const { build: { status } } = json;
if (status === 'success') {
Expand Down
24 changes: 23 additions & 1 deletion services/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ const {
makeColor,
setBadgeColor,
} = require('../lib/badge-data');
const {
checkErrorResponse,
asJson,
} = require('../lib/error-helper');


module.exports = class BaseService {
class BaseService {
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
this._sendAndCacheRequest = sendAndCacheRequest;
this._handleInternalErrors = handleInternalErrors;
Expand Down Expand Up @@ -215,3 +220,20 @@ module.exports = class BaseService {
}));
}
};

class BaseJsonService extends BaseService {
async _requestJson(url, options = {}, notFoundMessage) {
return this._sendAndCacheRequest(url,
{...{ 'headers': { 'Accept': 'application/json' } }, ...options}
).then(
checkErrorResponse.asPromise(
notFoundMessage ? { notFoundMessage: notFoundMessage } : undefined
)
).then(asJson);
}
};

module.exports = {
BaseService,
BaseJsonService,
};
2 changes: 1 addition & 1 deletion services/base.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { expect } = require('chai');
const { test, given, forCases } = require('sazerac');
const sinon = require('sinon');

const BaseService = require('./base');
const { BaseService } = require('./base');

require('../lib/register-chai-plugins.spec');

Expand Down
15 changes: 4 additions & 11 deletions services/cdnjs/cdnjs.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
'use strict';

const BaseService = require('../base');
const {
checkErrorResponse,
asJson,
} = require('../../lib/error-helper');
const { BaseJsonService } = require('../base');
const { NotFound } = require('../errors');
const { addv: versionText } = require('../../lib/text-formatters');
const { version: versionColor} = require('../../lib/color-formatters');

module.exports = class Cdnjs extends BaseService {
module.exports = class Cdnjs extends BaseJsonService {
async handle({library}) {
const apiUrl = 'https://api.cdnjs.com/libraries/' + library + '?fields=version';
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/json' }
}).then(checkErrorResponse.asPromise())
.then(asJson);
const json = await this._requestJson(apiUrl);

if (Object.keys(json).length === 0) {
/* Note the 'not found' response from cdnjs is:
Expand All @@ -42,7 +35,7 @@ module.exports = class Cdnjs extends BaseService {
static get url() {
return {
base: 'cdnjs/v',
format: '(.*)',
format: '(.+)',
capture: ['library']
};
}
Expand Down
47 changes: 47 additions & 0 deletions services/clojars/clojars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

const { BaseJsonService } = require('../base');
const { NotFound } = require('../errors');
const { version: versionColor } = require('../../lib/color-formatters');

module.exports = class Clojars extends BaseJsonService {
async handle({clojar}) {
const apiUrl = 'https://clojars.org/' + clojar + '/latest-version.json';
const json = await this._requestJson(apiUrl);

if (Object.keys(json).length === 0) {
/* Note the 'not found' response from clojars is:
status code = 200, body = {} */
throw new NotFound();
}

return {
message: "[" + clojar + " \"" + json.version + "\"]",
color: versionColor(json.version)
};
}

// Metadata
static get defaultBadgeData() {
return { label: 'clojars' };
}

static get category() {
return 'version';
}

static get url() {
return {
base: 'clojars/v',
format: '(.+)',
capture: ['clojar']
};
}

static get examples() {
return [
{ previewUrl: 'prismic' }
];
}

};
42 changes: 13 additions & 29 deletions services/gem/gem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

const semver = require('semver');

const BaseService = require('../base');
const {
checkErrorResponse,
asJson,
} = require('../../lib/error-helper');
const { BaseJsonService } = require('../base');
const { InvalidResponse } = require('../errors');
const { addv: versionText } = require('../../lib/text-formatters');
const { version: versionColor} = require('../../lib/color-formatters');
Expand All @@ -21,13 +17,10 @@ const {
const { latest: latestVersion } = require('../../lib/version');


class GemVersion extends BaseService {
class GemVersion extends BaseJsonService {
async handle({repo}) {
const apiUrl = 'https://rubygems.org/api/v1/gems/' + repo + '.json';
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/json' }
}).then(checkErrorResponse.asPromise())
.then(asJson);
const json = await this._requestJson(apiUrl);
const version = json.version;

return {
Expand All @@ -48,7 +41,7 @@ class GemVersion extends BaseService {
static get url() {
return {
base: 'gem/v',
format: '(.*)',
format: '(.+)',
capture: ['repo']
};
}
Expand All @@ -66,7 +59,7 @@ class GemVersion extends BaseService {
}
};

class GemDownloads extends BaseService {
class GemDownloads extends BaseJsonService {

_getApiUrl(repo, info) {
const endpoint = info === "dv" ? 'versions/' : 'gems/';
Expand Down Expand Up @@ -94,10 +87,7 @@ class GemDownloads extends BaseService {
version = (version === "stable") ? version : semver.valid(version);
const label = this._getLabel(version, info);
const apiUrl = this._getApiUrl(repo, info);
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/atom+json,application/json' }
}).then(checkErrorResponse.asPromise())
.then(asJson);
const json = await this._requestJson(apiUrl);

let downloads;
if (info === "dt") {
Expand Down Expand Up @@ -155,7 +145,7 @@ class GemDownloads extends BaseService {
static get url() {
return {
base: 'gem',
format: '(dt|dtv|dv)/(.*)',
format: '(dt|dtv|dv)/(.+)',
capture: ['info', 'rubygem']
};
}
Expand Down Expand Up @@ -194,14 +184,11 @@ class GemDownloads extends BaseService {
}
};

class GemOwner extends BaseService {
class GemOwner extends BaseJsonService {

async handle({user}) {
const apiUrl = 'https://rubygems.org/api/v1/owners/' + user + '/gems.json';
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/json' }
}).then(checkErrorResponse.asPromise())
.then(asJson);
const json = await this._requestJson(apiUrl);
const count = json.length;

return {
Expand All @@ -222,7 +209,7 @@ class GemOwner extends BaseService {
static get url() {
return {
base: 'gem/u',
format: '(.*)',
format: '(.+)',
capture: ['user']
};
}
Expand All @@ -240,7 +227,7 @@ class GemOwner extends BaseService {
}
};

class GemRank extends BaseService {
class GemRank extends BaseJsonService {

_getApiUrl(repo, totalRank, dailyRank) {
let endpoint;
Expand All @@ -256,10 +243,7 @@ class GemRank extends BaseService {
const totalRank = (info === 'rt');
const dailyRank = (info === 'rd');
const apiUrl = this._getApiUrl(repo, totalRank, dailyRank);
const json = await this._sendAndCacheRequest(apiUrl, {
headers: { 'Accept': 'application/json' }
}).then(checkErrorResponse.asPromise())
.then(asJson);
const json = await this._requestJson(apiUrl);

let rank;
if (totalRank) {
Expand Down Expand Up @@ -289,7 +273,7 @@ class GemRank extends BaseService {
static get url() {
return {
base: 'gem',
format: '(rt|rd)/(.*)',
format: '(rt|rd)/(.+)',
capture: ['info', 'repo']
};
}
Expand Down

0 comments on commit f78e6f1

Please sign in to comment.