Teste com o Sinatra

August 27, 2008 at 21:28

Esses 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.

http://gist.github.com/7610

Tags: , , ,

0 Responses to Teste com o Sinatra

Leave a Reply