Created
August 16, 2011 00:48
-
-
Save EmmanuelOga/1148224 to your computer and use it in GitHub Desktop.
Scrape rally on rails scores.
This file contains hidden or 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
require 'rubygems' | |
require 'nokogiri' | |
require 'open-uri' | |
require 'mysql' | |
require 'active_record' | |
ActiveRecord::Base.establish_connection( | |
adapter: "mysql", encoding: "utf8", database: "scores", username: "root", password: "" | |
) | |
class App < ActiveRecord::Base | |
def self.setup | |
ActiveRecord::Schema.define do | |
create_table(:apps) do |t| | |
t.string :title, :team, :url, :members, :team_url | |
t.float :integrity, :interface, :originality, :utility | |
t.integer :score | |
end rescue nil | |
end | |
end | |
def self.scrap(path) | |
print "." | |
team_url = "http://rallyonrails.com#{path}" | |
doc = Nokogiri::HTML(open(team_url).read.force_encoding('UTF-8')) | |
url = doc.at("h3 a")["href"] | |
votes = (doc / ".stars-1").map { |node| node.text.to_f } | |
score = doc.css("section hgroup h2").map(&:content).map do |line| | |
match_data = line.match(/\((.*)(\ pts.\))/) | |
match_data[1] if match_data | |
end.compact.first.to_i | |
app = find_or_initialize_by_url(url) | |
app.update_attributes :team => (doc / "h1")[1].text, | |
:title => doc.at("h3").text, | |
:url => url, | |
:members => doc.at("ul.members").children.map(&:text).map { |m| m.gsub(/\s+|\n/m, "") }.flatten.reject(&:blank?).join(" "), | |
:integrity => votes[0], | |
:interface => votes[1], | |
:originality => votes[2], | |
:utility => votes[3], | |
:team_url => team_url, | |
:score => score | |
rescue | |
nil | |
end | |
def self.update_all | |
doc = Nokogiri::HTML(open("http://rallyonrails.com/teams").read.force_encoding('UTF-8')) | |
(doc / "h2 a").map do |node| | |
path = node["href"].to_s | |
scrap(path) if path =~ /\/teams\/\d+/ | |
end.compact.sort | |
end | |
def total | |
(integrity || 0) + (interface || 0) + (originality || 0) + (utility || 0) | |
end | |
def <=> (other) | |
other.total <=> total | |
end | |
def to_s | |
"#{title}: #{total} (#{url})" | |
end | |
def members | |
read_attribute("members").to_s.split(" ").map do |attr| | |
name = attr.to_s[/([^(]+)/] && $1 | |
$1.present? ? $1 : name | |
end | |
end | |
end | |
if ARGV.first == "update" | |
puts "Updating..." | |
App.setup | |
App.update_all | |
puts "done" | |
else | |
require 'sinatra' | |
require 'haml' | |
enable :inline_templates | |
get("/") do | |
@apps = App.all.sort | |
haml :index | |
end | |
end | |
__END__ | |
@@index | |
!!! | |
%html | |
%head | |
%title Rally on Rails Results! | |
%meta{:charset => "utf-8"}/ | |
%meta{:content => "ie=edge", "http-equiv" => "x-ua-compatible"}/ | |
%meta{:content => "Emmanuel Oga", :name => "author"}/ | |
%meta{:content => "Licensed under GPL and MIT.", :name => "copyright"}/ | |
%meta{:content => "Results", :name => "description"}/ | |
%script{:src => "https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"} | |
%style{:type => "text/css"} | |
:plain | |
* { | |
text-align: center; | |
} | |
body { | |
font: 13px/1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; | |
padding: 10px; margin: 0 10px; | |
background-color: #fefec0; | |
} | |
h1 a { font-size: 36px; font-weight: bold; text-decoration: none; } | |
table { | |
background-color: #ddd; | |
margin: 2.5%; | |
width: 95%; padding: 10px; margin: 10px | |
border: 1px solid #ddd; | |
-moz-border-radius: 10px; | |
-webkit-border-radius: 10px; | |
border-radius: 10px; /* future proofing */ | |
-khtml-border-radius: 10px; /* for old Konqueror browsers */ | |
-moz-box-shadow: 5px 5px 5px #ccc; | |
-webkit-box-shadow: 5px 5px 5px #ccc; | |
box-shadow: 5px 5px 5px #ccc; | |
} | |
th {background: #efefef} | |
tr:nth-child(even) {background: #fefefe} | |
tr:nth-child(odd) {background: #efefef} | |
tr:hover { background: yellow; } | |
td, tr, th { padding: 5px; } | |
.total { font-weight: bold; color: green; font-size: 15px; } | |
.me { background-color: #afa !important; } | |
%script{:type => "application/javascript"} | |
= File.read("dt.js") | |
%script{:type => "application/javascript"} | |
:plain | |
$(function(){ | |
$("#scores").dataTable({ "iDisplayLength": 50, "aaSorting": [[8,'desc']] }); | |
}); | |
%body | |
%h1 | |
%a{:href => "http://rallyonrails.com/teams" } Rally On Rails Results | |
%h2 | |
Voting Completion (estimate): | |
= "#{(100 * @apps.select { |a| a.total > 0 }.length / @apps.length)}%" | |
%p | |
Refresh every now and then to get updates. | |
%small | |
%a{:href => "https://gist.github.com/1148224" } ( gist ) | |
%table#scores | |
%thead | |
%tr | |
- [:app, :members, :team, :integrity, :interface, :originality, :utility, "Stars Avg", "Judge Points"].each do |attr| | |
%th= attr.to_s.titleize | |
%tbody | |
- @apps.each do |app| | |
%tr{:class => (app.team.to_s =~ /jointstorm/i ? "me" : "not_me") } | |
%td | |
%a{:href => app.url}= app.title | |
%td | |
- app.members.each do |name| | |
%a{:href => "http://github.com/#{name}"}= name | |
%td | |
%a{:href => app.team_url}= app.team | |
- [:integrity, :interface, :originality, :utility].each do |attr| | |
%td= app.send(attr) | |
%td= app.total | |
%td.total= app.score |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment