[SourceForge] Added badges for SourceForge (#9078)

* Added sourceforge last-commit badge

* Added sourceforge commit-count badge

* Added sourceforge languages badge

* Added sourceforge contributors badge

* Added sourceforge translations badge

* Added sourceforge platform badge

* Fix SourceForge services ClassName

* Fixed JoiSchema + Added BaseSourceForgeService + Fixed last-commit and commit-count
This commit is contained in:
Av32000
2023-04-17 21:23:42 +02:00
committed by GitHub
parent 8d060fd419
commit c2998a2dc9
15 changed files with 377 additions and 4 deletions

View File

@@ -0,0 +1,13 @@
import { BaseJsonService } from '../index.js'
export default class BaseSourceForgeService extends BaseJsonService {
async fetch({ project, schema }) {
return this._requestJson({
url: `https://sourceforge.net/rest/p/${project}/`,
schema,
errorMessages: {
404: 'project not found',
},
})
}
}

View File

@@ -0,0 +1,54 @@
import Joi from 'joi'
import { BaseJsonService } from '../index.js'
import { metric } from '../text-formatters.js'
const schema = Joi.object({
commit_count: Joi.number().required(),
}).required()
export default class SourceforgeCommitCount extends BaseJsonService {
static category = 'activity'
static route = {
base: 'sourceforge/commit-count',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge commit count',
namedParams: {
project: 'guitarix',
},
staticPreview: this.render({
commitCount: 1365,
}),
},
]
static defaultBadgeData = { label: 'commit count' }
static render({ commitCount }) {
return {
message: metric(commitCount),
color: 'blue',
}
}
async fetch({ project }) {
return this._requestJson({
url: `https://sourceforge.net/rest/p/${project}/git`,
schema,
errorMessages: {
404: 'project not found',
},
})
}
async handle({ project }) {
const body = await this.fetch({ project })
return this.constructor.render({
commitCount: body.commit_count,
})
}
}

View File

@@ -0,0 +1,11 @@
import { isMetric } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('commit count')
.get('/guitarix.json')
.expectBadge({ label: 'commit count', message: isMetric })
t.create('commit count (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'commit count', message: 'project not found' })

View File

@@ -0,0 +1,43 @@
import Joi from 'joi'
import { renderContributorBadge } from '../contributor-count.js'
import BaseSourceForgeService from './sourceforge-base.js'
const schema = Joi.object({
developers: Joi.array().required(),
}).required()
export default class SourceforgeContributors extends BaseSourceForgeService {
static category = 'activity'
static route = {
base: 'sourceforge/contributors',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge contributors',
namedParams: {
project: 'guitarix',
},
staticPreview: this.render({
contributorCount: 9,
}),
},
]
static defaultBadgeData = { label: 'contributors' }
static render({ contributorCount }) {
return renderContributorBadge({
contributorCount,
})
}
async handle({ project }) {
const body = await this.fetch({ project, schema })
return this.constructor.render({
contributorCount: body.developers.length,
})
}
}

View File

