O Desenvolvedor http://odesenvolvedor.andafter.org/ Mon, 26 Sep 2016 14:27:41 -0300 GS Solutions pt-br Copyright GS Solutions - Tecnologia da Informação. Todos os direitos reservados. contato@gssolutions.com.br http://creativecommons.org/licenses/by-sa/2.0/ Eliminando PHP short tags com regex http://odesenvolvedor.andafter.org/publicacoes/eliminando-php-short-tags-com-regex.html http://odesenvolvedor.andafter.org/publicacoes/eliminando-php-short-tags-com-regex.html#comments Mon, 26 Sep 2016 14:27:41 -0300 Guilherme Serrano regex, php http://odesenvolvedor.andafter.org/publicacoes/eliminando-php-short-tags-com-regex.html Escrevi uma regex para substituir short tags do PHP, a única coisa diferente da maioria que eu encontrei foi que me preocupei em manter as quebras de linhas - e não quebrar nenhuma parte do código comendo caracter (encontrei várias sugestões com regex que acabam "comendo" caracter dependendo do caso).

A expressão regular (regex):

<\?([^p|=])

O replace:

<?php $1


Explicando a REGEX:

Ela irá buscar por qualquer <? que não seja seguido imediatemente por um "p", garantindo que <?php não case com a regex, ou seguido por um "=" - garantindo que <?= não case com a regex.

Os parêntesis da REGEX criam um grupo de captura que é utilizado no replace, isto serve para casos específicos como

<?if(

O i seria "engolido" neste caso. O grupo de captura também captura quebras de linha, isso garante que:

<?
if($x = $y)

Se transforme em:

<?php
if($x = $y)
E não em:

<?php if($x = $y)
Mantendo a mesma legibilidade e formatação do código original após o replace.


Não encontrei nenhuma situação em que esta regex causou problema, se ela não funcionar em algum caso comente aí.


]]>
Controlando GPIO do RaspberryPI com NodeJS http://odesenvolvedor.andafter.org/publicacoes/controlando-gpio-do-raspberrypi-com-nodejs.html http://odesenvolvedor.andafter.org/publicacoes/controlando-gpio-do-raspberrypi-com-nodejs.html#comments Wed, 14 Jan 2015 12:32:50 -0300 Guilherme Serrano maker, eletronica, raspberry-pi, arduino http://odesenvolvedor.andafter.org/publicacoes/controlando-gpio-do-raspberrypi-com-nodejs.html Esta semana eu comecei a me aventurar com o Arduino e depois de me sentir um pouco mais seguro na parte eletrônica resolvi entender como controlar os "pinos", ou formalmente conhecidos como General Purpose Input/Output (GPIO) do Raspberry Pi.

Consegui fazer testes para controlar GPIO do Raspberry PI pelo terminal unix, mas resolvi colocar em teste a Atwood's Law:

"any application that can be written in JavaScript, will eventually be written in JavaScript. "

qualquer aplicação que pode ser escrita em JavaScript, eventualmente será escrita em JavaScript.

Controlando GPIO do RaspberryPI com Node.JS


1) Instale NodeJS + NPM no RPi

A instalação do nodejs e do npm pode variar de acordo com o SO que você está usando no RPi - aqui eu estava usando o SO do Kano e consegui instalar sem problemas - mas não via (apt-get).

wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb

Para verificar se você tem nodejs instalado - ou se a instalação aconteceu com sucesso, utilize os comando abaixo para verificar a versão instalada:

node -v

Repita o proesso para o npm

npm -v

Se eles não estão instalados o primeiro passo é instalar o NodeJS e NPM no seu raspberry.

Camiseta Node.JS

Jabá: camiseta NodeJS do Eu Compraria



2) Instale o rpi-gpio

Com o node e npm instalados você precisa instalar o rpi-gpio utilizando o npm.

npm install rpi-gpio


3) Conecte um led ao seu RPi

