Teste com o Sinatra
August 27, 2008 at 21:28Esses dias vi alguém no Twitter falando do Sinatra (não me lembro quem, e também fiquei com preguiça de procurar :P ) e resolvi testar. Fiz um script que monta um select com todos os episódios do Rails Podcast Brasil, e ainda dando a possibilidade de ver o show notes de cada um deles.
Para instalar o Sinatra basta um simples
sudo gem install sinatra
Para ver se está funcionando basta criar um arquivo muito simples como esse: (test_sinatra.rb)
require 'rubygems'
require 'sinatra'
get '/' do
"Funciona muuuito esse Sinatra"
end
Botar o webserver a rodar
ruby test_sinatra.rb
E rodar no browser
http://localhost:4567/
Se aparecer na sua tela: Funciona muito esse Sinatra então tudo funcionou como deveria :)
Agora vamos a parte mais "complicada". Vamos pegar o nosso arquivo test_sinatra.tb e colocar o código abaixo:
require 'rubygems'
require 'sinatra'
require 'hpricot'
require 'open-uri'
get '/' do
body = '<form method="post" action="/"><select name="link">'
doc = Hpricot(open("http://podcast.rubyonrails.pro.br/"))
(doc/'div.sub').each do |sub|
a = sub.next_sibling.search('a').last
if a
(sub/'h1').each do |h1|
number = h1.children[0].inner_text
puts number.to_s
if number[0] == 35 # igual a #
body << '<option value="' + a[:href] + '">Episódio ' + number + ' - ' + h1.children[2].inner_text + '</option>'
end
end
end
end
body << '</select><button>Ok</button></form>'
end
post '/' do
body = '<form method="post" action="/"><select name="link">'
doc = Hpricot(open("http://podcast.rubyonrails.pro.br/"))
(doc/'div.sub').each do |sub|
a = sub.next_sibling.search('a').last
if a
(sub/'h1').each do |h1|
number = h1.children[0].inner_text
if number[0] == 35 # igual a #
body << '<option value="' + a[:href] + '">Episódio ' + number + ' - ' + h1.children[2].inner_text + '</option>'
end
end
end
end
body << '</select><button>Ok</button></form>'
doc = Hpricot(open("http://podcast.rubyonrails.pro.br#{params[:link]}"))
body << (doc/'div.content ul').last.to_html
end
Pelo código podemos ver que temos uma chamada para get '/' e outra post '/'. Elas tratam da mesma URL, porém dependendendo do método HTTP atual ele chama um ou outro, isso é bom para separar alguma lógica que seja diferente entre eles.
Mas temos um problema, o nosso código não está DRY, tem muito código duplicado. Para resolver isso o Sinatra possui helpers também, que podem ser criados facilmente usando o método helpers, assim:
helpers do
def meu_helper
# faz alguma coisa e retorna o resultado
end
end
Depois é só usar onde quiser
get '/minha_pagina' do
meu_helper
end
Simples assim. Abaixo o script atualizado usando um helper
require 'rubygems'
require 'sinatra'
require 'hpricot'
require 'open-uri'
helpers do
def episodes_form
body = '<form method="post" action="/"><select name="link">'
doc = Hpricot(open("http://podcast.rubyonrails.pro.br/"))
(doc/'div.sub').each do |sub|
a = sub.next_sibling.search('a').last
if a
(sub/'h1').each do |h1|
number = h1.children[0].inner_text
puts number.to_s
if number[0] == 35 # igual a #
body << '<option value="' + a[:href] + '">Episódio ' + number + ' - ' + h1.children[2].inner_text + '</option>'
end
end
end
end
body << '</select><button>Ok</button></form>'
end
end
get '/' do
episodes_form
end
post '/' do
body = episodes_form
doc = Hpricot(open("http://podcast.rubyonrails.pro.br#{params[:link]}"))
body << (doc/'div.content ul').last.to_html
end
Para coisas muito simples, frameworks como o Sinatra ajudam bastante, deixando tudo mais prático, mas obviamente tudo tem um limite, não recomendaria ele para aplicações maiores, então, caso precise de algo "mais sério", vá de Rails :)
OBS: O código está usando Hpricot, um parser HTML, bem rápido e fácil de usar, caso você não tenha ele instalado basta fazer como sempre
sudo gem install hpricot
OBS 2: Eu tinha colocado os códigos no gist, mas parece que ele não permite "embedar" diferentes revisões de um mesmo código, então resolvi tirar e colocar somente o link para lá, caso alguem queira dar uma fuçada.