Tradutor simples Inglês/Português e Português/Inglês

Sempre usei os bots do Google para o gtalk, mas percebi que os resultados que eles retornam são bem diferentes da página de tradução.

Então fiz uma página bem simples que usa a Language API do Google para traduzir textos do Inglês para o Português e do Português para o Inglês, sem todas aquelas opções de linguas que a página deles oferece.

Para você que tem interesse em saber como funciona traduzir textos com a Language API do Google, veja como é fácil:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>

e depois

google.load("language", "1");

google.language.translate("texto que eu quero traduzir", "pt", "en", function(result) {
  // aqui você faz o que quiser com o resultado
});

shoes-translator atualizado Ruby, Shoes e Google Translate API

Há tempos atrás desenvolvi uma pequena aplicação usando Shoes, e ontem resolvi atualizá-la, mudei um pouco a aparência e melhorei o suporte a pronúncia.

Caso tenha interesse em usar, você pode baixar o projeto do github: http://github.com/rafaelss/shoes-translator

Falando um pouco agora sobre o Shoes, me parece que após o sumiço do _why a coisas não vão tão bem, o projeto amadureceu muito pouco, muita coisa básica ainda é complicado de se fazer, impedindo um pouco que aplicações mais profissionais sejam feitas rodando sobre o framework.

Quando desenvolvi o shoes-translator na primeira vez, eu levava mais fé no projeto, acreditava que seria um concorrente de peso para os toolkits atuais, mas agora, voltando a mexer na código e buscando referências na internet para fazer as alterações, percebi que o Shoes ainda precisa de muito, mas muito trabalho para poder ter crédito suficiente e ser usado para fazer software de verdade.

UPDATE: O @kbmurata postou no twitter que o objetivo do Shoes é ser usado para o aprendizado de forma divertida, de qualquer forma, se você quiser começar um projeto usando Shoes, pense bem que tipo de projeto você está desenvolvendo, não pense em nada muito maior que um "tradutor de sapatos"


Compilando o Passenger sem espaço no /tmp

De ontem pra hoje perdi um bom tempo tentando compilar um passenger mais novo em um servidor que tem um /tmp de apenas 1MB (eu ainda preciso descobrir porque isso).

A solução é simples até, basta setar a var TMPDIR com o path de um outro diretório qualquer, mais ou menos assim:

sudo TMPDIR=/home/rafaelss/tmp passenger-install-apache2-module

Detalhe: eu estava acostumado a setar variáveis ao executar um comando colocando ela na frente do comando, mas com o sudo isso não funciona. No help do sudo diz que deve ficar ali no meio

usage: sudo [-bEHPS] [-p prompt] [-u username|#uid] [VAR=value] {-i | -s | }

Hora Extra em Porto Alegre

O Tailor lançou a idéia no twitter e eu apoiei, então, semana que vem, #horaextra na Cidade Baixa, em Porto Alegre, mais exatamente no Copão

A idéia é juntar um monte (ou não) de nerds pra falar de trabalho, tecnologia, frameworks, programação, enfim, tudo o que a gente mais gosta

Então, segunda-feira, 19:30, Copão. Aparece lá!


ASP.NET MVC e suas ActionResult

O framework MVC da Microsoft usa um determinado objeto para definir qual tipo de resultado/output a action executada deve retornar. São eles:

  • ContentResult - Pode ser usado para retornar textos simples.
  • EmptyResult - Esse serve para retornar resultados em branco, quando quiser que o output seja vazio.
  • HttpUnauthorizedResult - Usado quando o usuário não tem permissão para executar a action. Retorna o 401 como status da requisição.
  • JsonResult - Serializa um objeto em formato JSON, bom para ser usando em requisições AJAX.
  • RedirectResult - Resultado usado para redirecionamentos.
  • RedirectToRouteResult - Também usado para redirecionamentos, mas a URL está ligada a uma rota.
  • ViewResultBase - Classe abstrata, usada para renderizar HTMLs.
    • PartialViewResult - Estende ViewResultBase para renderizar as views e seus HTMLs.
  • BinaryResult - Classe abstrata usada para resultados binários.
    • BinaryStreamResult - Estende BinaryResult, pode ser usado para escrever imagens direto no stream do resutado.

Porém, em alguns casos, retornar um texto simples, ou um JSON pequeninho, é meio chato. Considere o código abaixo:

JsonResult json = new JsonResult();
json.ContentType = "text/javascript";
json.Data = new { success = true };
return json;

Isso poderia ser mais simples não? Porém, a classe JsonResult, e nenhuma outra ActionResult aceita parâmetros no construtor. Por isso criei duas classes que podem ser usadas como ActionResult, para simplificar essa tarefa. Elas devem ser usadas assim:

return new SimpleResult("Hello World");
return new SimpleResult(1);
return new SimpleResult(1257.14);
return new SimpleResult(true);

e

return new SimpleJsonResult(new { success = true });

Pronto, agora é hora de refatorar código. :)

UPDATE: Conforme o Guilherme comentou ali embaixo, o ASP.NET MVC tem um método que já simplifica as coisas.

return Json("Hello World");
return Json(1);
return Json(1257.14);
return Json(true);

e

return Json(new { success = true });

jQuery, Safari e CSS Selectors

Hoje estava verificando um bug em um projeto, que acontecia somente no Safari, tanto no MacOS, quanto no Windows, e descobri que o problema era a forma como eu estava definindo o elemento HTML envolvido na história.

O expressão que eu estava usando era a seguinte:

$("#meuform input[type='hidden'][value='']").length

No Safari sempre me retornava 0, já no Firefox e Internet Explorer, retorna 1, que era para ser o valor certo no caso. Analisando como o input estava definido eu descobri o problema, ele estava definido assim:

<input type="hidden" name="first_user" />

Resumindo:

O Safari não acha elementos onde o atributo filtrado não esteja presente no HTML. (Estou usando a versão 1.3.2 do jQuery e 4.0 (503.17) do Safari, no Windows, mas reportaram o problema no Mac também)


C# e códigos deprecated

Você desenvolve uma biblioteca de utilitários para facilitar a vida dos outros desenvolvedores da empresa, porém algumas vezes é necessário refatorar códigos, criando/renomeando/apagando alguns métodos. Obviamente você não pode sair mudando tudo, existe código "antigo" usando a sua "lib".

Existe um atributo no C# que permite que você marque código como deprecated, é o Obsolete, muito útil e fácil de usar.

[Obsolete("Use o método MinhaClasse.MeuMetodo(int parametro)")]
public static void MeuMetodo(string parametro) {
    // ...
}

No exemplo acima quero que os desenvolvedores usem a versão que recebe um integer como parâmetro, e não mais a versão com string.

Você ainda pode dizer que é para o compilador gerar um erro ao compilar o código, passando true como segundo parâmetro do atributo.

[Obsolete("Este método não deve mais ser usado. Usar MinhaClasse.MeuMetodo(int parametro)", true)]
public static void MeuMetodo(string parametro) {
    // ...
}

Permissão para o Apache na pasta home

Muitas vezes quando configuramos um servidor para hospedar sites para diferentes usuários, a primeira coisa que pensamos é em colocar os sites de cada usuário na pasta home do mesmo, mas para isso funcionar corretamente precisamos dar permissão para o Apache ler a home de cada usuário. A solução que tenho usado é dar a seguinte permissão na pasta do usuário

chmod a+x /home/nome_do_usuario/

Depois disso todos os "forbidden" desaparecem :)


Instalando o RMagick no Ubuntu

Se você estiver com problemas para instalar o RMagick no Ubuntu usando apt-get talvez essa solução possa ajudar. Primeiro, limpe os pacotes com "problemas":

sudo apt-get remove --purge librmagick-ruby-doc librmagick-ruby1.8

depois instale os seguintes pacotes:

sudo apt-get install libmagick9-dev ruby1.8-dev

depois disso é só instalar a gem:

sudo gem install rmagick

dica retirada daqui


PHP e SQL Server 2005

Se você tem problemas de conexão com SQL Server 2005 pelo PHP, tente usar essa versão (2000.80.194.0) da ntwdblib. Coloque esse arquivo na raiz da instalação do seu PHP, substituindo a versão existente, e reinicie o servidor web.


Nome da distro Linux usada

Uma coisa que eu sempre precisava e nunca me lembrava como fazer era descobrir qual a distro que eu estava usando no momento, como muitas vezes precisei mexer com os mais variados servidores, algumas vezes precisava dessa informação, e hoje achei o jeito mais fácil de fazer isso

cat /etc/issue

No meu micro aparece

Arch Linux \r  (\n) (\l)

No do meu colega

Ubuntu 8.10 \n \l

Achei essa dica aqui e estou documentando aqui pra não esquecer mais :)


Usando uma única instância do Vim

Hoje quando li o feed de comentários do blog do TaQ (re)apareceu uma dica que ele deu há um bom tempo, sobre usar uma única instância do Vim para editar arquivos, acho muito chato ter que abrir muitos editores.

Porém a dica que ele deu não funcionou para mim, apenas esta dos comentários, que ao invés de usar um alias, usa uma função.

# http://www.cyberciti.biz/faq/linux-unix-pass-argument-to-alias-command/
function edit() {
    gvim --servername `gvim --serverlist | head -1` --remote-tab "$@";
}

Eu mudei o nome para edit, acho mais fácil, mas fica a critério de cada um :)

Link do codigo original: http://pastebin.com/f7a69dcd7


bash history meme

Vi no blog do Luiz Rocha hoje um meme que rolou há um bom tempo atrás e resolvi fazer também.

[rafael ~]$ history 1000 | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
156 git
101 sudo
86 cd
75 yaourt
58 grep
52 gvim
48 exit
39 braid
36 ll
33 rake

Minha única surpresa foi o braid, considerando que conheci ele faz uma semana e que só utilizo ele em um projeto.


Usando Python e Google App Engine

UPDATE: O controle de versão do GAE não é muito "esperto", acabei mudando de micro e perdi tudo. Então, o site não existe mais.

No começo do mês recebi a liberação para usar o Google App Engine, foi o que faltava para eu dar uma brincada com Python.

Onde trabalho, toda a tarde rola de alguém ir no mercado comprar uns refrigerantes, mas todo dia era uma "briga" para ver quem ia. Para resolver isso, criamos página simples em PHP que sorteava quem naquele dia ia fazer as compras.

Depois que a minha conta foi liberada, fiquei um bom tempo pensando o que eu poderia fazer para usá-la, e então o Joel deu a idéia, fazer aquela "págininha" em Python e disponibilizar no Google App Engine.

http://eoescolhidofoi.appspot.com/

É simplesmente fantástica a facilidade de se criar uma aplicação e fazer o deploy dela no Google App Engine, o fato de não ter que se preocupar com banco de dados influencia bastante, basta definir modelos no próprio código, pensar apenas em objetos.

Depois dessa primeira eu já criei mais duas, uma está pronta, mas estou testando ainda, a outra está a caminho, mas será para a empresa que trabalho.


Github theme para o Vim

Depois de uma busca insana por um editor de texto acabei escolhendo o Vim, estou usando ele direto faz uma semana e estou me adaptando bem, apesar de algumas coisas me deixarem meio perdido (teclas de atalho principalmente).

Eu estava usando o Vim no console, com um tema com fundo escuro, e como estou usando o computador em um lugar muito claro, o reflexo que a minha tela emite fazia com que eu forçasse muito a visão para enxergar o código. Foi então que eu achei isto, um tema usando as cores do Github, instalei e ficou muito bom!

Um detalhe apenas é que a cor do fundo não é a mesma, nos comentários o Felipe Contreras dá a cor certa. Como não achei nenhum fork com a correção, eu mesmo o fiz.

Se você achar que alguma outra cor não está correta, você sabe, fork e pull request :)


Rails Summit, eu fui!

Eu sei, eu sei, Rails Summit já foi faz tempo, mas só agora consegui postar alguma coisa aqui no blog.

O evento estava muito bom, muito motivador, palestras como a do Obie Fernandez, do Vinícius Teles e do Chad Fowler me fizeram mudar alguns aspectos na minha vida profissional (motivo pelo qual esse blog ficou um pouco abandonado), estou focando mais em desenvolver alguma coisa do que simplesmente assistir a tudo de braços cruzados. Gmail só o essencial e Google Reader e Twitter são raramente abertos em casa.

No momento networking do evento, reencontrei o Jony e o Tailor, que tinha conhecido no FISL, e conheci mais uma galera legal lá, citando alguns: Júlio Monteiro, Henry Hamon, Evandro Dutra, Rafael Lima, Henrique Bastos, Thiago Pradi, Davis Cabral e mais alguns outros que não me lembro o nome.

Enfim, espero que o ano que vem tenhamos outro evento neste mesmo nível (ou até melhor), que com certeza eu estarei lá.


nginx: Redirecionando de um domínio para outro

Semana passada eu resolvi mudar o domínio do blog, usar algo mais pessoal, e acabei escolhendo http://rafaelss.com, mais simples, mais curto, tem meu nome, enfim, muito melhor :)

Mas com isso veio a necessidade de redirecionar do domínio antigo, http://www.joeh.com.br, para o novo.

Isso é muito fácil.

server {
    listen 80;
    server_name joeh.com.br  *.joeh.com.br;
    rewrite ^/(.*) http://rafaelss.com/$1 permanent;
}

Com isso todos os links que apontam para o domínio velho são redirecionados para o novo, com o permanent ali as buscas se entendem, a indexação não é afetada, e tudo continua funcionando normalmente como era antes.


Solução simples para um problema simples

É impressionante como alguns desenvolvedores muitas vezes não procuram uma forma mais simples de fazer certas tarefas do dia-a-dia, um exemplo clássico: Deixar apenas números em uma string, nesse caso, o número de uma agência bancária.

Primeiro a forma que vejo normalmente (em C#)

string agency = plan.Agency.Replace("-", "");
agency = agency.Replace(".", "");
agency = agency.Replace("/", "");
agency = agency.Replace("", "");

Forma simplificada (C# também)

Regex.Replace(plan.Agency, "[^0-9]+", "");

Não é muito mais simples? Basta procurar! ;)


Desabilitando validadores do .NET com Javascript

Mexendo com .NET hoje (eu sei, mas faz parte) tive que descobrir como desabilitar uns validadores com Javascript, e a resposta é bem simples:

var myVal = document.getElementById("&lt;%= myValidator.ClientID %&gt;");
ValidatorEnable(myVal, false);

Tirado daqui: http://geekswithblogs.net/jonasb/archive/2006/08/11/87708.aspx


Codificando e decodificando strings com HTML Entities

HTML Entities é uma gem para Ruby que serve para codificar e decodificar html entities.

sudo gem install htmlentities

Para codificar uma string usamos

require "rubygems"
require "htmlentities"

he = HTMLEntities.new
encoded = he.encode("essa gem é uma mão na roda!", :named)
puts encoded # essa gem é uma mão na roda!

e para decodificar

require "rubygems"
require "htmlentities"

he = HTMLEntities.new
decoded = he.decode("essa gem é uma mão na roda!")
puts decoded # essa gem é uma mão na roda!

Aplicação usando Shoes

Criei ontem de noite um aplicação de teste para traduzir palavras/frases usando Ruby, Shoes e Google AJAX Language API, ela é bem simples, não tem nada que não foi feito por aí, mas futuramente vou colocar a opção de salvar outras palavras/frases em um banco de dados local, usando SQLite provavelmente, já que estou reforçando meus estudos em inglês, acho que isto vai me ajudar bastante ;)

Mas nem tudo são flores nessa vida de programador, passei um trabalhinho para poder rodar o Shoes com as gems que eu usei, ele não funciona com gems instaladas usando gem install, por que ele tem uma espécie de "interpretador" próprio ou coisa parecida. Depois de instalar o Shoes tive que colocar as gems (json, rest-client) e a lib rexml dentro da Shoes-land - como vi uns chamando por ai.

Fiz um passo a passo de como rodar. Isso também serve para outras apps feitas usando Shoes que você queira rodar, não apenas para este projeto.

Copie as gems/libs - verifique antes se os diretórios são os mesmos

json - usei json_pure por que a outra é nativa, então não sei se funcionaria

sudo cp -R /usr/lib/ruby/gems/1.8/gems/json_pure-1.1.2/lib/json* /usr/local/lib/shoes/ruby/lib/

rest-client

sudo cp /usr/lib/ruby/gems/1.8/gems/rest-client-0.5.1/lib/* /usr/local/lib/shoes/ruby/lib/

rexml

sudo cp -R /usr/lib/ruby/1.8/rexml /usr/local/lib/shoes/ruby/lib/

Feito isso, clone o projeto

git clone git://github.com/rafaelss/shoes-translator.git

e quando terminar execute

cd shoes-translator
shoes translator.rb

PDO: bindParam ou bindValue?

Programando hoje uma validação para o framework que estou desenvolvendo me deparei com um problema usando variáveis em SQL, mais especificamente usando variáveis com o PDO.

Escrevendo os testes unitários para essas validações notei que precisava mudar a forma como passava os parâmetros para a SQL, ao invés de passar no execute, precisaria passar usando uma função própria para isso.

Lendo o manual, achei três opções de bind, bindColumn, bindParam e bindValue, depois de ler a documentação, optei pela bindParam, pois bindColumn é usado para atribuir o resultado para uma variável diretamente e bindColumn… eu só fui ver depois :P

Meus testes já estavam prontos e passando corretamente, mas quando fiz a mudança começou a não passar mais, então comecei a debugar para ver o que estava acontecendo. Depois de horas perdidas descobri o problema, não posso usar bindParam, tenho que usar bindValue.

O método bindParam recebe o valor do parâmetro por referência, então se o valor da variável mudar entre o chamada de bindParam e execute, o valor do parâmetro muda, alterando o resultado da SQL, coloquei bindValue e tudo voltou ao normal, com os testes passando novamente. Mas o que me deixa intrigado é que o meu código não mudava nada na variável, não tinha nada entre os métodos que pudesse fazer com o o resultado fosse diferente.

Mas fica a lição, ler a documentação melhor da próxima vez ;)



powered by jekyll. icons by noop.nl