Defina o GPIO que você urá utilizar, veja a documentação do GPIO dos RPi do RPi - a imagem abaixo é desta documentação.


No meu caso usei o 13 (que é o GPIO27) e o pino 14 para o terra. Não esqueca de usar um resistor de acordo com o led que você vai utilizar.

Eu utilizei uma protoboard para facilitar a instalação.


4) Crie uma aplicação em Node.JS

Crie uma aplicação de teste e carregue o rpi-gpio.

var gpio = require('rpi-gpio');

O setup (veja a documentação do rpi-gpio) faz o "export" da GPIO e configura se será entrada ou saída.

O último parâmetro é o callback para quando a porta estiver pronta.

gpio.setup(13, gpio.DIR_OUT, write);

No callback, estou escrevendo o valor "true" para o pino 13 (ou GPIO27) - que vai acenter o led conectado lá.

function write() {
  gpio.write(13, true, function(err) {
    if (err) throw err;
    console.log('Written to pin');
  });
}

Agora você já pode fazer um server web interagir com o Arduino, com leds, com a sua casa.


Veja também:

Instalação do NodeJS no RPi - we work we play (en)

Documentação do GPIO do Raspberry Pi (en)

Heim control - Automação residencial com Node.JS (en)

]]>
Instalar Node.js em Ubuntu 14.04 http://odesenvolvedor.andafter.org/publicacoes/instalar-nodejs-em-ubuntu-1404.html http://odesenvolvedor.andafter.org/publicacoes/instalar-nodejs-em-ubuntu-1404.html#comments Tue, 07 Oct 2014 08:23:16 -0300 Chris Benseler http://odesenvolvedor.andafter.org/publicacoes/instalar-nodejs-em-ubuntu-1404.html

Precisei configurar um servidor novo no EC2 da Amazon, escolhi um Ubuntu 14.04. Tudo as mil maravilhas (como sempre) até a hora de instalar o Node.js. O executável do Node.js no Ubuntu, quando instalado pelo repositório, é nodejs (e não node). Então alguns scripts começaram a dar problemas. Muitos problemas.

Uma solução que encontrei - e não conhecia, é usar o nvm (Node.js version manager).

Instalação simples e fácil. Primeiros, algumas dependências:

sudo apt-get update

sudo apt-get install build-essential libssl-dev

Pull no projeto do nvm:

curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh

Obs.: mude 0.16.1 pela versão desejada.

Recarregue o bash:

source ~/.profile

Pronto. Com o comando "nvm ls-remote" você verá as versões disponíveis. Então, dê um

nvm install 0.11.13

e a versão 0.11.13 estará instalada. Você pode instalar várias e alternar entre elas, usando:

nvm use 0.11.13

Para quem já usou o rvm, é a mesma coisa.

Referência: https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server

]]>
Como bloquear user-agent pelo .htaccess<br> http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html#comments Fri, 29 Aug 2014 07:28:47 -0300 Guilherme Serrano server, apache, server, bot http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html Na semana passada o site de um cliente foi atacado por spammers devido a uma falha de segurança do Wordpress e ontem um amigo notificou que o Eu Compraria estava fora do ar por falha do banco de dados - demorei um pouco para identificar isto pois o servidor e o banco continuavam "de pé", mas analizando o processamento do servidor vi que constantemente o MySQL estava estourando o processamento.

Achei estranho e fui verificar os logs do servidor e encontrei a causa do problema: um bot fazendo requisições constantes para o And After, para páginas de busca e tags (onde meu sistema de cache, confesso, não é muito eficiente).

O primeiro passo foi bloquear o bot pelo IP via .htaccess para sanar o problema.

Como bloquear um IP via .htaccess

Sem mistérios, nas regras de .htacces adicionei o seguinte:

Order Deny,Allow
Deny from 54.197.86.53

Problema resolvido temporariamente.

Mas claro que durou pouco, pois o bot tinha um tange de IP para trabalhar. Ao invés de ir bloquando IP por IP - ou bloquear o range de IPs, como este bot se identificava via user-agent, achei que seria uma solução mais elegante e duradoura.

Como bloquar user-agent via htaccess

O primeiro passo é identificar o user-agent que você quer bloquear, para isso basta ver os logs do apache.

tail -f /path_dos_logs_do_dominio/access.log

No meu caso o bot se identificava como BDBBot. Depois de identificar quem queremos bloquear vamos criar as regras no htacess, explicadas abaixo.

Na primeira linha vamos determinar uma "env" chamada bad_bot se o user-agent casar com BDCBot (usando o modsetenvif do Apache). Você pode repetir esta linha para todos os user-agents que deseja bloquear.

Com esta identificação de user-agent e com o env configurado quando "casar", você só precisa escrever a regra para negar os acessos sempre que o env for bad_bot.

Para o meu caso adicionei o seguinte ao htaccess:

BrowserMatchNoCase BDCBot bad_bot
Order Deny,Allow
Deny from env=bad_bot

Agora sim, problema com este bot resolvido de uma forma um pouco menos temporária.


Ainda neste tópico li sobte uma abordagem curiosa e, ao meu ver, perigosa que é fazer o inverso: ao invés de bloquear os spammers, bloquear tudo e permitir apenas os bots / crawlers conhecidos.

Eu não arrisco, mas se você se interessar pode conferir o tópico sobre o assunto.

]]>
Como bloquear user-agent pelo .htaccess<br> http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html#comments Fri, 29 Aug 2014 07:28:47 -0300 Guilherme Serrano server, apache, server, bot http://odesenvolvedor.andafter.org/publicacoes/como-bloquear-user-agent-pelo-htaccess.html Na semana passada o site de um cliente foi atacado por spammers devido a uma falha de segurança do Wordpress e ontem um amigo notificou que o Eu Compraria estava fora do ar por falha do banco de dados - demorei um pouco para identificar isto pois o servidor e o banco continuavam "de pé", mas analizando o processamento do servidor vi que constantemente o MySQL estava estourando o processamento.

Achei estranho e fui verificar os logs do servidor e encontrei a causa do problema: um bot fazendo requisições constantes para o And After, para páginas de busca e tags (onde meu sistema de cache, confesso, não é muito eficiente).

O primeiro passo foi bloquear o bot pelo IP via .htaccess para sanar o problema.

Como bloquear um IP via .htaccess

Sem mistérios, nas regras de .htacces adicionei o seguinte:

Order Deny,Allow
Deny from 54.197.86.53

Problema resolvido temporariamente.

Mas claro que durou pouco, pois o bot tinha um tange de IP para trabalhar. Ao invés de ir bloquando IP por IP - ou bloquear o range de IPs, como este bot se identificava via user-agent, achei que seria uma solução mais elegante e duradoura.

Como bloquar user-agent via htaccess

O primeiro passo é identificar o user-agent que você quer bloquear, para isso basta ver os logs do apache.

tail -f /path_dos_logs_do_dominio/access.log

No meu caso o bot se identificava como BDBBot. Depois de identificar quem queremos bloquear vamos criar as regras no htacess, explicadas abaixo.

Na primeira linha vamos determinar uma "env" chamada bad_bot se o user-agent casar com BDCBot (usando o modsetenvif do Apache). Você pode repetir esta linha para todos os user-agents que deseja bloquear.

Com esta identificação de user-agent e com o env configurado quando "casar", você só precisa escrever a regra para negar os acessos sempre que o env for bad_bot.

Para o meu caso adicionei o seguinte ao htaccess:

BrowserMatchNoCase BDCBot bad_bot
Order Deny,Allow
Deny from env=bad_bot

Agora sim, problema com este bot resolvido de uma forma um pouco menos temporária.


Ainda neste tópico li sobte uma abordagem curiosa e, ao meu ver, perigosa que é fazer o inverso: ao invés de bloquear os spammers, bloquear tudo e permitir apenas os bots / crawlers conhecidos.

Eu não arrisco, mas se você se interessar pode conferir o tópico sobre o assunto.

]]>
Como migrar um repositório git sem perder o histórico?<br> http://odesenvolvedor.andafter.org/publicacoes/como-migrar-um-repositorio-git-sem-perder-o-historico.html http://odesenvolvedor.andafter.org/publicacoes/como-migrar-um-repositorio-git-sem-perder-o-historico.html#comments Wed, 04 Jun 2014 11:12:46 -0300 Guilherme Serrano git, desenvolvimento http://odesenvolvedor.andafter.org/publicacoes/como-migrar-um-repositorio-git-sem-perder-o-historico.html Faz alguns anos que comecei a trabalhar com git e na época escolhi o Unfuddle como serviço para meus repositórios privados e de clientes. Atualmente estou usando o Bitbucket para repositórios privados e o Github para projetos open-source, mas ainda tem alguns repositórios "legados" no antigo serviço.

Ontem retomei um projeto de uns dois anos atrás que estava no unfuddle e resolvi migrar para o bitbucket, mas como fazer esta migração mantendo todo o histórico de commit e branches do repositório?

Como migrar um repositório git sem perder seu histórico?

O primeiro passo é fazer o clone do repositório original, para pegar todas as informações necessárias:

git clone url-do-repositorio.git

Agora você tem todos os arquivos e históricos do repositório no seu repositório git local. Vamos remover o repositório remoto (no meu caso, o unfuddle). Neste exemplo o nome do repositório remoto é "origin", substitua se necessário.

git remote rm origin

Agora vamos adicionar o novo repositório remoto (no meu caso, o do bitbucket):

git remote add origin git@bitbucket.org:gserrano/meurepositorio.git

Para finalizar, vamos dar um push de todos os dados do seu repositório local (recuperados do seu antigo repositório remoto) para o novo repositório remoto:

git push -u origin --all
git push -u origin --tags

Pronto, assim você não perde o histórico do seus repositórios GIT e tem liberdade para migrar de serviço se necessário.

Você também pode gostar:

]]>
Como ignorar arquivos no Git<br> http://odesenvolvedor.andafter.org/publicacoes/como-ignorar-arquivos-no-git.html http://odesenvolvedor.andafter.org/publicacoes/como-ignorar-arquivos-no-git.html#comments Mon, 19 May 2014 12:09:25 -0300 Guilherme Serrano git, desenvolvimento, programacao http://odesenvolvedor.andafter.org/publicacoes/como-ignorar-arquivos-no-git.html Faz algum tempo que estamos usando o Git para fazer deploy nos projetos da GS Solutions e um dos cuidados que isso exige é manter os arquivos de configuração do servidor de produção intactos.

Como ignorar arquivos no Git?

.gitignore

O modo mais fácil de ignorar arquivos no repositório é através do gitignore. O gitignore é uma lista que ignora qualquer arquivo que ainda não foi acompanhado pelo repositório através do git add. Veja a documentação (en).

Quando um arquivo já foi adicionado ao sistema de tracking muitas pessoas acham que o gitignore não está funcionando. Na verdade você precisa remover o arquivo do índice para que repositório pare de monitorar aquele arquivo.

Como fazer usar o .gitignore para um arquivo que já foi commitado?

Se um arquivo já foi adicionado e commitado não adianta somente adicionar ele no seu .gitignore, você precisa primeiro remover ele do sistema de tracking do git. Para isso utilize o comando abaixo:

git rm --cached config.json

No exemplo abaixo o git vai remover o cache/tracking do arquivo config.json e se ele estiver no .gitignore do repositório ele não será mais indexado nos commits.


Como ignorar um arquivo do repositório no git

Para arquivos de configuração eu prefiro que eles estejam no tracking do git, pois eles são parte do projeto e devem estar no repositório. Mas apesar de estarem no repositório, não quero enviar para o repositório minhas alterações locais. Para isso podemos pedir para que o git considere que determinados arquivos não foram alterados alterando o índice do git manualmente.

Mantendo o exemplo do arquivo config.json vamos supor que ele não está no seu gitignore e você fez alterações para o ambiente de desenvolvimento e não quer correr o risco de commitar estas mudanças.

Diga para o git considerar que aquele arquivo não foi alterado com o seguinte comando:

git update-index --assume-unchanged config.json

Agora seu repositório vai considerar que este arquivo não foi alterado mesmo que você atualize ele inúmeras vezes. Se você precisa dar commit em alguma alteração no arquivo é só remover o status de "não alterado" deste arquivo no índice do repositório com a seguinte linha de código:

git update-index --no-assume-unchanged config.json


Para arquivos de configuração eu prefiro utilizar o --assume-unchanged. Deixo o .gitignore para arquivos de uploads do projetos, cache e demais arquivos que não fazem parte do projeto.

Como vocês lidam com arquivos de configuração no repositório? Deixe dicas nos comentários!

]]>
Palestra sobre Componetização de CSS e HTML (Front in Sampa 2013) http://odesenvolvedor.andafter.org/publicacoes/palestra-sobre-componetizacao-de-css-e-html-front-in-sampa-2013.html http://odesenvolvedor.andafter.org/publicacoes/palestra-sobre-componetizacao-de-css-e-html-front-in-sampa-2013.html#comments Thu, 24 Apr 2014 14:41:51 -0300 Guilherme Serrano front-end, programacao, css, html http://odesenvolvedor.andafter.org/publicacoes/palestra-sobre-componetizacao-de-css-e-html-front-in-sampa-2013.html

Saiu o vídeo oficial da minha palestra no FrontInSampa 2013, sobre componetização de HTML e CSS e a polêmica sobre orientação a objetos com CSS.

E os slides:


E você usa componetização de CSS e HTML? Que ferramentas utiliza para isso?

]]>
Datas recursivas com PHP http://odesenvolvedor.andafter.org/publicacoes/datas-recursivas-com-php.html http://odesenvolvedor.andafter.org/publicacoes/datas-recursivas-com-php.html#comments Thu, 27 Mar 2014 11:03:08 -0300 Guilherme Serrano php, datas, programacao, web http://odesenvolvedor.andafter.org/publicacoes/datas-recursivas-com-php.html Em um dos projetos que estou trabalhando eu precisei trabalhar com datas recursivas a partir de uma data inicial e de uma periodicidade. 

Datas no PHP

Não vou abordar a fundo como trabalhar com datas no PHP, apenas como adicionar determinado número de dias em uma data. Se você não tem ideia de como trabalhar com datas no PHP, recomendo começar pelo manual do PHP date() date(). 

Mas o conceito de recursividade é simples e vou explicar abaixo o funcionamento de cada passo para gerar datas repetidas com PHP.

Formatando a data de hoje

Primeiro, o básico de formatação de datas com PHP. Estou trabalhando com MySQL (date), portanto trabalho com a seguinte formatação.

date('Y-m-d');

O código acima vai retornar a data de hoje no formato ano-mes-dia.

Adicionar dias em uma data

Para dar início a recursividade a lógica é: tenho uma data e preciso saber qual será a data daqui X dias, e assim sucessivamente. Para adicionar dias a uma data usamos a função strtotime (veja o manual) do PHP junto com date. 

No exemplo abaixo o resultado deve ser a data formatada para exatamente daqui a 7 dias.

date('Y-m-d', strtotime(date('Y-m-d') . '+7 days'));


Recursividade de datas

Com estes 2 conceitos básicos sobre datas no PHP e um pouco de criatividade você consegue gerar datas recursivas no PHP

No exemplo abaixo, vou pegar as próximas 10 datas a partir de hoje, com uma periodicidade de 15 dias e colocar no array $myDates;

$lastDate = date('Y-m-d');
$myDates = array();

for ($x=0; $x<=10; $x++){
  $myDates[] = $lastDate;
  $lastDate = date('Y-m-d', strtotime($lastDate . ' +15 days'));
}


Recursividade de datas por período

Indo um pouco mais longe, você pode fazer seleções de datas dentro de janela de tempo usando quase a mesma lógica - mas deve tomar cuidado para não gerar loop infinito no seu código.

No exemplo abaixo, quero retornar todas as datas a partir de hoje, contando de 15 em 15 dias, até a data limite de 4 de Dezembro.

$lastDate = date('Y-m-d');
$endDate = '2014-12-04';
$myDates = array();
$finished = false;
while(!$finished){
  $lastDate = date('Y-m-d', strtotime($lastDate . ' +15 days')); 
  if(strtotime($lastDate) > strtotime($endDate)){ $finished = true; break; } 
  $myDates[] = $lastDate;
}

Usando a mesma verificação do $endDate você pode configurar uma data inicial e uma final, selecionando apenas as datas dentro deste período.


Talvez existe algum método mais eficiente de fazer isso. Quando pesquisei sobre o assunto encontrei a biblioteca When, mas ela não era exatamente o que eu queria. 

Se você precisa saber quando serão as próximas Quarta-Feiras que irão cair em um dia 2 de Fevereiro, é a biblioteca para você, vale conferir. Se você optar pela When tome cuidado com os loops infinitos que ela pode gerar.

]]>
Como verificar o número de variáveis passadas em um shellscript? http://odesenvolvedor.andafter.org/publicacoes/como-verificar-o-numero-de-variaveis-passadas-em-um-shellscript.html http://odesenvolvedor.andafter.org/publicacoes/como-verificar-o-numero-de-variaveis-passadas-em-um-shellscript.html#comments Sun, 09 Mar 2014 12:52:07 -0300 Guilherme Serrano shellscript, linux, unix, automatizacao http://odesenvolvedor.andafter.org/publicacoes/como-verificar-o-numero-de-variaveis-passadas-em-um-shellscript.html O que mais me traz satisfação como desenvolvedor é gerar automatização de tarefas. Desenvolver ferramentas e rotinas que possibilitem que minha equipe ou meus clientes trabalhem menos para alcançar determinado objetivo.

Desde gerar backups até configurar um ambiente de desenvolvimento ou produção. Hoje fui implementar umas alterações no shellscript para criar um site no apache e criar as pastas no meu ambiente local, mas para isso precisava verificar o número de variáveis passadas pelo usuário antes de continuar a execução do script. 

Como verificar o número de variáveis passadas no shellscript?

Para ter o número de variáveis que um shelscript recebeu é bem simples:

$#

Sabendo disso basta você fazer uma comparação para validar se o número de variáveis é o que você esperava. No exemplo abaixo o script finaliza a execução se o usuário não passar pelo menos 2 variáveis:

if [ $# -lt 2 ]; then
echo 'Necessário 2 variáveis'
exit 0
fi

Uma dica do Bruno para tornar o código mais legível é fazer a comparação da seguinte forma, e também usar exit 1 para quando der erro, fica assim:

if [[ $# < 2 ]] then
echo 'Necessário 2 variáveis'
exit 1
fi
Usar o exit 1 quando algo der errado no seu script impede que outros scripts sejam executados na sequência se o seu deu errado, por exemplo:

seu_script.sh && seu_segundo_script.sh

Se algum erro acontecer no seu_script o seu_segundo_script não será executado.

Agora consigo validar a execução de qualquer shellscript e evitar erros. Se voc6e tem uma maneira diferente de fazer esta verificação deixe nos comentários!

]]>