Add landing page data for statistics & contributors

This commit is contained in:
venashial 2022-07-29 13:44:34 -07:00
parent fba6dd750d
commit 0e1c7cd8ed
3 changed files with 91 additions and 8 deletions

View File

@ -12,7 +12,7 @@ export async function fetch(route, options = {}) {
if (!version) {
version = JSON.parse(await fs.readFile('./package.json', 'utf8')).version
}
return baseFetch(API_URL + route, {
return baseFetch((route.startsWith('http') ? '' : API_URL) + route, {
...options,
headers: {
'user-agent': `Omorphia / ${version} (venashial@modrinth.com)`,

View File

@ -4,18 +4,19 @@ import cliProgress from 'cli-progress'
export async function landingPage() {
const progressBar = new cliProgress.SingleBar({
format: 'Generating landing page | {bar} | {percentage}% || {value}/{total} mods',
format: 'Generating landing page | {bar} | {percentage}%',
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
hideCursor: true,
})
progressBar.start(100, 0)
progressBar.start(111, 0)
/* MOD STACKS */
// Fetch top 100 mods
const response = await (await fetch('search?limit=100&facets=[["project_type:mod"]]')).json()
const mods = await (await fetch('search?limit=100&facets=[["project_type:mod"]]')).json()
// Simplified array with the format: ['id', 'slug', 'icon_extension']
const compressed = response.hits
const compressedMods = mods.hits
.filter((project) => project.icon_url)
.map((project) => {
progressBar.increment()
@ -26,12 +27,94 @@ export async function landingPage() {
]
})
/* STATISTICS */
const statistics = {
downloads: 0,
projects: 0,
authors: 0,
}
// Get total number of projects
const projectCount = (await (await fetch('search?limit=0')).json()).total_hits
statistics.projects = projectCount
progressBar.increment()
const authors = new Set()
// Number of pages through search to fetch
const requestCount = Math.ceil(projectCount / 100)
await Promise.allSettled(
Array.from({ length: requestCount }, async (_, index) => {
const response = await fetch(`search?limit=100&offset=${index * 100}`)
if (!response.ok) {
throw new Error(`Failed to fetch projects: ${response.statusText}`)
}
// Get project hits & use map to get rid of extra data
const { hits } = await response.json()
for (const hit of hits) {
authors.add(hit.author)
statistics.downloads += hit.downloads
}
})
)
statistics.authors = authors.size
progressBar.increment()
/* CONTRIBUTORS */
const contributorCounts = new Map()
const repoNames = [
'knossos',
'labrinth',
'theseus',
'minotaur',
'hydra',
'daedalus',
'omorphia',
'sisyphus',
'ariadne',
]
const repos = await Promise.all(
repoNames.map(async (repo) => {
const response = await fetch(`https://api.github.com/repos/modrinth/${repo}/contributors`)
if (!response.ok) {
console.error(await response.json())
throw new Error('Could not fetch repository from GitHub')
}
progressBar.increment()
return await response.json()
})
)
for (const repo of repos) {
for (const user of repo) {
if (!user.login.includes('[bot]')) {
contributorCounts.set(user.login, {
avatar_url: user.avatar_url,
contributions:
(contributorCounts.get(user.login)?.contributions || 0) + user.contributions,
})
}
}
}
const contributors = Array.from(contributorCounts, ([name, data]) => ({ name, ...data })).sort(
(a, b) => b.contributions - a.contributions
)
// Write JSON file
await fs.writeFile(
'./generated/landingPage.json',
JSON.stringify({
mods: compressed,
random: Math.random(),
mods: compressedMods,
statistics,
contributors,
})
)
progressBar.stop()

View File

@ -4,7 +4,7 @@
*/
const rft = new Intl.RelativeTimeFormat(
typeof navigator !== 'undefined' ? [...navigator.languages] : ['en'],
typeof navigator !== 'undefined' ? [...navigator?.languages] : ['en'],
{ numeric: 'auto' }
)