HashCode

An organizer of symbols

Pixily hiring RoR guy

Pixily hiring RoR guy

Quando o RAID não funciona

Ok esse não era pra ser o primeiro post do ano de 2009 mas o “RAID” do meu antigo provedor(que era cortesia) deu pau.


Como diria o velho ditado modificado “na casa do espeto o churrasqueiro é de pau” eu tinha um script na cron fazendo backup diário mas o que eu não tinha percebido era que minha chave publica tinha sido modificada :( .

Recebi alguns emails de pessoas querendo acessar alguns links então acho que esse blog pode ser de certo modo útil.

Diário de um desenvolvedor by Daft Punk

Nada mais que a verdade :) Só faltou commit it, push it, list it …

Buy it, use it, break it, fix it,
Trash it, change it, mail - upgrade it,
Charge it, point it, zoom it, press it,
Snap it, work it, quick - erase it,
Write it, cut it, paste it, save it,
Load it, check it, quick - rewrite it,
Plug it, play it, burn it, rip it,
Drag and drop it, zip - unzip it,
Lock it, fill it, call it, find it,
View it, code it, jam - unlock it,
Surf it, scroll it, pause it, click it,
Cross it, crack it, switch - update it,
Name it, rate it, tune it, print it,
Scan it, send it, fax - rename it,
Touch it, bring it, Pay it, watch it,
Turn it, leave it, start - format it.

Remix

Instalando RGhost com Debgem no Ubuntu Hardy

Acho que foi ontem que eu vi sobre o projeto DebGem dos caras da Phusion. O projeto consiste em portar uma gem para um pacote .deb. Fui testar achando que iria dar o maior pau mas eu estava errado, funcionou plug’n'play. O que eu fiz foi basicamente descrito abaixo.

Configurando o apt-get

Configurei o novo source para o apt-get colocando no arquivo /etc/apt/source.list a nova entrada

 deb http://www.debgem.com/apt ubuntu-8.04 rubyforge

No shell adicionei a nova chave

wget -q http://www.debgem.com/apt/debgem.gpg -O- | sudo apt-key add -

e por fim, atualizei o apt-get

sudo apt-get update

Tudo isso está bem documentado aqui

Obtendo o nome do pacote

Entre no site http://www.debgem.com/usage e digite o nome da gem, no nosso caso ‘rghost’, aparecerá uma página com o nome e a descrição da gem

Observe a linha Install command apt-get install librghost-ruby , instale com

sudo apt-get install librghost-ruby

Testando

Abra o irb ou crie um arquivo para testar

require 'rubygems'
require 'rghost'

RGhost::Config.is_ok? :render => "/tmp/test.pdf"

`evince /tmp/test.pdf`

Conclusão

Perfeito! Não há nada que reclamar :)

IRB com reverse search no Apple Terminal

Após muitas tentativa achei uma solução plausível, agora o meu irb aceita Ctrl+R. Solução simples
Edite o ~/.editrc e cole

bind "^R" em-inc-search-prev

Que saudade do gnome-terminal …

RGhost Barcode no Github

Onde posso encontrar 32 tipos de código de barras, de graça? Tenho que gerar em PDF ou imagens?

A solução está aqui no GitHub RGhost Barcode

Poli-hashcode sempre uma solução para salvar sua vida. :)

Firulando código em ruby para wordpress

Ultimamente estou recebendo emails me perguntando qual o plugin do WordPress eu uso para deixar o código do meu blog ‘bonitinho’. Já enviei uns 6 emails para pessoas diferentes, já que o pessoal está gostando vou postar a minha solução.

Criei um programinha que chamei de compile_post.rb ele recebe um arquivo texto e formata as tags code para html.

O programa requer as gems hpricot e syntax, para instalar basta

sudo gem install hpricot
sudo gem install syntax

O conteúdo é esse

#!/usr/bin/ruby
require 'rubygems'
require 'hpricot'
require 'syntax/convertors/html'

convertor = Syntax::Convertors::HTML.for_syntax "ruby"
source=ARGV[0]

abort "usage: ruby compile_post.rb filename.txt" unless source

doc = Hpricot.parse(File.readlines(source).join)
(doc/"code").each do |c|
   c.inner_html=convertor.convert(c.to_s.gsub(/<code>|<\/code>/,''),true)
end
File.open("#{source}.post",'w'){|f| f.puts doc.to_s.gsub(/<code>|<\/code>/,'') }

O programa gerará um arquivo .post é só copiar e colar no post editor do WordPress

Criei também um estilo meia-boca TextMate-like. Não se esqueça de

<link href="http://yoursite.com/mate.css" rel="stylesheet" type="text/css" media="all" />

ActiveRecord ParseLine no GitHub

ParseLine no GitHub.

Versão em Português aqui

RGhost no Github

Depois de muita enrolação, configuração e formatação acabo de colocar o RGhost no Github, vou manter o código lá e as gems continuarão no Ruby Forge pois no Github não está funcionando direito.

Criei umas 40 páginas de wiki(em inglês) e prometo(juro) que vou colocar mais exemplos.

Vou tentar migrar o RGhost Barcodes ainda este ano(eu acho).

Gostaria de agradecer a toda comunidade nacional e internacional que colaboram dando dicas e reportando bugs. Obrigado a vcs!

Para arquivos offline use a gem Parseline

Parsear um arquivo texto em Ruby é algo fácil, persistir os dados no banco com Rails é trivial.
Vou demostrar como carregar arquivos csv e arquivos com layout largura fixa no braço, e mais a frente a nova gem Parseline.

Caso 1: Largura fixa

Suponhamos que seja necessário carregar dados de produtos de um arquivo denominado “data.txt” com o conteúdo

000001PRODUTO 1       S 21/11/2008000090.00
000002PRODUTO 2       N 22/11/2008000341.33
000003PRODUTO 3       N 01/11/2008000001.99
000004PRODUTO 4       S 15/11/2008000034.98
000005PRODUTO 5       N 14/11/2008000130.44
000006PRODUTO 6       S 05/11/2008000020.11

sendo o layout definido dessa forma:
- posição 0 até 5 = código do produto 00221
- posiçao 6 até 21 = nome do produto
- posição 22 = ‘S’ se tem em estoque e ‘N’ não tem
- posição 23 = reservado para uso futuro
- posição 24 até 33 = a data do cadastro
- posição 34 até 42 = preço do produto

Nossa tabela/model será Product definida por

class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.integer  :code
      t.string  :name
      t.boolean :in_stock
      t.date    :date
      t.float   :price
    end
  end

  def self.down
    drop_table :products
  end
end

Vamos percorrer cada linha do arquivo fazendo parser dos campos, como descrito no layout acima

File.readlines('data.txt').each do |line|
  line.strip! #retirando caracteres não imprimiveis
  #definindo os campos
  code    = line[0..5]
  name    = line[6..21].strip
  in_stock   = line[22..22]
  nothing = line[23..23]
  date    = line[24..33]
  price   = line[34..42]
  #trantando os dados
  in_stock=(in_stock=='S') #=> true se 'S', false se 'N'
  date=date.split(/\//).reverse.join('-') #=> formata data para '2008-11-05'

  #attribuindo os valores no AR
  product=Product.new :code => code,
                      :name => name,
                      :in_stock => in_stock,
                      :date => date,
                      :price => price
  product.save # salvando :)                     

end

Pronto, tá lá no banco.

Caso 2: Arquivos CSV

Arquivos delimitados por um caracter geralmente , ou ;
Esse será o nosso arquivo “data.csv” com o conteúdo

1;PRODUTO 1;S;;21/11/2008;90.00
2;PRODUTO 2;N;;22/11/2008;341.33
3;PRODUTO 3;N;;01/11/2008;1.99
4;PRODUTO 4;S;;15/11/2008;34.98
5;PRODUTO 5;N;;14/11/2008;130.44
6;PRODUTO 6;S;;05/11/2008;20.11

temos o layout para cada linha

código do produto;nome;se tem em estoque;*reservado*;data;preço

Utilizaremos a mesma migration CreateProducts. Vamos ao código

File.readlines("data.csv").each do |line|
  #definindo os campos
  code,name,in_stock,nothing,date,price = line.strip.split(';')

  #trantando 
  in_stock=(in_stock=='S') #true se 'S', false se 'N'
  date=date.split(/\//).reverse.join('-') #formata data para '2008-11-05'

  #atribuindo os valores
  product=Product.new :code => code,
                      :name => name,
                      :in_stock => in_stock,
                      :date => date,
                      :price => price

  product.save                      

end

Nova gem ParseLine

O que ela faz? Nos ajuda a carregar dados externos de arquivos offline de uma forma mais elegante.
Suporta CSV ou largura fixa.

Funcionamento

Basta extender o módulo ParseLine::CSV ou ParseLine::FixedWidth e definir o layout.

Caso 1: Largura fixa

Utilizaremos o módulo ParseLine::FixedWidth com o arquivo “data.txt”, a sintáxe é

  parse.field :nome_do_campo, intervalo, lambda{|campo| fomatador}

Olha como é simples

require 'parseline'

class Product < ActiveRecord::Base
  extend ParseLine::FixedWidth
  fixed_width_layout do |parse|
    parse.field :code , 0..5
    parse.field :name,  6..21
    parse.field :in_stock, 22..22, lambda {|f| f == 'S' }
    parse.field :date , 24..33,    lambda {|d| d.split(/\//).reverse.join('-') }
    parse.field :price, 34..42
  end
end

então posso carregar apenas uma linha

dados=File.readlines("data.txt")
@product=Product.load_line dados[0]
@product.save
#<Product id: nil, code: "1", name: "PRODUTO 1", in_stock: false, date: "2008-11-21", price: 90.0>

ou carregar automáticamente todo arquivo em um array de Product

@products=Product.load_lines "data.txt"

conteúdo de @products

[
#<Product id: 29, code: "1", name: "PRODUTO 1", in_stock: true, date: "2008-11-21", price: 90.0>,
#<Product id: 30, code: "2", name: "PRODUTO 2", in_stock: false, date: "2008-11-22", price: 341.33>,
#<Product id: 31, code: "3", name: "PRODUTO 3", in_stock: false, date: "2008-11-01", price: 1.99>,
#<Product id: 32, code: "4", name: "PRODUTO 4", in_stock: true, date: "2008-11-15", price: 34.98>,
#<Product id: 33, code: "5", name: "PRODUTO 5", in_stock: false, date: "2008-11-14", price: 130.44>,
#<Product id: 34, code: "6", name: "PRODUTO 6", in_stock: true, date: "2008-11-05", price: 20.11>
]


Caso 2: Arquivos CSV

Utilizaremos o módulo ParseLine::CSV com o arquivo “data.csv”, a sintáxe é

  parse.field :nome_do_campo, lambda{|campo| fomatador}

para ignorar um campo como aquele “reservado para uso futuro” basta invocar o método ignore_field

Veja

class Product < ActiveRecord::Base
  extend ParseLine::CSV
  csv_layout :delimiter => ";" do |parse|
    parse.field :code
    parse.field :name
    parse.ignore_field
    parse.field :in_stock, lambda {|f| f == 'S' }
    parse.field :date ,    lambda {|d| d.split(/\//).reverse.join('-') }
    parse.field :price
  end
end

O ParseLine::CSV também tem os métodos Model.load_line e Model.load_lines.
Então temos para uma linha de dados

dados=File.readlines("data.csv")
@product=Product.load_line dados[0]
@product.save
#<Product id: nil, code: "1", name: "PRODUTO 1", in_stock: false, date: "2008-11-21", price: 90.0>

Ou carregar tudo de um array

@products=Product.load_lines "data.txt"


Instalação

#rubyforge
sudo gem install parseline

Se ainda não estiver disponível baixe aqui
Espero que gostem.

ps. em breve no GitHub em inglês