Created
July 13, 2010 10:30
-
-
Save drnic/473707 to your computer and use it in GitHub Desktop.
Discover the contribution status of a user for all their watched repos: owner, collaborator, or watcher
This file contains 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
#!/usr/bin/env ruby | |
# | |
# Discover the contribution status of a user for all their watched repos: owner, collaborator, or watcher | |
# Returns either JSON (default) or HTML (example http://github-user-profiles-example.heroku.com/) | |
# | |
# JSON: Returns either Array of JSON; or streams each JSON result as discovered (--stream flag) | |
# { "repo" => { ... }, "owner" => is project owner?, "collaborator" => has collaborator access? } | |
# | |
# HTML: Sort-of pretty HTML output. Nice to use --stream | bcat. | |
# | |
# Usage: | |
# | |
# Save to file github_user_collaborations.rb | |
# | |
# JSON usage: | |
# ./github_user_collaborations.rb drnic --stream # lots of results streamed | |
# ./github_user_collaborations.rb kef # 20+ results in an Array | |
# | |
# HTML usage: | |
# gem install bcat | |
# ./github_user_collaborations.rb drnic --stream --html | bcat | |
# | |
# Or: | |
# | |
# ruby -rubygems -ropen-uri -e 'eval open("http://gist.github.com/raw/473707/github_user_collaborations.rb").read' drnic --stream | |
require "json" | |
require "open-uri" | |
def collaborators(user, project) | |
begin | |
url = "http://github.com/api/v2/json/repos/show/#{user}/#{project}/collaborators" | |
$stderr.puts "open #{url}" if ENV['DEBUG'] | |
JSON.parse(open(url).read)["collaborators"] | |
rescue OpenURI::HTTPError => e | |
$stderr.puts "404 on #{url}" if ENV['DEBUG'] | |
[] | |
end | |
end | |
def watched_repos(user) | |
begin | |
url = "http://github.com/api/v2/json/repos/watched/#{user}" | |
$stderr.puts "open #{url}" if ENV['DEBUG'] | |
JSON.parse(open(url).read)["repositories"] | |
rescue OpenURI::HTTPError => e | |
$stderr.puts "404 on #{url}" if ENV['DEBUG'] | |
[] | |
end | |
end | |
def contributions(user, &block) | |
if block | |
watched_repos(user).each do |repo| | |
is_owner = repo["owner"] == user | |
yield({ "repo" => repo, "owner" => is_owner, "collaborator" => (is_owner || collaborators(repo["owner"], repo["name"]).include?(user)) }) | |
end | |
else | |
watched_repos(user).map do |repo| | |
is_owner = repo["owner"] == user | |
{ "repo" => repo, "owner" => is_owner, "collaborator" => (is_owner || collaborators(repo["owner"], repo["name"]).include?(user)) } | |
end | |
end | |
end | |
def render_html_header(user) | |
puts <<-HTML | |
<html> | |
<head> | |
<title>Profile for Github User #{user}</title> | |
<link href="http://assets2.github.com/stylesheets/bundle_common.css" media="screen" rel="stylesheet" type="text/css" /> | |
<link href="http://assets1.github.com/stylesheets/bundle_github.css" media="screen" rel="stylesheet" type="text/css" /> | |
</head> | |
<body> | |
<div class="first"> | |
<h2>#{user} repositories</h2> | |
<ul class="repositories"> | |
HTML | |
end | |
def render_contribution_html(contribution) | |
repo = contribution["repo"] | |
puts <<-HTML | |
<li class="public"> | |
<ul class="repo-stats"> | |
#{render_status(contribution["owner"], contribution["collaborator"], repo['url'])} | |
</ul> | |
<h3><a href="#{repo['url']}">#{repo["owner"]}/#{repo["name"]}</a></h3> | |
<div class="body"> | |
</div> | |
</li> | |
HTML | |
$stdout.flush | |
end | |
def render_status(owner, collaborator, url) | |
if owner | |
%Q{<li class="forks"><a href="#{url}" title="Owner">Owner</a></li>} | |
elsif collaborator | |
%Q{<li class="forks"><a href="#{url}" title="Contributor">Contributor</a></li>} | |
end | |
end | |
def render_contributions_html(user, contributions) | |
render_html_header user | |
contributions.each {|contribution| render_contribution_html contribution } | |
end | |
options = {:format => "json"} | |
parser = OptionParser.new do |opts| | |
opts.banner = <<-BANNER.gsub(/^ /, '') | |
Discover the contribution status of a user for all their watched repositories: owner, collaborator, or watcher | |
Returns JSON { "repo" => { ... }, "owner" => is project owner?, "collaborator" => has collaborator access? } | |
Returns either Array of JSON above; or streams each JSON result as discovered (--stream flag) | |
Usage: #{File.basename($0)} user [options] | |
Options are: | |
BANNER | |
opts.separator "" | |
opts.on("-s", "--stream", | |
"Stream each watched repository result on a line of its own." | |
) { |arg| options[:stream] = true } | |
opts.on("--html", | |
"Outputs HTML (streaming and non-stream)", | |
"Default: false" | |
) { |arg| options[:format] = "html" } | |
opts.on("--json", | |
"Outputs JSON (streaming and non-stream)", | |
"Default: true" | |
) { |arg| options[:format] = "json" } | |
opts.on("-h", "--help", | |
"Show this help message.") { $stdout.puts opts; exit } | |
opts.parse!(ARGV) | |
end | |
if user = ARGV.shift | |
if options[:format] == "json" | |
if options[:stream] | |
contributions(user) do |contribution| | |
puts contribution.to_json | |
$stdout.flush | |
end | |
else | |
print contributions(user).to_json | |
end | |
elsif options[:format] == "html" | |
if options[:stream] | |
render_html_header user | |
contributions(user) do |contribution| | |
render_contribution_html contribution | |
end | |
else | |
render_contributions_html user, contributions(user) | |
end | |
end | |
else | |
puts parser | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment