Arquivo para março \26\UTC 2008

Como abrir arquivos OpenXML no OpenOffice

Post movido para: http://blog.guilhermegarnier.com/2008/03/26/como-abrir-arquivos-openxml-no-openoffice/

Na versão 2007, o Microsoft Office começou a usar o formato OpenXML como padrão – no caso do Word, a extensão deste formato é docx. Porém, este formato é incompatível com o OpenOffice (e com versões anteriores do Word…). Para abrir arquivos deste formato no OpenOffice, instale o odf-converter. Após instalá-lo, reinicie o OpenOffice e você conseguirá abrir e salvar nesse formato. O pacote deb pode ser acessado aqui. Instalei este pacote sem problemas no Ubuntu com OpenOffice 2.3, apesar dos comentários nessa página de download.

Referência:

Anúncios

Procurando falhas de segurança com o Google

Post movido para: http://blog.guilhermegarnier.com/2008/03/26/procurando-falhas-de-seguranca-com-o-googl/

O blog Penguim’s Place publicou um excelente artigo em 3 partes, apresentando várias técnicas para procurar falhas de segurança em servidores web utilizando apenas o Google para isso. São técnicas muito interessantes, como buscar servidores com a página inicial padrão do Apache (o que pode indicar que ele foi mal configurado) e procurar por falhas específicas em banco de dados. Na parte final são apresentadas técnicas de defesa.

Como montar diretórios remotos via ssh

Post movido para: http://blog.guilhermegarnier.com/2008/03/24/como-montar-diretorios-remotos-via-ssh/

O sshfs é um comando muito útil para quem precisa acessar servidores (ou máquinas virtuais) remotos. Com este comando, em vez de precisarmos executar o ssh para logarmos ou o scp para copiarmos arquivos entre o desktop e os servidores, podemos montar localmente um diretório remoto.

Para instalar esse pacote no Ubuntu, basta executar o comando sudo apt-get install sshfs. Em seguida, adicione seu login ao grupo fuse:

sudo usermod -a -G fuse login

Apenas usuários deste grupo terão permissão para montar e desmontar diretórios. Para montar um diretório remoto:

sudo sshfs user@server:/usr/local/test ./server-test

O comando acima mapeia o diretório /usr/local/test do servidor server no diretório local ./server-test, como usuário remoto user. Há uma série de parâmetros opcionais, como forçar sincronização e cache. Verifique o man do comando para mais detalhes.

Para desmontar o diretório, basta executar:

fusermount -u ./server-test

Referência:

Configurações fora do padrão em Rails

Post movido para: http://blog.guilhermegarnier.com/2008/03/18/configuracoes-fora-do-padrao-em-rails/

O framework Rails é excelente na tarefa de automatizar o máximo possível o desenvolvimento de aplicações web. Todos os detalhes que podem ser implementados automaticamente são abstraídos do desenvolvedor, facilitando e agilizando muito o trabalho.

Porém, toda essa automatização e abstração de detalhes internos tem um custo, que é a padronização. Por exemplo, ao usar o script generate para criar um model, o Rails cria uma classe derivada de ActiveRecord::Base. Os nomes do arquivo, da classe e da tabela são automaticamente gerados a partir do parâmetro passado. Ex:

ruby script/generate model tipo_usuario

Arquivo: tipo_usuario.rb

Classe: TipoUsuario

Tabela: tipo_usuarios

Neste caso, a partir do parâmetro passado para o script, o nome do arquivo é o próprio parâmetro com “.rb” no final, o nome da classe é gerado retirando-se os “_” e colocando a primeira letra de cada palavra em maiúscula, e o nome da tabela é o plural – que pode ser redefinido no arquivo config/initializers/inflections.rb:

Inflector.inflections do |inflect|
  inflect.irregular 'tipo_usuario', 'tipos_usuario'
end

Com a configuração acima, o nome da tabela será tipos_usuario – desde que esta configuração seja realizada antes do generate!

O principal problema que esta padronização traz é que nem sempre queremos/podemos seguir o padrão de configuração gerado pelo Rails. Na maioria das situações, é possível definir explicitamente quando se quer usar uma configuração diferente, como no caso do plural da tabela acima. O nome da tabela associado a um model também pode ser alterado, através do método set_table_name. Desta forma, o Rails não amarra totalmente o desenvolvedor aos seus padrões.

Porém, apesar da flexibilidade, essas configurações fora dos padrões nem sempre funcionam como deveriam. Muitas vezes, ocorre algum “efeito colateral” que faz com que algum outro módulo não funcione corretamente. Conforme escrevi no post Acessando múltiplos bancos de dados em Rails, ao configurar o acesso a múltiplos bancos de dados, os unit tests pararam de funcionar. Mais uma vez, precisei passar algum tempo pesquisando no Google para encontrar uma solução.

O primeiro problema é com os fixtures. Quando o nome da tabela é diferente do model, o nome do arquivo de fixtures deve ser igual ao nome da tabela seguido por “.yml”. Nos unit tests, o símbolo passado para o método fixtures deve ter este nome. No artigo sobre acesso a múltiplos bancos de dados, citei como exemplo uma tabela usuario_tb. Neste caso, o arquivo de fixtures deveria se chamar usuario_tb.yml, e o arquivo com unit tests deveria carregar esses fixtures assim:

class UsuarioTest < ActiveSupport::TestCase
  fixtures :usuario_tb
end

Em casos onde a única configuração fora do padrão seja o nome da tabela, a configuração acima é suficiente. Porém, no caso do exemplo citado no artigo anterior, onde o model não é mapeado numa tabela local, e sim num outro banco de dados, surgem outros problemas. O primeiro é que, ao tentar executar os testes, o rake informa que a tabela não existe. A única maneira que descobri para corrigir este problema foi criar esta tabela no ambiente de desenvolvimento. Ela não é usada para nada, mas se não for criada, os testes não funcionarão.

O segundo problema com esta configuração é que não é possível carregar os fixtures da maneira descrita acima. Em vez disso, é necessário usar o método create_fixtures da classe Fixtures. Para simplificar, como podem haver mais models configurados desta maneira, fiz a seguinte configuração:

1 – criar o método set_fixtures no arquivo test/test_helper.rb:

def set_fixtures (table, base)
  return unless (table && base.kind_of?(ActiveRecord::Base))

  ActiveRecord::Base.connection = base.connection
  Fixtures.create_fixtures(File.join(RAILS_ROOT, 'test', 'fixtures'), table) { base.connection }
end

2 – criar o método setup nos unit tests, utilizando esse método para cada arquivo de fixtures que será carregado:

def setup
  set_fixtures('usuario_tb', AutenticacaoDatabase)
end

No código acima, AutenticacaoDatabase é a classe abstrata usada como base para o model Usuario.

Com essas configurações é possível realizar os testes, com um único problema: não é possível referenciar os fixtures pelos labels. Para simplificar, como ainda não descobri uma maneira de corrigir isto, eu costumo definir os labels dos fixtures como números seqüenciais, começando em 0. Assim eu posso buscar todos os dados da tabela (ex: Usuario.find(:all)) e referenciar o array pelos índices, que, neste caso, correspondem aos labels. Mas cuidado: o find(:all) não garante que o array retornado terá a mesma ordem do arquivo de fixtures. O ideal é criar fixtures com id seqüencial, e adicionar o parâmetro order ao find.

Referências:

Linguagens de programação de baixo, médio e alto nível

Post movido para: http://blog.guilhermegarnier.com/2008/03/17/linguagens-de-programacao-de-baixo-medio-e-alto-nivel/

O excelente blog Code Commit publicou um artigo interessante sobre linguagens de programação: como podemos definir se uma linguagem é de baixo, médio ou alto nível?

O post apresenta as principais características de cada nível e as dificuldades de se classificar as linguagens num nível específico, e inclui um gráfico apontando a classificação de algumas das linguagens mais populares, de acordo com a experiência do autor. Muito interessante.

Acessando múltiplos bancos de dados em Rails

Post movido para: http://blog.guilhermegarnier.com/2008/03/11/acessando-multiplos-bancos-de-dados-em-rails/

Esta semana me deparei com uma situação no projeto em Rails em que estou trabalhando, onde necessitei acessar um banco de dados de outra aplicação, para fazer algumas consultas simples. Eu poderia simplesmente fazer a conexão com o banco e as querys em SQL. Porém, eu obviamente queria aproveitar as facilidades que o Rails proporciona ao abstrair estes detalhes com a classe ActiveRecord::Base.

Quando criamos um novo model em Rails, a nova classe criada, derivada de ActiveRecord::Base, é mapeada por padrão em uma tabela no banco de dados da aplicação – o Rails assume o nome da classe no plural, mas permite que você especifique um nome diferente. Na migration que também é criada automaticamente, a tabela correspondente é definida. Porém, neste caso, eu não queria criar uma tabela, pois ela já existe. Além disso, é um servidor de banco de dados diferente, com usuário e senha diferentes.

Após alguma pesquisa, descobri como resolver este problema. Suponha que você queira acessar uma base de usuários para compartilhar login e senha:

1 – especificar a nova conexão no arquivo config/database.yml. No exemplo abaixo, defini o nome “autenticacao_development”, supondo que tenhamos outras conexões para teste e produção:

autenticacao_development:
  adapter: mysql
  host: autenticacao_dev
  username: login
  password: senha
  database: autenticacao

2 – criar uma classe abstrata (model), derivada de ActionRecord::Base, e usar o método establish_connection para referenciar a conexão. O parâmetro “autenticacao_#{RAILS_ENV}” usa a variável RAILS_ENV para especificar a conexão relativa ao ambiente (autenticacao_development, autenticacao_test ou autenticacao_production):

class AutenticacaoDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "autenticacao_#{RAILS_ENV}"
end

3 – para cada tabela deste banco de dados que será acessada, criar uma nova classe (model) derivada da classe AutenticacaoDatabase recém-criada. Caso o nome da tabela seja diferente do padrão (o nome da classe no plural), use o método set_table_name para especificar o nome correto. E se a primary key não for “id”, use “set_primary_key” para definir o nome correto deste campo.

class Usuario < AutenticacaoDatabase
  set_table_name 'usuario_tb'
  set_primary_key 'usuario_id'
end

Feitas as configurações acima, o banco de dados externo ficará acessível como o da aplicação, com todos os métodos usados normalmente. Por exemplo:

Usuario.find(:all)
Usuario.find_by_usuario_id(1)
Usuario.create

Detalhe importante: com esta configuração, é necessário fazer uma série de alterações nos unit tests para que estes funcionem. Em breve farei outro post detalhando estes passos.

Seguem abaixo os links que eu usei como base:

Verificação de tipos em Ruby

Post movido para: http://blog.guilhermegarnier.com/2008/03/04/verificacao-de-tipos-em-ruby/

Uma das principais características do Ruby é ser uma linguagem dinâmica, o que significa que a tipagem é dinâmica, ou seja, a linguagem permite que uma variável seja usada sem ser previamente declarada, assuma um valor de uma classe qualquer e depois possa ter seu valor alterado para um objeto de outra classe.

Apesar da simplicidade que esta característica traz, freqüentemente precisamos verificar o tipo de classe de uma variável, para termos certeza de que em uma chamada de função não é passada uma variável contendo um objeto de uma classe diferente da esperada, por exemplo. Isto não é necessário em linguagens como C e Java, onde cada variável precisa ser declarada antes do uso, e na declaração é necessário especificar o tipo de variável.

Este artigo apresenta um módulo Ruby chamado Types, que simplifica bastante o trabalho de verificação do tipo de classe passado em cada parâmetro de uma função. É possível, inclusive, verificar se a classe passada implementa um método específico. Qualquer tipo de verificação é feito acrescentando-se uma linha antes da definição da função, eliminando a necessidade de verificarmos o tipo de cada parâmetro no código da função. Não cheguei a testar o módulo ainda, porém, de acordo com o artigo, parece ser uma solução muito simples e flexível para problemas de tipagem.


@guilhermgarnier

Erro: o Twitter não respondeu. Por favor, aguarde alguns minutos e atualize esta página.

Estatísticas

  • 58,410 hits
Linux Counter