Skip to content

Instantly share code, notes, and snippets.

@EmmanuelOga
Created August 16, 2011 00:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EmmanuelOga/1148224 to your computer and use it in GitHub Desktop.
Save EmmanuelOga/1148224 to your computer and use it in GitHub Desktop.
Scrape rally on rails scores.
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