Archive for the ‘web’ tag
[Dica] Valide e-mail, IP e URLs no PHP sem regex
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:
Há 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!
#12elw foi show!
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 ![]()
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
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á.
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.
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.
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!
Plugins indispensaveis para desenvolvimento com jQuery
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.
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.
2 – 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.
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.
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.
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.
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.
Mande sugestões de outros plugins indispensáveis para jQuery! See ya!
O que fazer quando seu codigo JavaScript se torna um monstro
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:
alert('Fui clicado!');
});
Mas nem sempre isso é legal: muitas vezes você quer reaproveitar essa função para outros callbacks, como por exemplo:
$('#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:
$('#meuInput').blur(getClientes);
getClientes = function()
{
$.get('/clientes/get','',
function(data){
//trata os dados recebidos aqui
},'json');
};
Faça algo assim:
$('#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:
$(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:
{
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:
{
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!
Criando Web crawlers em Python – Parte II
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:
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:
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:
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!
Minicurso de jQuery na Unimontes. Reserve ja a sua vaga!
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:













