Herberth Amaral

Software development adventures

Archive for the ‘web’ tag

[Dica] Valide e-mail, IP e URLs no PHP sem regex

with 4 comments

Eu vejo muita gente utilizando regex (expressão regular) para validar vários tipos de dados, incluindo emails, tipos (boolean, string e int), sanitizar dados (remover caracteres inválidos, por exemplo) no PHP. Este tipo de coisa é um saco para quem não saca muito de regex, mas é possível fazer todas estas validações sem o uso de regex utilizando as funções da família filter:

if(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL) )
{
   echo 'Yay!';
}

vários outros filtros que você pode experimentar com esta função super útil e nunca mais precisar lembrar daquela regex chata de email :-)

Happy coding!

[Update]

Esqueci de mencionar: Estas funções estão disponíveis a partir do PHP 5.2.0. Valeu, Almir Mendes!

Written by Herberth Amaral

August 13th, 2010 at 1:21 pm

Posted in PHP

Tagged with ,

#12elw foi show!

without comments

Décimo segundo encontro Locaweb

Ontem, 15 de Abril de 2010, aconteceu o 12º encontro Locaweb de Profissionais de Internet em Belo Horizonte. O evento foi muito bacana, mas infelizmente não posso falar muita coisa das palestras pois não quero ser acusado de espalhar spoiler :-P

O evento aconteceu em um auditório no Ouro Minas, um dos mais luxosos hotéis de Belo Horizonte e fomos super bem recebidos pelo pessoal da Locaweb

Recepção da Locaweb

E que recepção essa, hein...

O evento foi aberto pelo Gilberto Mautner, um dos fundadores da Locaweb, falando sobre tendências do mercado da Internet. Palestra interessante: não conhecia o Mautner e não sabia do tamanho do novo datacenter da locaweb… é monstruoso.

Logo após o Mautner, foi a vez do Fábio Akita com sua palestra “Desmembrando pessoas – Pensamentos aleatórios sobre Gestão”. Essa palestra segue a linha de algumas outras que o Akita ministrou no ano passado. O nível da palestra tava bem alto e deu pra perceber o quanto ele está avançando em suas pesquisas sobre fatores humanos dentro de empresas, principalemente as de desenvolvimento de software. Após a palestra, deu para trocar umas idéias com ele e com outra galera que estava lá.

André Oliveira, Fábio Akita e eu

André Oliveira, Fábio Akita e eu

Falamos principalmente de implantação de metodologias ágeis, Scrum Alliance e suas formas de arrancar dinheiro da galera ;-) , Rails (como não poderia deixar de ser), ambientes de trabalhos e suas restrições (e como burla-las, hehehe).

Infelizmente, não deu pra assistir a palestra da Microsoft toda. Pelo que eu vi, eles falaram de um bocado de novidades que estão acontecendo com as tecnologias da Microsoft, principalmente no que diz respeito à Web. Vamos ver :-)

Após a palestra da Microsoft e após o almoço, foi a vez do Vinícius Teles palestrar “Startup – De empregado a empregador”. Palestra realmente inspiradora e uma das top 3 do evento. Bem bacana.

Uma coisa que eu achei legal, foi o nível dos palestrantes e a atenção com que os mesmos te tratam. Foi assim com o Akita e não foi diferente com o Vinícius Teles. Uma das coisas que me chamou atenção foi o fato dele ter trabalhado com a Empresa Junior da UFRJ. O bate papo se resumiu a basicamente EJs: que tipo de serviços prestar, o que fazer com relação à rotatividade de membros, que tipo de projetos não pegar, etc.

Vinícius Teles e eu.

Depois do Vinícius, a próxima palestra foi do Gil Giardelli: “Painel Cyber Punk”. Ele falou várias coisas sobre Web 2.0, mas eu fiquei meio perdido durante a palestra. Não dá pra comentar muita coisa.

A última palestra e a mais foda de todas foi a do Luli Radfaher. Eu não o conhecia. O cara é uma figura! Com a palestra intitulada “A nova escala da Inovação”, ele disse sobre como a Web está se expandindo, conectando pessoas e como novas possibilidades surgem a partir disso.

Luli Radfaher, eu e André Oliveira

Luli Radfaher, eu e André Oliveira

A palestra do cara é simplesmente ilária, principalmente da forma que ele fala que precisamos de psiquiatras e como ele zoa a Microsoft ;-)

Quem ainda não foi no evento, eu recomendo fortemente. Vale cada centavo investido mesmo!(e você ainda recebe de volta os R$50,00 como crédito para contratar algum serviço da Locaweb).

Até o ano que vem!

Written by Herberth Amaral

April 17th, 2010 at 12:34 am

Plugins indispensaveis para desenvolvimento com jQuery

with 4 comments

jquery-logo

Algumas pessoas já me perguntaram quais são os plugins que eu mais uso quando estou desenvolvendo em JavaScript usando jQuery. Bem, aí vai a lista:

1 – Autocomplete.

jquery-autocomplete

Estupidamente fácil e intuitivo de usar, o autocomplete é o primeiro plugin que eu coloco na pasta de Scripts (isso quando eu não posso usar umCDN). É difícil eu me deparar com alguma aplicação que eu não o use. A documentação oficial disponível não é lá das melhores, mas há várias páginas na Web falando sobre o assunto.

Página oficial Demo

2 – Datatables

jquery-datatables

Na minha humilde opinião, o melhor plugin de tabelas para jQuery. Com ele você pode criar uma tabela dinâmica com paginação, busca e ordenação e usando AJAX em pouquíssimas linhas de código. O único problema é que a convenção de código dele não segue tanto a convenção usada pelo jQuery ou por outros plugins (normalmente nota-se isso quando se precisa fazer algo mais complexo). O mais interessante é que ele está em constante desenvolvimento e apresenta melhoras bem significativas a cada nova versão.

Página oficial Demo

3 – Validator


Do mesmo cara que criou o plugin do autocomplete, o jQuery validator é outro must-have na sua toolbox. Quem já fez validação de formulários em JavaScript na unha, sabe que esse plugin também é um salvador de vidas. Assim como o autocomplete, o validator não tem uma documentação oficial muito boa, mas é bem intuitivo e fácil de usar.

Página oficialDemo

4 – jQueryTools


Mesmo com a nem-tão-verdadeira promessa de conter todas essas ferramentas em míseros 5.76 KB, o jQuery Tools é uma excelente ferramenta que até certo ponto é concorrente do jQueryUI. Com diversos componentes, como tabs, tooltips, exposé e overlay, o trabalho com jQuery se torna muito mais poderoso e divertido com essa ferramenta.

Página inicialDemo

5 – jQuery UI


Por último, mas não mais importante: o jQueryUI. A versão 1.8.2 está bem completa e pra você que não gosta de ficar perdendo tempo desenhando janelinhas modais usando o lightbox, ou de fazer menus razoáveis (seja no estilo accordion ou tabs), o jQueryUI é pra você. Extremamente poderoso e simples de usar (assim como a maioria dos plugins decentes pra jQuery), o jQueryUI facilita muito a vida de pessoas que precisam de uma interface mais poderosa mas sem gastar muito tempo elaborando-a.

Página inicial Demo

6 – FireQuery


Esse não é um plugin para jQuery na verdade, mas um plugin para o Firefox (melhor browser para desenvolvedores IMO) que dá uma mão e tanto na hora de trabalhar com jQuery no Firefox. Um dos principais recursos é o jQuerify, que adiciona o jQuery numa página que não o possui. Extremamente útil quando se sabe usar o console do Firebug. Além disso, ele mostra todos os elementos que possuem um EventListener usando o jQuery. Muito legal.

Página inicialDemo

Mande sugestões de outros plugins indispensáveis para jQuery! See ya!

Written by Herberth Amaral

April 3rd, 2010 at 6:13 pm

Posted in JavaScript,jQuery

Tagged with , , , ,

O que fazer quando seu codigo JavaScript se torna um monstro

without comments

Quando eu não conhecia jQuery e seus plugins, JavaScript era um tédio pra mim. É fato que uma biblioteca de alto nível (não só o jQuery, mas o mootools e o prototype, por exemplo) facilitam e deixam o desenvolvimento em JavaScript rápido e divertido, pois você não terá que se preocupar (muito) com detalhes de implementação de browsers.

Mas o que acontece quando, mesmo usando com alguma lib fodástica, seu código começa a ficar grande demais, complexo demais, fragmentado demais ou desorganizado demais? Isso é a minha definição de código monstro. Eis algumas dicas que podem te ajudar se você estiver passando por isso:

1 – Evite o Callback Hell

O jQuery mostra muitos exemplos usando funções anônimas como callback. De certo modo, isso é uma boa prática para situações simples, como o  tratamento do evento clique de um botão:

$("#meuBotao").click(function(){
  alert('Fui clicado!');
});

Mas nem sempre isso é legal: muitas vezes você quer reaproveitar essa função para outros callbacks, como por exemplo:

$('#meuBotao').click(getClientes);
$('#meuInput').blur(getClientes);

getClientes = function()
{
   $.get('/clientes/get','',
   function(data){
      //trata os dados recebidos aqui
   },'json')
}

Nesse caso, eu estou aproveitando minha função de callback getClientes para dois event listeners. Isso é bem legal, mas quando nosso código começa a crescer, nos esbarramos em outro problema: as funções globais.

2 – Evite funções globais

Isso quer dizer, ao invés disso:

$('#meuBotao').click(getClientes);
$('#meuInput').blur(getClientes);

getClientes = function()
{
   $.get('/clientes/get','',
   function(data){
      //trata os dados recebidos aqui
   },'json');
};

Faça algo assim:

$('#meuBotao').click(getClientes);

$('#meuInput').blur(Clientes.getClientes);

var Clientes = {
    getClientes:function()
    {
       $.get('/clientes/get','',
       function(data){
          //trata os dados recebidos aqui
       },'json');
    }
};

Isto é, coloque suas funções dentro de objetos. Assim você evita funções globais e evita fazer código “estruturado”, passando a usar os recursos da orientação à objetos do JavaScript e deixando o mínimo de globals possível. Essa é a forma mais fácil que eu conheço de se evitar funções globais e organizar melhor seu código, mas há outras formas como o Module Pattern.

3 – O “this” aponta para diferentes lugares em diferentes contextos. Saiba como lidar com isso.

Você não está deixando mais todas as suas funções como globais, está encapsulando tudo dentro de objetos, reaproveitando código e feliz da vida quando percebe que o this não é mais this. Calma que eu explico.

Você já deve ter visto algo assim no jQuery:

$('a').click(function(){
   $(this).html('fui clicado') ;
});

Isso faz com que, quando um link é clicado, o mesmo fique com o texto “fui clicado”. Deu pra notar que nesse caso, o this aponta para o elemento que disparou o evento. Mas olhe o seguinte exemplo:

var Cliente =
{
    texto:'Fui clicado',
    init:function()
    {
        //this aponta para o objeto Cliente
        $('a').click(this.aClickHandler);
    },
    aClickHandler:function()
    {
        //this aponta para o elemento "a" que disparou o evento
        $(this).html(Cliente.texto);
    }
};

Viu como “this” pode mudar de contexto? No exemplo acima, o problema de não ter o this apontando para o objeto Cliente foi facilmente contornado, mas você poderá precisar acessar o objeto pai de uma forma parecida com a this. Nesse caso, você pode passar um parâmetro para o evento usando o método bind() do jQuery, informando o contexto que ele foi chamado:

var Cliente =
{
    texto:'Fui clicado',
    init:function()
    {
        //this aponta para o objeto Cliente
        $('a').bind('click',{'self':this},this.aClickHandler);
    },
    aClickHandler:function(event)
    {
        var self = event.data.self;
        //o self aponta para Cliente e o this aponta para
        //o elemento "a" que disparou o evento
        $(this).html(self.texto);
    }
};

4 – Procure pelos patterns corretos.

Quem disse que padrões de projeto criam um vocabulário em comum na equipe não poderia ter dito algo mais pertinente:  o uso de padrões faz com que o desenvolvedor foque nas funcionalidades da aplicação sem se preocupar com alguns detalhes de implementação.

O AjaxPatterns contém uma coleção bem legal e bem documentadas de patterns para Ajax e JavaScript em geral. Mas não espere ter problemas pra consultar os patterns: quanto mais se conhece sobre padrões, mais fácil é pensar em soluções de problemas e planejamento em geral.

5 – Deixe apenas um $(document).ready em todo o seu código

Eu diria isso para todos os event listeners que você possa vir a colocar, mas o $(document).ready é o mais crítico na minha opinião. No JavaScript não há sobreposição de eventos: se você colocar dos event listeners para um mesmo evento, os dois serão executados. Isso pode dar problemas, pois você pode deixar o $(docuement).ready em dois arquivos diferentes e você pode desejar que um evento execute antes de outro.

6 – Valide seu JavaScript

Browsers interpretam JavaScript de forma diferente, então é sempre bom ter uma padronização de código para que não tenhamos problemas com sintaxe em diferentes browsers. Uma ferramenta de validação bem legal é o jslint.

– EDIT–

Nem sei onde tava com a cabeça quando esqueci isso:

7 – Escreva testes!

Testes pode ser tido como documentação executável e facilita muito quando você pega um código de outro desenvolvedor que já tenha testes: é fácil de ver os modos de uso do código e você se sentirá seguro ao fazer algo e ver que os testes passam. Além do mais, você não precisa encher seu código de comentário pra explicar como ele funciona (comentar é bom, mas sem exageros);

Entretanto, testar JavaScript pode não ser tão fácil assim. É necessário mais disciplina e paciência do que é necessário para testar seu código backend, mas é algo que se adquire com o tempo.

See ya!

Written by Herberth Amaral

March 11th, 2010 at 10:08 pm

Criando Web crawlers em Python – Parte II

with 9 comments

Ir para  Criando Web crawlers em Python – Parte I

Ir para Criando Web crawlers em Python – Parte III

No post anterior, eu mostrei como recuperar informações básicas de uma página da Web usando urllib, urllib2 e BeautifulSoup. Neste post eu mostrarei como enviar dados via GET e POST.

Há um excelente guia sobre urllib2: o urllib2 – The Missing Manual que foi de grande valia nos meus estudos. Nele, pode-se encontrar as informações sobre envio de informações do tipo GET e POST para o servidor. Isso será útil, pois é assim que a busca do SourceForge (e da maioria dos outros portais) funcionam.

Vamos dar uma olhada na URL do na pesquisa por “Python” no SF:

http://sourceforge.net/search/?type_of_search=soft&words=python

Bem, isso indica que temos que enviar duas variáveis para o SF.net: type_of_search (sempre igual à soft) e words (que é a nossa busca). Um exemplo de código que faria essa busca poderia ser esse:

import urllib,urllib2

base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')

variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()
print response

Se der tudo certo, você  deveráver  o código fonte da página do SF que contém os resultados da pesquisa.

Feito isso, vamos analisar como a marcação do SF é organizada na busca:

O Firebug nos ajuda a não perder tanto tempo assim analisando código. De acordo com o que pudemos obter, podemos dividir as informações que queremos dessa forma:

  • O resultado da busca está dentro de uma tabela com o id=”searchtable”.
  • Um resultado da busca está sempre dentro de um td com classe description.
  • O nome do projeto está dentro de um link dentro de um h2 dentro desse td “description”.
  • O link de download se encontra na próxima td da mesma linha da tabela.

Exibindo as informações dos projetos

Agora nós temos como buscar nossa informação e como filtra-la. Como disse no post anterior, eu iria mostrar alguns usos mais avançados do BeautifulSoup, principalmente no que diz respeito à percorrer o documento. O próximo passo será mostrar as informações dos projetos que aparecem no resultado da nossa busca. Podemos fazer isso da seguinte forma:

from BeautifulSoup import BeautifulSoup
import urllib,urllib2

base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')

variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()

soup = BeautifulSoup(response)
# procura pela tabela com id=searchtable
tabela = soup.find('table',{'id':'searchtable'})
#retorna uma lista com todas as linhas (<tr>) da tabela
linhas_tabela = tabela.findAll('tr')

i=0

for linha in linhas_tabela:
    i+=1
    #encontra a primeira coluna (descricao) da linha
    coluna_descricao = linha.find('td')

    #o atributo contents contem uma lista com o conteudo da tag
    nome_projeto = coluna_descricao.find('a').contents[0]

    descricao_projeto = coluna_descricao.contents[2].strip()
    print 'Projeto '+str(i)+': '+nome_projeto
    print descricao_projeto
    print '--------------------------------'

Legal, não?  Isso é uma demonstração básica do poder que o BeautifulSoup tem para percorrer e extrair informações em (X)HTML. O mais interessante de tudo é que quase todos os métodos da classe BeutifulSoup.Tag retornam a própria referência, o que quer dizer que podemos fazer chains (cadeias) de comando como essas:

nome_do_primeiro_projeto_da_pesquisa = soup.find('table',{'id':'searchtable'}).findAll('tr')[0].find('td').find('a').contents[0]

Isso é realmente muito útil quando se quer economizar código. E o mais interessante de tudo: é bem legível (mas não necessariamente fácil de interpretar… quem ler seu código assim terá que ter uma boa noção do BeautifulSoup).

Baixando os arquivos do projeto

Essa parte é relativamente fácil. O SF é um serviço muito bom, até para o nosso pequeno experimento :)

A URL que o link “Download Now” aponta sofre 3 redirects até o arquivo final. Tudo isso serve para o SF determinar a sua localização e apontar o mirror mais próximo de você. Então a única coisa que precisamos fazer é passar esse link para o wget (um programa bem útil para download de arquivos na Web presente na maioria das distribuições Linux. Um clone para Windows pode ser encontrado aqui) e ele irá baixar o projeto para nós. Simples, não?

Então vamos ao código:

from BeautifulSoup import BeautifulSoup
import urllib,urllib2
from subprocess import call

base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')

variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()

soup = BeautifulSoup(response)

# procura pela tabela com id=searchtable
tabela = soup.find('table',{'id':'searchtable'})

 #retorna uma lista com todas as linhas da tabela
linhas_tabela = tabela.findAll('tr')

i=0
links_download = []

for linha in linhas_tabela:
    i+=1
    coluna_descricao = linha.find('td')
    nome_projeto = coluna_descricao.find('a').contents[0]
    link_download = linha.find('a',{'class':'downloadnow'})['href']
    links_download.append(link_download)
    descricao_projeto = coluna_descricao.contents[2].strip()
    print 'Projeto '+str(i)+': '+nome_projeto
    print descricao_projeto
    print '--------------------------------'

opcao = int(raw_input('Qual projeto gostaria de baixar? '))
opcao_url = base_url+links_download[opcao-1]
call(['wget',opcao_url]) #chama o wget com o link para download

A única coisa que eu fiz de novo foi adicionar o link de download em uma lista e perguntar ao usuário qual projeto ele deseja baixar. Então, eu passei o link de download para o wget que fez o serviço de baixar o arquivo pra mim. Pronto! Nosso crawler de exemplo do SF.net está pronto :)

No proximo post eu mostrarei como guardar valores de sessão para percorrermos páginas protegidas por senha. See ya!

Written by Herberth Amaral

March 7th, 2010 at 11:08 am

Posted in Python,crawler

Tagged with , , ,

Minicurso de jQuery na Unimontes. Reserve ja a sua vaga!

without comments

Era pra eu ter postado isso aqui antes, mas ainda há tempo.

A comissão de formatura do 7º período de SI da Unimontes (a qual eu me incluo) está organizando um minicurso de 12 horas de jQuery. Serão duas turmas com 20 vagas: uma durante a semana (segundas e quartas-feira, de 19:30 às 21:30 – vagas esgotadas) e durante o sábado (8:00 – 12:00 – aproximadamente 10 vagas restantes).

O conteúdo a ser abordado será esse:

1 – Introdução
1.1 – Introdução à HTML.
1.2 – Introdução à CSS.
1.3 – Introdução à JavaScript.
2 – Document Object Modelling (DOM)
2.1 – A árvore de elementos
2.2 – Selecionando elementos.
2.3 – Mudando conteúdo do documento.
2.4 – Mudando estilos da página.
3 – Automatizando acesso ao DOM com jQuery.
3.1 – Seletores – Selecionando elementos por ID, classe, tag, atributos, conteúdo e posição.
3.2 – Alterando conteúdo.
3.3 – Eventos.
4 – Efeitos.
4.1 – fadeIn/fadeOut.
4.2 – slideDown/slideUp.
4.3 – animate.
5 – AJAX
5.1 – Formatos de dados: XML e JSON.
5.2 – Requisitando dados do servidor.
5.3 – Eventos AJAX (ajaxComplete,ajaxStop,ajaxStart).
5.4 – Mudando o conteúdo da página dinamicamente.
6 – jQueryUI.
6.1 – Accordion.
6.2 – Dialog.
6.3 – Drag n’ drop (arrastar/soltar).
6.4 – Efeitos especiais.
6.5 – Slide.
6.6 – Button.
6.7 – DatePicker.
7 – Plugins.
7.1 – Galeria de fotos.
7.2 – Validação de formulários.
7.3 – Tabelas.
7.4 – Autocomplete.
7.5 – Onde obter mais plugins.
8 – Firebug.
8.1 – Usando o console interativo.
8.2 – Debugando JavaScript.
8.3 – FireQuery.
8.4 – Consoles de outros browsers.
Eu reconheço que o conteúdo é relativamente extenso para um curso de 12 horas, por isso eu gostaria de ressaltar que quem já souber (mesmo que seja pouco) HTML e CSS já estará na frente de muita gente.
Como o minicurso é presencial e nessa primeira versão não terá aulas online (sim, perguntaram isso =), a inscrição só será feita na Coordenação do Curso de Sistemas de Informação no CCET (prédio 3 da Unimontes).
Corram, as vagas estão se esgotando! :)

Written by Herberth Amaral

March 6th, 2010 at 9:11 am