Improve contributors.rb plugin

Validate returned data from GitHub API
htmlescape data on the HTML page
Drop unnecessary yaml dependency
Add more comments in the code
Add more aliases in _config.yml
Fix vertical-align style
This commit is contained in:
Saivann 2014-06-06 15:33:16 -04:00
parent f6f85b4447
commit 187ed2562a
4 changed files with 68 additions and 33 deletions

View file

@ -112,6 +112,13 @@ aliases:
--author=Satoshi Nakamoto: Satoshi Nakamoto --author=Satoshi Nakamoto: Satoshi Nakamoto
gavinandresen: Gavin Andresen gavinandresen: Gavin Andresen
tcatm: Nils Schneider tcatm: Nils Schneider
gmaxwell: Gregory Maxwell
sipa: Pieter Wuille
jgarzik: Jeff Garzik
petertodd: Peter Todd
luke-jr: Luke-Jr
laanwj: Wladimir J. van der Laan
mikehearn: Mike Hearn
safe: false safe: false
server_port: 4000 server_port: 4000

View file

@ -961,10 +961,11 @@ table td,table th{
font-size:80%; font-size:80%;
} }
.contributors span{ .contributors span{
padding:6px 0; padding:8px 0;
width:170px; width:170px;
overflow:hidden; overflow:hidden;
display:inline-block; display:inline-block;
vertical-align:top;
} }
.resources{ .resources{

View file

@ -4,56 +4,83 @@
require 'open-uri' require 'open-uri'
require 'json' require 'json'
require 'yaml'
module Jekyll module Jekyll
class CategoryGenerator < Generator class CategoryGenerator < Generator
def fetch_contributors
page = 1 def contributors(aliases)
contributors = [] contributors = []
# Call GitHub API with 100 results per page
page = 1
data = []
while page < 10 do while page < 10 do
begin begin
ar = JSON.parse(open("https://api.github.com/repos/bitcoin/bitcoin/contributors?page=#{page}&per_page=100","User-Agent"=>"Ruby/#{RUBY_VERSION}").read) ar = JSON.parse(open("https://api.github.com/repos/bitcoin/bitcoin/contributors?page=#{page}&per_page=100","User-Agent"=>"Ruby/#{RUBY_VERSION}").read)
# Prevent any error to stop the build process, return an empty array instead
rescue rescue
print 'GitHub API Call Failed!' print 'GitHub API Call Failed!'
break break
end end
if !ar.is_a?(Array)
print 'GitHub API Call Failed!'
return contributors
end
if ar.length > 100
print 'GitHub API exceeding the 100 results limit!'
return contributors
end
# Stop calling GitHub API when no new results are returned
break if (ar.length == 0) break if (ar.length == 0)
contributors.push(*ar) # Merge contributors into a single array
data.push(*ar)
page += 1 page += 1
end end
# Loop in returned results array
contributors.map do |x| result = {}
x['name'] = x['login'] unless x.has_key?('name') for c in data
x['name'] = x['login'] if x['name'] == "" # Skip incomplete / invalid data and set contributor's name
next if !c.is_a?(Hash)
x next if !c.has_key?('contributions') or !c['contributions'].is_a?(Integer) or c['contributions'] > 1000000
if c.has_key?('name') and c['name'].is_a?(String) and /^[A-Za-z0-9\-]{1,150}$/.match(c['name'])
name = c['name']
elsif c.has_key?('login') and c['login'].is_a?(String) and /^[A-Za-z0-9\-]{1,150}$/.match(c['login'])
name = c['login']
else
next
end
# Replace name by its corresponding alias if defined in _config.yml
name = aliases[name] if aliases.has_key?(name)
# Assign variables
x = {}
x['name'] = name
x['contributions'] = c['contributions']
# Set gravatar_id when available
if c.has_key?('gravatar_id') and c['gravatar_id'].is_a?(String) and /^[A-Za-z0-9\-]{1,150}$/.match(c['gravatar_id'])
x['gravatar_id'] = c['gravatar_id']
end
# Set login when available
if c.has_key?('login') and c['login'].is_a?(String) and /^[A-Za-z0-9\-]{1,150}$/.match(c['login'])
x['login'] = c['login']
end
# Add new contributor to the array, or increase contributions if it already exists
if result.has_key?(name)
result[name]['contributions'] += x['contributions']
else
result[name] = x
end end
end end
# Generate final ordered contributors array
def merge_contributors(contributors, aliases) result.each do |key, value|
contributors = contributors.map do |c| contributors.push(value)
c['name'] = aliases[c['name']] if aliases.has_key?(c['name'])
c
end end
contributors.sort_by{|c| - c['contributions']}
hoaoh = contributors.reduce({}) do |result, item|
result.merge({ item['name'] => [item] }) { |key, old, new| old[0]['contributions'] += new[0]['contributions']; old }
end
hoaoh.values.map { |sublist|
sublist.reduce({}) do |merged,h|
merged.merge(h) do |key,old,new| (key=='name' ? old : old+new) end
end
}.flatten
end end
def generate(site) def generate(site)
# Set site.contributors global variables for liquid/jekyll
class << site class << site
attr_accessor :contributors attr_accessor :contributors
alias contrib_site_payload site_payload alias contrib_site_payload site_payload
def site_payload def site_payload
h = contrib_site_payload h = contrib_site_payload
@ -63,8 +90,8 @@ module Jekyll
h h
end end
end end
# Populate site.contributors array
site.contributors = merge_contributors(fetch_contributors(), site.config['aliases']).sort_by{|c| - c['contributions']} site.contributors = contributors(site.config['aliases'])
end end
end end

View file

@ -77,7 +77,7 @@ id: development
<div class="contributors">{% for c in site.contributors %} <div class="contributors">{% for c in site.contributors %}
<span> <span>
{% if c.gravatar_id %}<img class="icon" height="16" width="16" src="https://secure.gravatar.com/avatar/{{c.gravatar_id}}?s=140&amp;d=mm" alt="icon" />{% else %}<img class="icon" height="16" width="16" alt="icon" />{% endif %} {% if c.gravatar_id %}<img class="icon" height="16" width="16" src="https://secure.gravatar.com/avatar/{{c.gravatar_id}}?s=140&amp;d=mm" alt="icon" />{% else %}<img class="icon" height="16" width="16" alt="icon" />{% endif %}
{% if c.login %}<a href="https://github.com/{{c.login}}">{{ c.name }} ({{ c.contributions }})</a>{% else %}{{ c.name }} ({{ c.contributions }}){% endif %} {% if c.login %}<a href="https://github.com/{{c.login}}">{{ c.name | htmlescape }} ({{ c.contributions }})</a>{% else %}<a>{{ c.name | htmlescape }} ({{ c.contributions }})</a>{% endif %}
</span>{% endfor %} </span>{% endfor %}
</div> </div>
</section> </section>