refactor: use renderDownloadsBadge helper in remaining classes (#7211)

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
Caleb Cartwright
2021-10-31 11:10:05 -05:00
committed by GitHub
parent c3d213c65c
commit 8fcde9de85
15 changed files with 149 additions and 233 deletions

View File

@@ -1,5 +1,5 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'
@@ -13,19 +13,19 @@ const intervalMap = {
query: 'point/last-week',
schema: pointResponseSchema,
transform: json => json.downloads,
messageSuffix: '/week',
interval: 'week',
},
dm: {
query: 'point/last-month',
schema: pointResponseSchema,
transform: json => json.downloads,
messageSuffix: '/month',
interval: 'month',
},
dy: {
query: 'point/last-year',
schema: pointResponseSchema,
transform: json => json.downloads,
messageSuffix: '/year',
interval: 'year',
},
dt: {
query: 'range/1000-01-01:3000-01-01',
@@ -37,7 +37,6 @@ const intervalMap = {
json.downloads
.map(item => item.downloads)
.reduce((accum, current) => accum + current),
messageSuffix: '',
},
}
@@ -63,13 +62,12 @@ export default class NpmDownloads extends BaseJsonService {
// For testing.
static _intervalMap = intervalMap
static render({ interval, downloadCount }) {
const { messageSuffix } = intervalMap[interval]
return {
message: `${metric(downloadCount)}${messageSuffix}`,
color: downloadCount > 0 ? 'brightgreen' : 'red',
}
static render({ interval, downloadCount: downloads }) {
return renderDownloadsBadge({
downloads,
interval: intervalMap[interval].interval,
colorOverride: downloads > 0 ? 'brightgreen' : 'red',
})
}
async handle({ interval, scope, packageName }) {

View File

@@ -16,8 +16,9 @@ describe('NpmDownloads', function () {
interval: 'dt',
downloadCount: 0,
}).expect({
message: '0',
color: 'red',
message: '0',
label: undefined,
})
})
})

View File

@@ -1,5 +1,4 @@
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import OpenVSXBase from './open-vsx-base.js'
export default class OpenVSXDownloads extends OpenVSXBase {
@@ -18,7 +17,7 @@ export default class OpenVSXDownloads extends OpenVSXBase {
namespace: 'redhat',
extension: 'java',
},
staticPreview: this.render({ downloads: 29000 }),
staticPreview: renderDownloadsBadge({ downloads: 29000 }),
keywords: this.keywords,
},
{
@@ -29,30 +28,25 @@ export default class OpenVSXDownloads extends OpenVSXBase {
extension: 'java',
version: '0.69.0',
},
staticPreview: this.render({ version: '0.69.0', downloads: 29000 }),
staticPreview: renderDownloadsBadge({
version: '0.69.0',
downloads: 29000,
}),
keywords: this.keywords,
},
]
static defaultBadgeData = { label: 'downloads' }
static render({ version, downloads }) {
return {
label: version ? `downloads@${version}` : 'downloads',
message: metric(downloads),
color: downloadCount(downloads),
}
}
async handle({ namespace, extension, version }) {
const { version: tag, downloadCount } = await this.fetch({
const { version: tag, downloadCount: downloads } = await this.fetch({
namespace,
extension,
version,
})
return this.constructor.render({
return renderDownloadsBadge({
downloads,
version: version ? tag : undefined,
downloads: downloadCount,
})
}
}

View File

@@ -1,5 +1,4 @@
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { BaseOreService, documentation, keywords } from './ore-base.js'
export default class OreDownloads extends BaseOreService {
@@ -13,30 +12,17 @@ export default class OreDownloads extends BaseOreService {
static examples = [
{
title: 'Ore Downloads',
namedParams: {
pluginId: 'nucleus',
},
staticPreview: this.render({ downloads: 560891 }),
namedParams: { pluginId: 'nucleus' },
staticPreview: renderDownloadsBadge({ downloads: 560891 }),
documentation,
keywords,
},
]
static defaultBadgeData = {
label: 'downloads',
}
static render({ downloads }) {
return {
message: metric(downloads),
color: downloadCount(downloads),
}
}
static defaultBadgeData = { label: 'downloads' }
async handle({ pluginId }) {
const {
stats: { downloads },
} = await this.fetch({ pluginId })
return this.constructor.render({ downloads })
const { stats } = await this.fetch({ pluginId })
return renderDownloadsBadge({ downloads: stats.downloads })
}
}

View File

@@ -1,6 +1,5 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'
@@ -21,11 +20,11 @@ const schema = Joi.object({
}).required(),
})
function DownloadsForInterval(interval) {
const { base, messageSuffix, transform, name } = {
function DownloadsForInterval(downloadInterval) {
const { base, interval, transform, name } = {
day: {
base: 'packagecontrol/dd',
messageSuffix: '/day',
interval: 'day',
transform: resp => {
const platforms = resp.installs.daily.data
let downloads = 0
@@ -39,7 +38,7 @@ function DownloadsForInterval(interval) {
},
week: {
base: 'packagecontrol/dw',
messageSuffix: '/week',
interval: 'week',
transform: resp => {
const platforms = resp.installs.daily.data
let downloads = 0
@@ -55,7 +54,7 @@ function DownloadsForInterval(interval) {
},
month: {
base: 'packagecontrol/dm',
messageSuffix: '/month',
interval: 'month',
transform: resp => {
const platforms = resp.installs.daily.data
let downloads = 0
@@ -71,11 +70,10 @@ function DownloadsForInterval(interval) {
},
total: {
base: 'packagecontrol/dt',
messageSuffix: '',
transform: resp => resp.installs.total,
name: 'PackageControlDownloadsTotal',
},
}[interval]
}[downloadInterval]
return class PackageControlDownloads extends BaseJsonService {
static name = name
@@ -88,20 +86,13 @@ function DownloadsForInterval(interval) {
{
title: 'Package Control',
namedParams: { packageName: 'GitGutter' },
staticPreview: this.render({ downloads: 12000 }),
staticPreview: renderDownloadsBadge({ downloads: 12000 }),
keywords,
},
]
static defaultBadgeData = { label: 'downloads' }
static render({ downloads }) {
return {
message: `${metric(downloads)}${messageSuffix}`,
color: downloadCount(downloads),
}
}
async fetch({ packageName }) {
const url = `https://packagecontrol.io/packages/${packageName}.json`
return this._requestJson({ schema, url })
@@ -109,7 +100,10 @@ function DownloadsForInterval(interval) {
async handle({ packageName }) {
const data = await this.fetch({ packageName })
return this.constructor.render({ downloads: transform(data) })
return renderDownloadsBadge({
downloads: transform(data),
interval,
})
}
}
}

View File

@@ -1,6 +1,5 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { optionalUrl } from '../validators.js'
import {
keywords,
@@ -12,15 +11,14 @@ import {
const periodMap = {
dm: {
field: 'monthly',
suffix: '/month',
interval: 'month',
},
dd: {
field: 'daily',
suffix: '/day',
interval: 'day',
},
dt: {
field: 'total',
suffix: '',
},
}
@@ -55,9 +53,9 @@ export default class PackagistDownloads extends BasePackagistService {
user: 'doctrine',
repo: 'orm',
},
staticPreview: this.render({
staticPreview: renderDownloadsBadge({
downloads: 1000000,
interval: 'dm',
interval: 'month',
}),
keywords,
documentation: cacheDocumentationFragment,
@@ -69,9 +67,9 @@ export default class PackagistDownloads extends BasePackagistService {
user: 'doctrine',
repo: 'orm',
},
staticPreview: this.render({
staticPreview: renderDownloadsBadge({
downloads: 1000000,
interval: 'dm',
interval: 'month',
}),
queryParams: { server: 'https://packagist.org' },
keywords,
@@ -80,24 +78,20 @@ export default class PackagistDownloads extends BasePackagistService {
},
]
static defaultBadgeData = {
label: 'downloads',
}
static defaultBadgeData = { label: 'downloads' }
static render({ downloads, interval }) {
return {
message: metric(downloads) + periodMap[interval].suffix,
color: downloadCount(downloads),
}
}
async handle({ interval, user, repo }, { server }) {
async handle({ interval: period, user, repo }, { server }) {
const {
package: { downloads },
} = await this.fetchByJsonAPI({ user, repo, schema, server })
return this.constructor.render({
downloads: downloads[periodMap[interval].field],
} = await this.fetchByJsonAPI({
user,
repo,
schema,
server,
})
const { interval, field } = periodMap[period]
return renderDownloadsBadge({
downloads: downloads[field],
interval,
})
}

View File

@@ -1,5 +1,4 @@
import { downloadCount } from '../color-formatters.js'
import { metric } from '../text-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { BasePuppetForgeModulesService } from './puppetforge-base.js'
export default class PuppetforgeModuleDownloads extends BasePuppetForgeModulesService {
@@ -17,21 +16,14 @@ export default class PuppetforgeModuleDownloads extends BasePuppetForgeModulesSe
user: 'camptocamp',
moduleName: 'openldap',
},
staticPreview: this.render({ downloads: 720000 }),
staticPreview: renderDownloadsBadge({ downloads: 720000 }),
},
]
static defaultBadgeData = { label: 'downloads' }
static render({ downloads }) {
return {
message: metric(downloads),
color: downloadCount(downloads),
}
}
async handle({ user, moduleName }) {
const data = await this.fetch({ user, moduleName })
return this.constructor.render({ downloads: data.downloads })
const { downloads } = await this.fetch({ user, moduleName })
return renderDownloadsBadge({ downloads })
}
}

View File

@@ -1,8 +1,7 @@
import Joi from 'joi'
import { downloadCount } from '../color-formatters.js'
import { metric } from '../text-formatters.js'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'
import { renderDownloadsBadge } from '../downloads.js'
const keywords = ['python']
@@ -16,16 +15,16 @@ const schema = Joi.object({
const periodMap = {
dd: {
api_field: 'last_day',
suffix: '/day',
apiField: 'last_day',
interval: 'day',
},
dw: {
api_field: 'last_week',
suffix: '/week',
apiField: 'last_week',
interval: 'week',
},
dm: {
api_field: 'last_month',
suffix: '/month',
apiField: 'last_month',
interval: 'month',
},
}
@@ -46,20 +45,16 @@ export default class PypiDownloads extends BaseJsonService {
period: 'dd',
packageName: 'Django',
},
staticPreview: this.render({ period: 'dd', downloads: 14000 }),
staticPreview: renderDownloadsBadge({
interval: 'day',
downloads: 14000,
}),
keywords,
},
]
static defaultBadgeData = { label: 'downloads' }
static render({ period, downloads }) {
return {
message: `${metric(downloads)}${periodMap[period].suffix}`,
color: downloadCount(downloads),
}
}
async fetch({ packageName }) {
return this._requestJson({
url: `https://pypistats.org/api/packages/${packageName.toLowerCase()}/recent`,
@@ -69,10 +64,11 @@ export default class PypiDownloads extends BaseJsonService {
}
async handle({ period, packageName }) {
const json = await this.fetch({ packageName })
return this.constructor.render({
period,
downloads: json.data[periodMap[period].api_field],
const { apiField, interval } = periodMap[period]
const { data } = await this.fetch({ packageName })
return renderDownloadsBadge({
downloads: data[apiField],
interval,
})
}
}

View File

@@ -1,7 +1,6 @@
import Joi from 'joi'
import moment from 'moment'
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'
@@ -12,20 +11,19 @@ const schema = Joi.object({
const intervalMap = {
dd: {
startDate: endDate => endDate,
suffix: '/day',
interval: 'day',
},
dw: {
// 6 days, since date range is inclusive,
startDate: endDate => moment(endDate).subtract(6, 'days'),
suffix: '/week',
interval: 'week',
},
dm: {
startDate: endDate => moment(endDate).subtract(30, 'days'),
suffix: '/month',
interval: 'month',
},
dt: {
startDate: () => moment(0),
suffix: '',
},
}
@@ -68,11 +66,11 @@ export default class Sourceforge extends BaseJsonService {
static defaultBadgeData = { label: 'sourceforge' }
static render({ downloads, interval }) {
return {
label: 'downloads',
message: `${metric(downloads)}${intervalMap[interval].suffix}`,
color: downloadCount(downloads),
}
return renderDownloadsBadge({
downloads,
labelOverride: 'downloads',
interval: intervalMap[interval].interval,
})
}
async fetch({ interval, project, folder }) {
@@ -100,7 +98,7 @@ export default class Sourceforge extends BaseJsonService {
}
async handle({ interval, project, folder }) {
const json = await this.fetch({ interval, project, folder })
return this.constructor.render({ interval, downloads: json.total })
const { total: downloads } = await this.fetch({ interval, project, folder })
return this.constructor.render({ interval, downloads })
}
}

View File

@@ -1,5 +1,4 @@
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { BaseSpigetService, documentation, keywords } from './spiget-base.js'
export default class SpigetDownloads extends BaseSpigetService {
@@ -16,25 +15,16 @@ export default class SpigetDownloads extends BaseSpigetService {
namedParams: {
resourceId: '9089',
},
staticPreview: this.render({ downloads: 560891 }),
staticPreview: renderDownloadsBadge({ downloads: 560891 }),
documentation,
keywords,
},
]
static defaultBadgeData = {
label: 'downloads',
}
static render({ downloads }) {
return {
message: metric(downloads),
color: downloadCount(downloads),
}
}
static defaultBadgeData = { label: 'downloads' }
async handle({ resourceId }) {
const { downloads } = await this.fetch({ resourceId })
return this.constructor.render({ downloads })
return renderDownloadsBadge({ downloads })
}
}

View File

@@ -1,7 +1,8 @@
import Joi from 'joi'
import prettyBytes from 'pretty-bytes'
import { renderDownloadsBadge } from '../downloads.js'
import { metric, formatDate } from '../text-formatters.js'
import { age as ageColor, downloadCount } from '../color-formatters.js'
import { age as ageColor } from '../color-formatters.js'
import { NotFound } from '../index.js'
import BaseSteamAPI from './steam-base.js'
@@ -350,23 +351,15 @@ class SteamFileDownloads extends SteamFileService {
{
title: 'Steam Downloads',
namedParams: { fileId: '100' },
staticPreview: this.render({ downloads: 20124 }),
staticPreview: renderDownloadsBadge({ downloads: 20124 }),
documentation,
},
]
static defaultBadgeData = {
label: 'downloads',
}
static defaultBadgeData = { label: 'downloads' }
static render({ downloads }) {
return { message: metric(downloads), color: downloadCount(downloads) }
}
async onRequest({ response }) {
return this.constructor.render({
downloads: response.lifetime_subscriptions,
})
async onRequest({ response: { lifetime_subscriptions } }) {
return renderDownloadsBadge({ downloads: lifetime_subscriptions })
}
}

View File

@@ -1,5 +1,4 @@
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import VisualStudioMarketplaceBase from './visual-studio-marketplace-base.js'
const documentation = `
@@ -27,35 +26,29 @@ export default class VisualStudioMarketplaceAzureDevOpsInstalls extends VisualSt
measure: 'total',
extensionId: 'swellaby.mirror-git-repository',
},
staticPreview: this.render({ count: 651 }),
staticPreview: renderDownloadsBadge({ downloads: 651 }),
keywords: this.keywords,
documentation,
},
]
static defaultBadgeData = {
label: 'installs',
}
static defaultBadgeData = { label: 'installs' }
static render({ count }) {
return {
message: metric(count),
color: downloadCount(count),
transform({ json, measure }) {
const { statistics } = this.transformStatistics({ json })
const { onpremDownloads, install } = statistics
if (measure === 'total') {
return { downloads: onpremDownloads + install }
}
if (measure === 'services') {
return { downloads: install }
}
return { downloads: onpremDownloads }
}
async handle({ measure, extensionId }) {
const json = await this.fetch({ extensionId })
const { statistics } = this.transformStatistics({ json })
if (measure === 'total') {
return this.constructor.render({
count: statistics.onpremDownloads + statistics.install,
})
} else if (measure === 'services') {
return this.constructor.render({ count: statistics.install })
} else {
return this.constructor.render({ count: statistics.onpremDownloads })
}
const { downloads } = this.transform({ json, measure })
return renderDownloadsBadge({ downloads })
}
}

View File

@@ -1,5 +1,4 @@
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import VisualStudioMarketplaceBase from './visual-studio-marketplace-base.js'
const documentation = `
@@ -25,7 +24,7 @@ export default class VisualStudioMarketplaceDownloads extends VisualStudioMarket
title: 'Visual Studio Marketplace Installs',
pattern: 'visual-studio-marketplace/i/:extensionId',
namedParams: { extensionId: 'ritwickdey.LiveServer' },
staticPreview: this.render({ measure: 'i', count: 843 }),
staticPreview: this.render({ measure: 'i', downloads: 843 }),
keywords: this.keywords,
documentation,
},
@@ -33,29 +32,24 @@ export default class VisualStudioMarketplaceDownloads extends VisualStudioMarket
title: 'Visual Studio Marketplace Downloads',
pattern: 'visual-studio-marketplace/d/:extensionId',
namedParams: { extensionId: 'ritwickdey.LiveServer' },
staticPreview: this.render({ measure: 'd', count: 1239 }),
staticPreview: this.render({ measure: 'd', downloads: 1239 }),
keywords: this.keywords,
documentation,
},
]
static render({ measure, count }) {
const label = measure === 'd' ? 'downloads' : 'installs'
return {
label,
message: metric(count),
color: downloadCount(count),
}
static render({ measure, downloads }) {
const labelOverride = measure === 'd' ? 'downloads' : 'installs'
return renderDownloadsBadge({ downloads, labelOverride })
}
async handle({ measure, extensionId }) {
const json = await this.fetch({ extensionId })
const { statistics } = this.transformStatistics({ json })
const count =
const downloads =
measure === 'i'
? statistics.install
: statistics.install + statistics.updateCount
return this.constructor.render({ measure, count })
return this.constructor.render({ measure, downloads })
}
}

View File

@@ -1,5 +1,5 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { BaseJsonService, NotFound } from '../index.js'
const documentation = `
@@ -65,13 +65,11 @@ export default class WikiapiaryInstalls extends BaseJsonService {
static defaultBadgeData = { label: 'installs', color: 'informational' }
static render({ usage }) {
return { message: metric(usage) }
}
static validate({ results }) {
if (Array.isArray(results))
throw new NotFound({ prettyMessage: 'not found' })
static render({ usage: downloads }) {
return renderDownloadsBadge({
downloads,
colorOverride: 'informational',
})
}
async fetch({ variant, name }) {
@@ -88,12 +86,10 @@ export default class WikiapiaryInstalls extends BaseJsonService {
})
}
async handle({ variant, name }) {
const response = await this.fetch({ variant, name })
const { results } = response.query
this.constructor.validate({ results })
static transform({ results, variant, name }) {
if (Array.isArray(results)) {
throw new NotFound({ prettyMessage: 'not found' })
}
const keyLowerCase = `${variant}:${name.toLowerCase()}`
const resultKey = Object.keys(results).find(
key => keyLowerCase === key.toLowerCase()
@@ -103,6 +99,14 @@ export default class WikiapiaryInstalls extends BaseJsonService {
throw new NotFound({ prettyMessage: 'not found' })
const [usage] = results[resultKey].printouts['Has website count']
return { usage }
}
async handle({ variant, name }) {
const {
query: { results },
} = await this.fetch({ variant, name })
const { usage } = this.constructor.transform({ results, name, variant })
return this.constructor.render({ usage })
}
}

View File

@@ -1,6 +1,5 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { downloadCount } from '../color-formatters.js'
import { renderDownloadsBadge } from '../downloads.js'
import { NotFound } from '../index.js'
import BaseWordpress from './wordpress-base.js'
@@ -22,23 +21,22 @@ const extensionData = {
const intervalMap = {
dd: {
limit: 1,
messageSuffix: '/day',
interval: 'day',
},
dw: {
limit: 7,
messageSuffix: '/week',
interval: 'week',
},
dm: {
limit: 30,
messageSuffix: '/month',
interval: 'month',
},
dy: {
limit: 365,
messageSuffix: '/year',
interval: 'year',
},
dt: {
limit: null,
messageSuffix: '',
},
}
@@ -66,12 +64,10 @@ function DownloadsForExtensionType(extensionType) {
static defaultBadgeData = { label: 'downloads' }
static render({ interval, downloads }) {
const { messageSuffix } = intervalMap[interval]
return {
message: `${metric(downloads)}${messageSuffix}`,
color: downloadCount(downloads),
}
return renderDownloadsBadge({
downloads,
interval: intervalMap[interval].interval,
})
}
async handle({ interval, slug }) {
@@ -130,25 +126,18 @@ function InstallsForExtensionType(extensionType) {
{
title: `WordPress ${capt} Active Installs`,
namedParams: { slug: exampleSlug },
staticPreview: this.render({ installCount: 300000 }),
staticPreview: renderDownloadsBadge({ downloads: 300000 }),
},
]
static defaultBadgeData = { label: 'active installs' }
static render({ installCount }) {
return {
message: metric(installCount),
color: downloadCount(installCount),
}
}
async handle({ slug }) {
const { active_installs: installCount } = await this.fetch({
extensionType,
slug,
})
return this.constructor.render({ installCount })
return renderDownloadsBadge({ downloads: installCount })
}
}
}