Mais uma mudança de endereço…

May 11th, 2008

A partir de agora, todos os posts do Googletron serão publicados no seu irmão gêmeo, o hervalicio.us. Para acompanhar somente os posts em português, basta ir na categoria “Posts em Português

see you there!

Lendo arquivos PDF, XLS e DOC no iPhone

October 5th, 2007

Enquanto ninguém inventa por aí um programinha capaz de ler documentos no iPhone, aqui vai um hack bem rápido que permite carregar e ler documentos no seu aparelhinho.
Caso você não tenha percebido ainda (eu mesmo só descobri isso ontem, ao clicar por acidente em um link para um PDF), o SafariMobile (a versão do Safari que vem no iPhone) é capaz de abrir e visualizar arquivos PDF, DOC, TXT - e até mesmo planilhas XLS - muito bem. E já que o Safari o mecanismo de rotação de tela, ler documentos longos na telinha fica ainda mais fácil. Aqui vai a receita rápida para esse “truque”:

- Antes de mais nada, é necessário que seu iPhone esteja desbloqueado. Não vamos entrar no mérito do desbloqueio neste artigo, já que existe uma centena de tutoriais por aí que detalham bem o processo de desbloqueio.

- Uma vez que o seu iPhone esteja desbloqueado (”jailbroke”), instale o programinha installer.app nele.
utilizando o (using iBrickr, no caso do Windows, ou o iFuntastic, no Mac. O Installer.app é uma aplicaçãozinha bastante útil
que localiza e instala outras aplicações de terceiros (um mecanismo bastante parecido com o Synaptics, para quem está acostumado com o Ubuntu).

Installer

- Agora que você já tem o installer.app rodando, clique no ícone “Installer” e procure por lighttpd (na sessão “Network”). Clique e instale.

DSCF0213

Uma vez que o lighttpd tenha sido instalado, abra o Safari e digite “http://localhost” na barra de endereço.

Your web server to go, baby!

Parabéns, agora você está rodando um servidor web completo… dentro do seu aparelhinho! ;-)

- E agora, o toque final. Utilizando o iBrickr (ou qualquer outro gerenciador de arquivos), procure pelo diretório /var/root/Sites/ e apague o arquivo index.html. Este arquivo é o mesmo que é exibido no browser quando você navega para http://localhost
Agora, para permitir a listagem do conteúdo do diretório /Sites/, navegue no iBrickr até o arquivo /usr/local/etc/lighttpd.conf e faça o download do arquivo para sua máquina. Edite o arquivo (no bloco de notas mesmo) e adicione a seguinte linha no começo (ou no fim) do arquivo:

dir-listing.activate = "enable"

Salve e faça o upload do arquivo novamente para o iPhone, sobrescrevendo o original. Reinicie o telefone para que o lighttpd recarregue as suas configurações, e aponte o Safari para “http://localhost” novamente. Agora você será capaz de ver o conteúdo do diretório /var/root/Media/Sites .

O último passo é provavelmente óbvio: utilizando o iBrickr, localize os documentos que você deseja carregar no iPhone e faça upload deles para o diretório Sites. Faça um reload da página no Safari, e os seus documentos aparecerão. Para ler, basta clicar em qualquer um dos arquivos.

Ruby on iPhone

Agora se me dão licença, tenho um e-book para ler na minha telinha… ;-)

“Mac Sucks” - propaganda fake

September 21st, 2007


A verdade às vezes é cruel… Especialmente para os “seguidores sem cérebro” de qualquer crença/tecnologia, como dá pra ver nos comentários do vídeo.

Singletons no Rails

August 26th, 2007

Se você já precisou alguma vez utilizar objetos singleton em seu projeto Rails, você deve ter percebido que os Singletons não são exatamente… Singletons. Suponha que você crie a seguinte classe em seu diretório /app/model:

[source:ruby]
class MySillySingleton
include Singleton
end
[/source]

SEMPRE que um novo request for feito, uma nova instância da classe será retornada:
[source:ruby]
puts MySillySingleton.instance
=> #
[/source]

E no próximo request:
[source:ruby]
puts MySillySingleton.instance
=> #
[/source]

Este tipo de recarga automática de objetos não acontecerá, entretanto, se você colocar a sua classe no diretório /lib do projeto.
É importante lembrar que este comportamento só acontece quando se roda o Webrick ou Mongrel em modo development, onde todo o conteúdo de /app é recarregado a cada request. Fique ligado!

yahoo-finance: uma RubyGem minimalista para download de dados financeiros do Yahoo! Finance

August 4th, 2007

O yahoo-finance é o meu primeiro RubyGem publicado: trata-se de uma ferramentinha muito, muito simples, que foi desenvolvida enquanto montava o site CanalFinancas para download de preços de ações em tempo real. Depois de tudo pronto, por que não tornar essa belezinha pública? E cá está ela!
O uso é simples:

[source:ruby]
gem install yahoo-finance
[/source]

E a partir daí:
[source:ruby]
require ‘yahoo_finance’

quotes = Yahoo::Finance.quotes(["VALE5.SA"], [:last_trade_price_only, :trade_date])
puts “#{quotes[0].symbol}: #{quotes[0].last_trade_price_only} em #{quotes[0].trade_date}”
[/source]

Não poderia ser mais fácil… :-)

Rigg

July 11th, 2007

O Projeto Rigg acaba de ser disponibilizado em código aberto - e precisa de desenvolvedores. Rigg é uma aplicação Rails que permite a construção rápida de sites de notícias colaborativas como Digg.com, DZone.com e Reddit.com.
A versão inicial ainda tem um bom número de pontas soltas, mas uma versão alfa deverá ser lançada dentro de alguns dias. O código fonte, no entanto, já está disponível na página do projeto.

User expected, got User?

July 7th, 2007

Sem dúvida uma das mensagens mais irritantes que já tive o desprazer de encontrar nas andanças pelo Rails, a infame “User expected, got User” tende a aparecer, quando se utilizam plugins como o acts_as_commentable ou o acts_as_taggable, que definem Models dentro do diretório vendor/plugins.
A solução, como apontado pelo blog localhost:3000 blog (belo nome para um blog, diga-se de passagem ;)), é simples (apesar de meio “xunxo”): basta mover os models do plugin para o diretório apps/models de sua aplicação. A razão por trás do problema é que as libs (e o conteúdo do diretório vendor) não são carregadas a cada request, quando utilizando o modo “development”, diferentemente de todo o conteúdo do /app . Teoricamente, definir models dentro de plugins é uma má pratica, e deve ser evitado. Vale notar que o problema não acontece em modo production, onde os models não são recarregados o tempo todo.
Existe ainda uma maneira menos intrusiva de adicionar os plugins ao ‘reloadable path’, fazendo com que eles sejam recarregados junto da aplicação, conforme explicado neste link:

[source:ruby]
# Array of plugins with Application model dependencies.
reloadable_plugins = ["acts_as_commentable"]
# Force these plugins to reload, avoiding stale object references.
reloadable_plugins.each do |plugin_name|
reloadable_path = RAILS_ROOT + “/vendor/plugins/#{plugin_name}/lib”
Dependencies.load_once_paths.delete(reloadable_path)
end
[/source]

API Rails - agora em Ajax!

June 10th, 2007

Ta aí um site “Ajax powered” bastante útil: para quem precisa da documentação do Ruby on Rails sempre a mão, um prato cheio.
Em tempo: O GotApi também é um prato cheio - e ainda tem documentação de muitas outras coisas, de SQL a CSS. Bookmark obrigatório!

Cacheando comentários com acts_as_commentable

May 13th, 2007

Enquanto os criadores do acts_as_commentable não lançam uma nova versão do plugin com suporte a counter_caches, aqui vai um pequeno truque para utilizar contadores nas suas classes commentable. Basta adicionar dois métodos no comment.rb:

comments.rb
[source:ruby]
def after_create
if commentable.attributes['comments_count']
commentable.increment!(”comments_count”)
end
end

def before_destroy
if commentable.attributes['comments_count']
commentable.class.decrement_counter(”comments_count”, commentable.id)
end
end
[/source]

Lembre-se que você precisará ter um campo ‘comments_count’ nas tabelas em que quiser que o cache seja mantido (as tabelas das classes que declaram acts_as_commentable).

Traduzindo as mensagens do time_ago_in_words

May 11th, 2007

Enquanto o Rails não suporta nenhum tipo de internacionalização, aqui vai uma pequena dica para internacionalizar o método time_ago_in_words (e todos os outros métodos do DateHelper que imprimem mensagens como “12 hours”, ou “less than 1 minute” (se seu site não exibe datas desse jeito, você não tem o direito de dizer que ele é um site Web 2.0! ;)). O hack é simples: basta redefinir o método distance_of_time_in_words no módulo ActionView::Helpers::DateHelper (o coração de todos os métodos date-to-words). No meu caso:

[source:ruby]
module ActionView
module Helpers
module DateHelper

def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
distance_in_minutes = (((to_time - from_time).abs)/60).round
distance_in_seconds = ((to_time - from_time).abs).round

case distance_in_minutes
when 0..1
return (distance_in_minutes == 0) ? ‘menos de um minuto’ : ‘1 minuto’ unless include_seconds
case distance_in_seconds
when 0..4 then ‘menos de 5 segundos’
when 5..9 then ‘menos de 10 segundos’
when 10..19 then ‘menos de 20 segundos’
when 20..59 then ‘menos de um minuto’
else ‘1 minuto’
end

when 2..44 then “#{distance_in_minutes} minutos”
when 45..89 then ‘aproximadamente 1 hora’
when 90..1439 then “aproximadamente #{(distance_in_minutes.to_f / 60.0).round} horas”
when 1440..2879 then ‘1 dia’
when 2880..43199 then “#{(distance_in_minutes / 1440).round} dias”
when 43200..86399 then ‘aproximadamente 1 mês’
when 86400..525959 then “#{(distance_in_minutes / 43200).round} meses”
when 525960..1051919 then ‘aproximadamente 1 ano’
else “mais de #{(distance_in_minutes / 525960).round} anos”
end
end
end
end
[/source]

Feito isso, basta salvar seu helper no diretório /lib/ da aplicação, e importá-lo no final do environment.rb:

[source:ruby]
require ‘my_hackery_stuff’
[/source]

E pronto! A mesma lógica pode ser utilizada para sobrescrever qualquer comportamento do Rails (não recomendado na maioria dos casos!). Você pode até mesmo utilizar algum plugin de i18n com seu novo código que sobrescreve o método e exibir suas mensagens em qualquer idioma!
Caso você seja o tipo de programador que gosta de entender as coisas que está fazendo, esta página explica em detalhes o processo de inicialização do Rails. ;)