1
0
Files
AstralRinth/src/plugins/generator/outputs/landingPage.js

122 lines
2.9 KiB
JavaScript

import { fetch } from '../fetch.js'
import { promises as fs } from 'fs'
import cliProgress from 'cli-progress'
export async function landingPage() {
const progressBar = new cliProgress.SingleBar({
format: 'Generating landing page | {bar} | {percentage}%',
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
hideCursor: true,
})
progressBar.start(111, 0)
/* MOD STACKS */
// Fetch top 100 mods
const mods = await (await fetch('search?limit=100&facets=[["project_type:mod"]]')).json()
// Simplified array with the format: ['id', 'slug', 'icon_extension']
const compressedMods = mods.hits
.filter((project) => project.icon_url)
.map((project) => {
progressBar.increment()
return [
project.project_id,
project.slug || '',
project.icon_url.match(/\.[0-9a-z]+$/i)[0].substring(1),
]
})
/* 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: compressedMods,
statistics,
contributors,
})
)
progressBar.stop()
}