@@ -0,0 +1,11 @@
import { isMetric } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('contributors')
.get('/guitarix.json')
.expectBadge({ label: 'contributors', message: isMetric })
t.create('contributors (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'contributors', message: 'project not found' })

View File

@@ -27,17 +27,17 @@ const intervalMap = {
},
}
export default class Sourceforge extends BaseJsonService {
export default class SourceforgeDownloads extends BaseJsonService {
static category = 'downloads'
static route = {
base: 'sourceforge',
base: 'sourceforge/downloads',
pattern: ':interval(dt|dm|dw|dd)/:project/:folder*',
}
static examples = [
{
title: 'SourceForge',
title: 'SourceForge Downloads',
pattern: ':interval(dt|dm|dw|dd)/:project',
namedParams: {
interval: 'dm',
@@ -49,7 +49,7 @@ export default class Sourceforge extends BaseJsonService {
}),
},
{
title: 'SourceForge',
title: 'SourceForge Downloads (folder)',
pattern: ':interval(dt|dm|dw|dd)/:project/:folder',
namedParams: {
interval: 'dm',

View File

@@ -0,0 +1,42 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import BaseSourceForgeService from './sourceforge-base.js'
const schema = Joi.object({
categories: Joi.object({
language: Joi.array().required(),
}).required(),
}).required()
export default class SourceforgeLanguages extends BaseSourceForgeService {
static category = 'analysis'
static route = {
base: 'sourceforge/languages',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge languages',
namedParams: {
project: 'mingw',
},
staticPreview: this.render(6),
},
]
static defaultBadgeData = { label: 'languages' }
static render(languages) {
return {
message: metric(languages),
color: 'blue',
}
}
async handle({ project }) {
const body = await this.fetch({ project, schema })
return this.constructor.render(body.categories.language.length)
}
}

View File

@@ -0,0 +1,11 @@
import { isMetric } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('languages')
.get('/guitarix.json')
.expectBadge({ label: 'languages', message: isMetric })
t.create('languages (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'languages', message: 'project not found' })

View File

@@ -0,0 +1,61 @@
import Joi from 'joi'
import { BaseJsonService } from '../index.js'
import { formatDate } from '../text-formatters.js'
import { age as ageColor } from '../color-formatters.js'
const schema = Joi.object({
commits: Joi.array()
.items(
Joi.object({
committed_date: Joi.string().required(),
}).required()
)
.required(),
}).required()
export default class SourceforgeLastCommit extends BaseJsonService {
static category = 'activity'
static route = {
base: 'sourceforge/last-commit',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge last commit',
namedParams: {
project: 'guitarix',
},
staticPreview: this.render({
commitDate: 1653556285,
}),
},
]
static defaultBadgeData = { label: 'last commit' }
static render({ commitDate }) {
return {
message: formatDate(new Date(commitDate)),
color: ageColor(new Date(commitDate)),
}
}
async fetch({ project }) {
return this._requestJson({
url: `https://sourceforge.net/rest/p/${project}/git/commits`,
schema,
errorMessages: {
404: 'project not found',
},
})
}
async handle({ project }) {
const body = await this.fetch({ project })
return this.constructor.render({
commitDate: body.commits[0].committed_date,
})
}
}

View File

@@ -0,0 +1,11 @@
import { isFormattedDate } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('last commit')
.get('/guitarix.json')
.expectBadge({ label: 'last commit', message: isFormattedDate })
t.create('last commit (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'last commit', message: 'project not found' })

View File

@@ -0,0 +1,48 @@
import Joi from 'joi'
import BaseSourceForgeService from './sourceforge-base.js'
const schema = Joi.object({
categories: Joi.object({
os: Joi.array()
.items({
fullname: Joi.string().required(),
})
.required(),
}).required(),
}).required()
export default class SourceforgePlatform extends BaseSourceForgeService {
static category = 'platform-support'
static route = {
base: 'sourceforge/platform',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge Platform',
namedParams: {
project: 'guitarix',
},
staticPreview: this.render({
platforms: ['linux', 'bsd'],
}),
},
]
static defaultBadgeData = { label: 'platform' }
static render({ platforms }) {
return {
message: platforms.join(' | '),
}
}
async handle({ project }) {
const body = await this.fetch({ project, schema })
return this.constructor.render({
platforms: body.categories.os.map(obj => obj.fullname),
})
}
}

View File

@@ -0,0 +1,11 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('platform')
.get('/guitarix.json')
.expectBadge({ label: 'platform', message: Joi.string().required() })
t.create('platform (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'platform', message: 'project not found' })

View File

@@ -0,0 +1,46 @@
import Joi from 'joi'
import { metric } from '../text-formatters.js'
import BaseSourceForgeService from './sourceforge-base.js'
const schema = Joi.object({
categories: Joi.object({
translation: Joi.array().required(),
}).required(),
}).required()
export default class SourceforgeTranslations extends BaseSourceForgeService {
static category = 'activity'
static route = {
base: 'sourceforge/translations',
pattern: ':project',
}
static examples = [
{
title: 'SourceForge Translations',
namedParams: {
project: 'guitarix',
},
staticPreview: this.render({
translationCount: 4,
}),
},
]
static defaultBadgeData = { label: 'translations' }
static render({ translationCount }) {
return {
message: metric(translationCount),
color: 'blue',
}
}
async handle({ project }) {
const body = await this.fetch({ project, schema })
return this.constructor.render({
translationCount: body.categories.translation.length,
})
}
}

View File

@@ -0,0 +1,11 @@
import { isMetric } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('translations')
.get('/guitarix.json')
.expectBadge({ label: 'translations', message: isMetric })
t.create('translations (project not found)')
.get('/that-doesnt-exist.json')
.expectBadge({ label: 'translations', message: 'project not found' })