Files
shields/services/base-svg-scraping.js
Paul Melnikow 275805e90c Add BaseSvgScrapingService and rewrite [ReadTheDocs]; also affects [codacy vso] (#2229)
Based on discussion in #2031, this adds an abstract service for SVG badges. I started with Readthedocs and the other services can be done as a follow-on.

I called it **BaseSvgScrapingService** rather than **BaseSvgService** to clarify that it's for badges from svg source data – not svg badges, which is all the badges.

Since I don't expect the svg parsing function to be used anywhere else once the services are refactored, I moved it into the class. I added a default value for `valueMatcher`, which works on Shields-style badges and seems to be used more than once.

The tests are based on XmlBaseService. I added one for valueMatcher, and also moved the SVG parsing badge here. Testing on codacy + vso should ensure the old `fetchFromSvg` is still working.
2018-11-01 15:09:00 -04:00

47 lines
1.4 KiB
JavaScript

'use strict'
// See available emoji at http://emoji.muan.co/
const emojic = require('emojic')
const BaseService = require('./base')
const trace = require('./trace')
const { InvalidResponse } = require('./errors')
const defaultValueMatcher = />([^<>]+)<\/text><\/g>/
const leadingWhitespace = /(?:\r\n\s*|\r\s*|\n\s*)/g
class BaseSvgScrapingService extends BaseService {
static valueFromSvgBadge(svg, valueMatcher = defaultValueMatcher) {
if (typeof svg !== 'string') {
throw TypeError('Parameter should be a string')
}
const stripped = svg.replace(leadingWhitespace, '')
const match = valueMatcher.exec(stripped)
if (match) {
return match[1]
} else {
throw new InvalidResponse({
prettyMessage: 'unparseable svg response',
underlyingError: Error(`Can't get value from SVG:\n${svg}`),
})
}
}
async _requestSvg({ valueMatcher, url, options = {}, errorMessages = {} }) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
const mergedOptions = {
...{ headers: { Accept: 'image/svg+xml' } },
...options,
}
const { buffer } = await this._request({
url,
options: mergedOptions,
errorMessages,
})
logTrace(emojic.dart, 'Response SVG', buffer)
const message = this.constructor.valueFromSvgBadge(buffer, valueMatcher)
return { message }
}
}
module.exports = BaseSvgScrapingService