Welcome to WeeklyRandom, a blog series in which I challenge myself to explore a random GitHub repository starred by me every week.
Let's get started. I'll need a way to retrieve a random GitHub repository starred by me. I found this Gist that shows how one can retrieve the starred repositories of a user.
// https://gist.github.com/derhuerst/19e0844796fa3b62e1e9567a1dc0b5a3
const stars = (user) =>
got(`https://api.github.com/users/${user}/starred`)
.then((res) => JSON.parse(res.body))
.then((starred) => starred.map((s) => ({
owner: s.owner.login
, repo: s.name
, description: s.description
, language: s.language
, isFork: false
, stargazers: s.stargazers_count
, watchers: s.watchers_count
})))
I am no JavaScript wizard 🧙 and do not know if the got
dependency is really necessary here. Let's keep it for now.
Problem: This only returns 30 repositories. Since the GitHub API is paginated, I'll need to figure out a way to get the total number of pages before trying to get a random page and entry. I solved this by parsing the response headers which contained the following Link
:
<https://api.github.com/user/13335308/starred?page=2>; rel="next", <https://api.github.com/user/13335308/starred?page=93>; rel="last"
Perfect. I can use rel="last"
to generate a random page number between 1 and - in this case - 93. If I send a request for that page, the only thing left to do is to pick a random repository out of the returned 30.
This is the current script:
Note: Updated on Oct 16, 2018 to reflect changes suggested by u/ChucklefuckBitch and u/dulac91. Thanks!
// index.js
"use strict";
const got = require("got");
let user = process.argv.slice(2)[0];
let randomEntry = Math.floor(Math.random() * 30);
let lastPage = new RegExp(/(.*)page=(.*)>; rel=\"last\"/);
if (!user) {
console.log("Usage: `node index.js username`");
process.exit(1);
}
const getStars = (user, page) =>
got(`https://api.github.com/users/${user}/starred?page=${page}`)
.then((res) => JSON.parse(res.body))
.then((starred) =>
starred.map((s) => ({
owner: s.owner.login,
repo: s.name
}))
);
const getRandomPage = (user) =>
got(`https://api.github.com/users/${user}/starred`)
.then((res) =>
res.headers.link
.replace(lastPage, "$2")
)
.then((pages) => Math.floor(Math.random() * pages) + 1);
getRandomPage(user, randomEntry)
.then((page) => getStars(user, page))
.then((result) =>
console.log("https://github.com/" + result[randomEntry].owner + "/" + result[randomEntry].repo)
);
I'm pretty sure that this is a very inefficient way to do this, but it should get the job done. The whole purpose of this series is to learn something and to improve myself. And I definitely learned something about consuming the GitHub API and about arrow functions in JavaScript.
Let's try it:
node index.js vintagesucks
https://github.com/lgkonline/mavo-snippets
node index.js vintagesucks
https://github.com/simonepri/geo-maps
node index.js vintagesucks
https://github.com/genuinetools/apk-file
It works! 🎉
You can find the complete code on GitHub at vintagesucks/random-starred-repository. Pull requests with improvements are very welcome!
Until next week, when I'll check out my first WeeklyRandom repository.
Top comments (0)