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
:
( scratchpad ) "http://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" "http://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 ) "http://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 ) "http://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.
( 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.
hi im xiackok. im done with gui just look at bakire-dunya.blogspot.com
ReplyDeleteWhere does http-image. come from? I was not able to find it anywhere in the listener.
ReplyDelete@Pallavolo, it comes from the "images.http" vocabulary.
ReplyDelete