Skip to content

Instantly share code, notes, and snippets.

@jstrutz
Created February 4, 2016 05:11
Show Gist options
  • Save jstrutz/6a871450185602aab9b8 to your computer and use it in GitHub Desktop.
Save jstrutz/6a871450185602aab9b8 to your computer and use it in GitHub Desktop.
Webtask.io Github Contribution Data API-ification! 🤘
"use latest";
/*
* A webtask.io little hack to scrape the github contributions data, and present it in some usable JSON
*
* Setup:
* - Download this file
* - Setup a webtask.io account
* - Upload to webtask.io with something like:
* wt create --name github-contributions github-contributions-webtask.js
* - Make note of the endpoint webtask.io provides for you
*
* Usage (replace the given url with your own)
* curl https://webtask.it.auth0.com/api/run/wt-j-jasonstrutz_com-0/github-contributions?username=jstrutz
*
* the `username` querystring argument is a GitHub username, and is required
*
*/
var fetch = require('isomorphic-fetch');
var htmlparser = require('htmlparser2');
function githubContributions(username) {
let url = 'https://github.com/users/'+username+'/contributions';
return fetch(url)
.then( res => res.text())
.then( body => {
let contributionsByDay = {},
parser = new htmlparser.Parser({
onopentag: (name, attribs) => {
if(name === "rect" && attribs['class'] === "day"){
let count = parseInt(attribs['data-count']),
date = attribs['data-date'];
contributionsByDay[date] = count;
}
},
}, {decodeEntities: true});
parser.write(body);
parser.end();
// Calculate streaks and totals from days
return Object.keys(contributionsByDay).sort().reduce( (agg, day) => {
let count = contributionsByDay[day];
agg.total += count;
if (count > 0) {
agg.currentStreak += 1;
}
else {
if (agg.longestStreak < agg.currentStreak) agg.longestStreak = agg.currentStreak;
agg.currentStreak = 0;
}
return agg;
}, {
username: username,
total: 0,
currentStreak: 0,
longestStreak: 0,
days: contributionsByDay
});
});
}
module.exports = function(ctx, cb) {
var username = ctx.data.username;
if (username) {
githubContributions(ctx.data.username)
.then( results => cb(null, results), err => cb(err) );
}
else {
cb(Error("You must provide a `username` argument"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment