public
Last active

Discover the contribution status of a user for all their watched repos: owner, collaborator, or watcher

  • Download Gist
github_user_collaborations.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
#!/usr/bin/env ruby
#
# Discover the contribution status of a user for all their watched repos: 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:
#
# Save to file github_user_collaborations.rb
# ./github_user_collaborations.rb drnic --stream # lots of results streamed
# ./github_user_collaborations.rb kef # 20+ results in an Array
#
# 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">
<li class="watchers"><a href="/drnic/github_organizations_scraper/watchers" title="Owner">#{contribution["owner"]}</a></li>
<li class="forks"><a href="/drnic/github_organizations_scraper/network" title="Contributor">#{contribution["collaborator"]}</a></li>
</ul>
<h3><a href="#{repo['url']}">#{repo["name"]}</a></h3>
<div class="body">
</div>
</li>
HTML
$stdout.flush
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.