[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:
13
services/sourceforge/sourceforge-base.js
Normal file
13
services/sourceforge/sourceforge-base.js
Normal 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',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
54
services/sourceforge/sourceforge-commit-count.service.js
Normal file
54
services/sourceforge/sourceforge-commit-count.service.js
Normal 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-commit-count.tester.js
Normal file
11
services/sourceforge/sourceforge-commit-count.tester.js
Normal 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' })
|
||||
43
services/sourceforge/sourceforge-contributors.service.js
Normal file
43
services/sourceforge/sourceforge-contributors.service.js
Normal 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-contributors.tester.js
Normal file
11
services/sourceforge/sourceforge-contributors.tester.js
Normal 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' })
|
||||
@@ -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',
|
||||
42
services/sourceforge/sourceforge-languages.service.js
Normal file
42
services/sourceforge/sourceforge-languages.service.js
Normal 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)
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-languages.tester.js
Normal file
11
services/sourceforge/sourceforge-languages.tester.js
Normal 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' })
|
||||
61
services/sourceforge/sourceforge-last-commit.service.js
Normal file
61
services/sourceforge/sourceforge-last-commit.service.js
Normal 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-last-commit.tester.js
Normal file
11
services/sourceforge/sourceforge-last-commit.tester.js
Normal 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' })
|
||||
48
services/sourceforge/sourceforge-platform.service.js
Normal file
48
services/sourceforge/sourceforge-platform.service.js
Normal 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),
|
||||
})
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-platform.tester.js
Normal file
11
services/sourceforge/sourceforge-platform.tester.js
Normal 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' })
|
||||
46
services/sourceforge/sourceforge-translations.service.js
Normal file
46
services/sourceforge/sourceforge-translations.service.js
Normal 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
11
services/sourceforge/sourceforge-translations.tester.js
Normal file
11
services/sourceforge/sourceforge-translations.tester.js
Normal 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' })
|
||||
Reference in New Issue
Block a user