GitHub Vanity
Monday, January 24, 2011
There was a blog
post
on The Changelog yesterday describing a
project that can give at-a-glance statistics about a GitHub user. The
project is called vain
and is open
source. Since implementing APIs is
fun (at least the first few times), I thought I would show how to
implement the vain
utility using Factor
and the GitHub API.
USING: accessors assocs combinators formatting http.client
json.reader kernel math sequences sorting utils ;
Experiment
We can experiment with the GitHub API in the Factor Listener, looking at
seejohnrun, the creator of vain
:
IN: scratchpad "https://github.com/api/v2/json/user/show/seejohnrun"
http-get nip json> .
H{
{
"user"
H{
{ "followers_count" 18 }
{
"gravatar_id"
"3a0541ed3d5324bb54b9f07990be20ae"
}
{ "login" "seejohnrun" }
{ "public_gist_count" 0 }
{ "public_repo_count" 23 }
{ "location" "Verona, NJ" }
{ "created_at" "2009/03/19 10:29:18 -0700" }
{ "type" "User" }
{ "id" 64965 }
{ "blog" "https://johncrepezzi.com" }
{ "email" "john@crepezzi.com" }
{ "name" "John Crepezzi" }
{ "company" "Patch" }
{ "permission" json-null }
{ "following_count" 11 }
}
}
}
Implement
We can use the
set-slots
word (similar to how we implemented Reddit
“Top”) to get
the user details:
TUPLE: user blog company created_at email followers_count
following_count gravatar_id id location login name permission
public_gist_count public_repo_count type ;
: user-info ( login -- user )
"https://github.com/api/v2/json/user/show/%s" sprintf
http-get nip json> "user" swap at
user new [ set-slots ] keep ;
Similarly, we can access a list of public repositories for a specific user:
TUPLE: repository created_at description fork forks
has_downloads has_issues has_wiki homepage language name
open_issues organization owner private pushed_at size url
watchers ;
: repositories ( login -- seq )
"https://github.com/api/v2/json/repos/show/%s" sprintf
http-get nip json> "repositories" swap at
[ repository new [ set-slots ] keep ] map ;
Using this, we have everything we need to implement vain
:
: vain ( login -- )
[
user-info {
[ login>> ]
[ followers_count>> ]
[ public_repo_count>> ]
} cleave
"%s - %s followers - %s public repositories\n" printf
] [
repositories [ watchers>> ] inv-sort-with [
{
[ name>> ]
[ watchers>> "%s watchers" sprintf ]
[ forks>> "%s forks" sprintf ]
[ fork>> "(FORK)" "" ? ]
} cleave "%-25s %12s %12s %s\n" printf
] each
] bi ;
Try It
You can see the output for seejohnrun.
IN: scratchpad "seejohnrun" vain
seejohnrun - 18 followers - 23 public repositories
ice_cube 255 watchers 15 forks
database_validation 60 watchers 4 forks
track_history 57 watchers 4 forks
easy_translate 39 watchers 2 forks
vain 23 watchers 2 forks
console_tweet 15 watchers 1 forks
tweetStream4J 6 watchers 3 forks
my_tunes 3 watchers 1 forks
locale_base 2 watchers 1 forks
Open-Stanza 2 watchers 1 forks
Pretty-Damn-Fancy 1 watchers 1 forks
rstack 1 watchers 1 forks
dependable 1 watchers 1 forks
quick_short 1 watchers 1 forks
html_namespacing 1 watchers 0 forks (FORK)
usps 1 watchers 0 forks (FORK)
dotfiles 1 watchers 1 forks
datejs 1 watchers 0 forks (FORK)
redis-repeater 1 watchers 1 forks
roflscale 1 watchers 1 forks
weatherbug 1 watchers 1 forks
gravatar_helper 1 watchers 1 forks
columnizer 1 watchers 1 forks
Bonus
Some fun with Gravatar pictures:
The code for this is on my GitHub.