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.
47 lines
1.4 KiB
JavaScript
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
|