Last active
March 27, 2021 20:37
-
-
Save MaxGraey/e80843bf15e9eacc4f2881126b590648 to your computer and use it in GitHub Desktop.
Script which sort programming languages in Github Explore Collection Category
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO: next implement HITS ranking algorithm from: https://d-nb.info/1112813659/34 | |
const https = require('https'); | |
const url = require('url'); | |
const fs = require('fs'); | |
const LANGS_URL = 'https://raw.githubusercontent.com/github/explore/main/collections/programming-languages/index.md'; | |
const MD_PROLOGUE = "---\nitems:\n"; | |
const MD_EPILOGUE = ( | |
"\n" + | |
"display_name: Programming languages\n" + | |
"created_by: leereilly\n" + | |
"---\n" + | |
"A list of programming languages that are actively developed on GitHub\n" | |
); | |
function request(urlString, headersOptions = {}) { | |
return new Promise((ok, fail) => { | |
const { host, path } = url.parse(urlString); | |
const options = { host, path, headers: { | |
'User-Agent': 'NodeJS', ...headersOptions } | |
}; | |
let content = ''; | |
https.get(options, response => { | |
response.on('data', data => { | |
content += data.toString(); | |
}).on('end', () => { ok(content); }); | |
}).on('error', err => { | |
fail(err.message); | |
}); | |
}); | |
} | |
function zip(a, b) { | |
return a.map((e, i) => [e, b[i]]); | |
} | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
function getLangCollection(content) { | |
return content.split('\n') | |
.filter(l => l.startsWith('- ')) | |
.map(l => l.substring(2)); | |
} | |
function computeScore({ stargazers_count: stars, forks }) { | |
// Use simple geometric weighted mean for now | |
const STARS_WEIGHT = 0.85; | |
const FORKS_WEIGHT = 0.15; | |
const n = ( | |
STARS_WEIGHT * Math.log(stars) + | |
FORKS_WEIGHT * Math.log(forks) | |
); | |
const m = STARS_WEIGHT + FORKS_WEIGHT; | |
const score = Math.exp(n / m); | |
if (!Number.isFinite(score)) { | |
throw new Error(`Invalid score for stars=${stars}, watchers=${watchers}, forks=${forks}`); | |
} | |
return score; | |
} | |
async function regenerateMarkdownPage() { | |
const collection = getLangCollection(await request(LANGS_URL)); | |
const responces = []; | |
console.log('please wait...'); | |
for (const repo of collection) { | |
try { | |
const responce = await request(`https://api.github.com/repos/${repo}`); | |
responces.push(responce); | |
await sleep(40); | |
} catch (e) { | |
throw new Error('cannot accees to GitHub API or parse responce', e); | |
} | |
} | |
// calculate scores from "stars", "subscribers" and "repos" in responce data | |
const scores = responces.map(info => computeScore(JSON.parse(info))); | |
const entries = zip(collection, scores); | |
// descending sort by score | |
entries.sort((a, b) => { | |
const score1 = a[1]; | |
const score2 = b[1]; | |
return score2 - score1; | |
}); | |
const updatedContent = ( | |
MD_PROLOGUE + | |
entries.map((e, i) => '- ' + e[0]).join('\n') + | |
MD_EPILOGUE | |
); | |
console.log(updatedContent); | |
fs.writeFileSync(__dirname + '/index.md', updatedContent); | |
} | |
regenerateMarkdownPage(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment