mirror of
https://github.com/textmate/textmate.git
synced 2026-04-28 03:00:34 -04:00
JSON should be a subset of YAML so we use ruby’s YAML parser to parse GitHub’s JSON. This however leads to syntax errors reported by the parser (as noted in issue #637) but if the JSON is “pretty printed” it seems to parse it fine (seems to be the extra white space for associative array pairs). We can trick GitHub into pretty printing the JSON result by setting the user agent to be curl, so that is all this workaround does.
133 lines
4.4 KiB
Ruby
Executable File
133 lines
4.4 KiB
Ruby
Executable File
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -wKU
|
|
# == Synopsis
|
|
#
|
|
# Module to assist in building the Contributors page using git commit history.
|
|
#
|
|
|
|
require 'getoptlong'
|
|
require 'rdoc/usage'
|
|
require 'digest/md5'
|
|
require 'net/https'
|
|
require 'uri'
|
|
require 'cgi'
|
|
require 'dbm'
|
|
require 'date'
|
|
require 'yaml'
|
|
|
|
# Helper class to handle searching for GitHub users
|
|
# by their email address. Caches mappings to a file
|
|
# to avoid exhausting the GitHub API rate limits for
|
|
# anonymous requests.
|
|
class GitHubLookup
|
|
|
|
def self.initialize(dbm_file)
|
|
@db = DBM.new(dbm_file)
|
|
# seed with some contributors that don't have an email
|
|
# address assigned publicly in their account
|
|
@db['1178ce2f664a6cee9a05a3e11af5d8d2'] = 'aaronbrethorst'
|
|
@db['3b0ef5e2a5f1aa3ccf3f23a20adf8873'] = 'Hoverbear'
|
|
@db['ff3502050b3b1b00cb6c810d5c41ffc9'] = 'bradchoate'
|
|
@db['ee646002e51a3c83e01db85ae42187ff'] = 'dmcdougall'
|
|
@db['85af9ad71af2dc0166b7c0c5780fa086'] = 'caldwell'
|
|
@db['fa64968e4a3c8e20364bb92ba7511ff9'] = 'dvennink'
|
|
@db['0669ff1e3ada91e7f1e7714f6f9a67f6'] = 'etienne'
|
|
@db['49ed289f3de94dbcd7c10392bcc40b53'] = 'fernando82'
|
|
@db['7b3ae2214891a47b26b4db98949c1bb0'] = 'gknops'
|
|
@db['34820bca697fbf1598774b393c5ca4fe'] = 'whitlockjc'
|
|
@db['ec9254734cd341f1b104d558dc4fc36a'] = 'joachimm'
|
|
@db['09c16a631eeba332147a8d620e1369cc'] = 'muellerj'
|
|
@db['6890db3146e20bfb99be3bc7bc3bfeec'] = 'lczekaj'
|
|
@db['e34425c11547a48a4701c9d1720dadf8'] = 'infininight'
|
|
@db['65efe3355478c8db96bc82f22fd3aa20'] = 'nathanieltagg'
|
|
@db['4e89e196a1f8fa34a6bdc6d165f75e5e'] = 'Ralle'
|
|
@db['ccc5b318408880a67eeebf0d18177fb5'] = 'rhencke'
|
|
@db['4cf620221f7e622260f8424b8142451f'] = 'ryanmaxwell'
|
|
@db['5780111eb4b5565816d9388b091e1057'] = 'youngrok'
|
|
ObjectSpace.define_finalizer(@db, proc {|id| db.close })
|
|
end
|
|
|
|
def self.user_by_email(email)
|
|
emailhash = Digest::MD5.hexdigest(email)
|
|
if @db.has_key?(emailhash)
|
|
return @db[emailhash]
|
|
end
|
|
|
|
url = 'https://api.github.com/legacy/user/email/' + email
|
|
uri = URI.parse(url)
|
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
http.use_ssl = true
|
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
|
|
# issue request
|
|
request = Net::HTTP::Get.new(uri.request_uri, {'User-Agent' => 'curl'})
|
|
response = http.request(request)
|
|
|
|
# could be a 404, return nil if so
|
|
if response.code == '404'
|
|
return @db[emailhash] = nil
|
|
end
|
|
|
|
user = YAML.load(response.body)
|
|
# save result to k/v store
|
|
return @db[emailhash] = user['user']['login']
|
|
end
|
|
|
|
end
|
|
|
|
def generate_credits(dbm_file)
|
|
GitHubLookup.initialize(dbm_file)
|
|
|
|
# use git's log command to pull out basic info:
|
|
# git hash, author name, email address, author date, commit summary
|
|
cmd = 'git log -z --date=iso --pretty=format:"%H%n%an%n%ae%n%ad%n%s%n%B"'
|
|
|
|
`#{cmd}`.split(/\x00/s).each {|commit|
|
|
fields = commit.split(/\n/, 6)
|
|
|
|
# omit commits from Allan; he gets enough credit already ;)
|
|
if fields[1] != 'Allan Odgaard' then
|
|
# hash email address for referencing Gravatar userpics
|
|
emailhash = Digest::MD5.hexdigest(fields[2])
|
|
|
|
# escape user-supplied bits like name and subject
|
|
hash = fields[0]
|
|
name = CGI.escapeHTML(fields[1])
|
|
# locate the GitHub login for the author's email address
|
|
user = GitHubLookup.user_by_email(fields[2])
|
|
date = DateTime.parse(fields[3])
|
|
subject = CGI.escapeHTML(fields[4])
|
|
body = CGI.escapeHTML(fields[5].sub(fields[4], '').sub(/[\s\x00]+$/s, '').sub(/^[\s\x00]+/s, ''))
|
|
userpic = "http://www.gravatar.com/avatar/#{emailhash}?s=48&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"
|
|
|
|
# if we have a github username, populate a link to their
|
|
# profile.
|
|
if !user || user == ''
|
|
user = nil
|
|
STDERR << "WARNING: failed to find GitHub user for #{name} <#{fields[2]}>\n";
|
|
end
|
|
|
|
yield(hash, name, subject, body, userpic, date, user)
|
|
end
|
|
}
|
|
end
|
|
|
|
__END__
|
|
# Contributions
|
|
|
|
See [commits at GitHub][1].
|
|
|
|
<table width="100%">
|
|
<tr>
|
|
<th width="20%">Author</th>
|
|
<th width="60%">Contribution</th>
|
|
<th width="20%">Date</th>
|
|
</tr>
|
|
<%
|
|
require 'bin/gen_credits'
|
|
credits = generate_credits(File.expand_path('~/Library/Caches/com.macromates.TextMate/githubcredits'))
|
|
%>
|
|
<%= credits %>
|
|
</table>
|
|
|
|
[1]: https://github.com/textmate/textmate/commits/master
|