You've already forked AstralRinth
forked from didirus/AstralRinth
122 lines
2.9 KiB
JavaScript
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()
|
|
}
|