João Pinto Neto Desenvolvimento Web

28abr/120

Arduino com Eclipse sem complicação

Arduino com Eclipse

Suas sketches já não cabem na IDE do Arduino? Tente o Eclipse.
O tutorial a seguir foi testado em ambiente Linux (Debian squeeze), mas acredito que não seja muito difícil adaptar para windows.

Faça o download do SDK do Arduino e descompacte em /opt/arduino:

http://arduino.cc/en/Main/Software

Instalar as seguintes dependências:
# aptitude install avrdude binutils-avr gcc-avr avr-libc gdb-avr

Faça o download do Makefile:

http://ed.am/dev/make/arduino-mk/arduino.mk

Java:
# aptitude install openjdk-6-jre

Eclipse IDE for C/C++ e descompacte na sua home ~/eclipse-cpp:

http://www.eclipse.org/downloads/

Abra o Eclipse, em Workspace, troque para /home/SEU_USUARIO/workspace-cpp e quando terminar de carregar o Eclipse, feche a aba welcome.

Crie um projeto File > New > C++ Project
Defina o nome do projeto Project Name: Blink
Clique no botão Next

Na próxima tela, desmarque a opção Debug e clique em Finish:

Clique com o botão direito no projeto que criamos Blink e abra o menu Properties
Em C/C++ Build, clique em Builder Settings, desative a opção Generate Makefiles automatically e em Build directory deixe: ${workspace_loc:/Blink}

Em C/C++ General, abra Path and Simbols e em Includes clique em Add...e adicione:
/opt/arduino/hardware/arduino/cores/arduino
/opt/arduino/hardware/arduino/variants/standard
/opt/arduino/libraries

De Ok para fechar as propriedades.

Agora abra o menu Window > Preferences
Em General > Content Types, no lado direito, em Text > C Source File > C++ Source File, adicione a extenção *.ino

De Ok para fechar as preferências.

Copie o arquivo makefile para /home/SEU_USUARIO/workspace-cpp/Blink e atualize o projeto (F5)

Clique com o botão direito no projeto Blink e abra o menu New > File e em File Name digite Blink.ino (O nome do sketch, deve ser o mesmo nome da pasta).

Clique com o botão direito no projeto Blink e abra o menu Properties. Em C/C++ General > Code Analysis, escolha Use project settings e desmarque Syntax and Semantic Errors e clique em Ok.

Clique com o botão direito no projeto Blink e escolha o menu Build Project, o arquivo Makefile que fizemos o download, será evocado para construir o projeto.

Quando começarmos a incluir os headers de bibliotecas externas, o Eclipse não encontrará, mas logo após o Build do projeto ele consegue resolver o caminho.

E por fim, para fazermos o upload para sua rom, usando o avr-dude, entre com o seguinte comando:
$ cd /home/SEU_USUARIO/workspace-cpp/Blink
$ avrdude-pm328p -carduino -P/dev/ttyACM0 -b115200 -F -Uflash:w:Blink.hex:a

3dez/110

Faça seu próprio MVC

2nov/110

Repositório Git remoto em 5 minutos

Se você estiver utilizando uma distribuição baseada em Debian, instale os seguintes pacotes:

aptitude install openssh-server openssh-client git git-core git-doc git-gui gitk

Senão, garanta que o serviço e o cliente SSH estão funcionando.

Configurando o "servidor remoto":

$ cd /opt
$ mkdir git</code>
$ cd /opt/git
$ mkdir projeto.git
$ cd /opt/git/projeto.git
$ git --bare init
Initialized empty Git repository in /opt/git/projeto.git/
$ git config core.sharedrepository 1
$ find objects -type d -exec chmod 02770 {} \;

Configurando o ambiente de desenvolvimento:

$ cd /var/www
$ mkdir projeto
$ cd projeto</code>
$ touch index.php
$ git init
$ git add *
$ git commit -m "Initial commit"
create mode 100755 index.php
$ git remote add origin ssh://usuario@localhost/opt/git/projeto.git
$ git push origin master
Counting objects: 1, done.
Compressing objects: 100% (1/1), done.
Writing objects: 100% (1/1), 1.18 MiB | 1.38 MiB/s, done.
Total 1 (delta 375), reused 0 (delta 0)
To ssh://usuario@localhost/opt/git/projeto.git
* [new branch] master -&gt; master

Veja alguns links para você aprender mais como utilizar esta ferramenta de controle de versões:

Página do projeto:
http://git-scm.com/

Manual do usuário:
http://schacon.github.com/git/user-manual.html

É isso!

16mai/110

Validação do campo tinyMCE com saída no jQuery ui

Usando o jQuery Validation Plugin (http://bassistance.de/jquery-plugins/jquery-plugin-validation/) podemos fazer validações em formulários de uma forma bem elegamte. Melhor ainda quando usamos essa saída de erros em uma janela modal personalizada, no jQuery UI.

Para validar um campo tinymce, precisamos usar a função tinyMCE.triggerSave que verifica se o hypertexto é nulo, essa função tem que ser chamada antes do validador, eu usei no "bind" .submit(function() { tinyMCE.triggerSave(); }).

O bind no invalid-form.validate é para não usar o comportamento padrão (com showErrors). Ele chama o popup da mensagem de erro, apenas quando for submit e estiver com dados inválidos preenchidos. Caso contrário (não usando esse bind e usando showErrors), o popup será exibido no onchange dos inputs, quando estiver com algum campo inválido.

Vejam como ficou:

tinyMCE.init({
	mode     : "textareas",
	theme    : "simple",
	language : "pt",
	width    : "600",
	height   : "150",
	onchange_callback: function(editor) {
		tinyMCE.triggerSave();
	}
});

$(document).ready(function() {
	$("#message").dialog({
		modal: true,
		autoOpen: false,
		title: "Erros no formulário",
		buttons: {
			Fechar: function() {
				$(this).dialog("close");
			}
		}
	});

	$("form").bind("invalid-form.validate", function(e, validator) {
		tinyMCE.triggerSave();
		if (validator.numberOfInvalids()) {
			$("#message").dialog("open");
		}
	})
	.submit(function() { tinyMCE.triggerSave(); })
	.validate({
		debug: true,
		errorPlacement: function(error, element) {
			error.prependTo($("#message"));
		},
		errorLabelContainer: $("#message ul"),
		wrapper: "li",
		meta: "validate",
		submitHandler: function(form) {
			form.submit();
	    },
		rules: {
			"data[Questao][titulo]": "required"
		},
		messages: {
			"data[Questao][titulo]": "A questão não pode estar em branco"
		}
	});

});
10mai/110

Login por email ou username

No cakephp, se estivermos usando o AuthComponent para autenticar os usuários na aplicação, por padrão, devemos criar um formulário de login passando username e password (que equivalem ao campo username e password da tabela User). Mas, sabendo que podemos definir no /app/app_controller quais serão os campos para username e password (e também, outras definições) mais ou menos igual a isso:

<?php
class AppController extends Controller
{
    public $components = array('Auth', 'Session');
    public $helpers = array('Html', 'Form', 'Session');
    public function beforeFilter()
    {
        parent::beforeFilter();
        $this->Auth->allow('display');
        Security::setHash('md5');
        $this->Auth->userModel = 'Usuario';
        $this->Auth->loginAction = array('controller' => 'usuarios', 'action' => 'login');
        $this->Auth->loginRedirect = array('controller' => 'usuarios', 'action' => 'home');
        $this->Auth->logoutRedirect = array('controller' => 'usuarios', 'action' => 'login');
        $this->Auth->loginError = "Login e senha não conferem!";
        $this->Auth->authError = "Desculpe, você está sem acesso!";
    }
...
}

Também podemos utilizar duas formas de efetuar comparar login, uma por e-mail e outra por cpf, ou nome_usuario, ou qualquer outro campo. Fica mais ou menos igual a isso:

<?php
class AppController extends Controller
{
    public $components = array('Auth', 'Session');
    public $helpers = array('Html', 'Form', 'Session');
    public function beforeFilter()
    {
        parent::beforeFilter();
        $this->Auth->allow('display');
        Security::setHash('md5');
        $this->Auth->userModel = 'Usuario';
        $this->Auth->loginAction = array('controller' => 'usuarios', 'action' => 'login');
        $this->Auth->loginRedirect = array('controller' => 'usuarios', 'action' => 'home');
        $this->Auth->logoutRedirect = array('controller' => 'usuarios', 'action' => 'login');
        /**
         * Este trexo, faz a verificação, se o usuário está tentando fazer login por e-mail ou por cpf
         */
        if (isset($this->data['Usuario']['usuario']) && Validation::email($this->data['Usuario']['usuario'])) {
            $this->data['Usuario']['email'] = $this->data['Usuario']['usuario'];
            $this->Auth->fields = array('username' => 'email', 'password' => 'senha');
        } else {
            $this->data['Usuario']['cpf'] = $this->data['Usuario']['usuario'];
            $this->Auth->fields = array('username' => 'cpf', 'password' => 'senha');
        }

        $this->Auth->loginError = "Login e senha não conferem!";
        $this->Auth->authError = "Desculpe, você está sem acesso!";
    }
    ...
}
18jun/104

Instalando PHPUnit no windows

Para instalar PHPUnit no windows, devemos instalar o PEAR executando o script go-pear.bat que encontra-se no diretório de instalação do PHP

C:\>go-pear
Are you installing a system-wide PEAR or a local copy?
(system|local) [system] : (ENTER)
Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.
1. Installation base ($prefix)                   : C:\php
2. Temporary directory for processing            : C:\php\tmp
3. Temporary directory for downloads             : C:\php\tmp
4. Binaries directory                            : C:\php
5. PHP code directory ($php_dir)                 : C:\php\pear
6. Documentation directory                       : C:\php\docs
7. Data directory                                : C:\php\data
8. User-modifiable configuration files directory : C:\php\cfg
9. Public Web Files directory                    : C:\php\www
10. Tests directory                               : C:\php\tests
11. Name of configuration file                    : C:\Windows\pear.ini
12. Path to CLI php.exe                           : C:\php

1-12, 'all' or Enter to continue: (ARRUME OS PATHS)
Beginning install...
Configuration written to C:\Windows\pear.ini...
Initialized registry...
Preparing to install...

installing phar://go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.3.3.tar...
installing phar://go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.2.3.tar...
installing phar://go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.9.0.tar...
installing phar://go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.0.2.tar...
installing phar://go-pear.phar/PEAR/go-pear-tarballs/XML_Util-1.2.1.tar...

install ok: channel://pear.php.net/Archive_Tar-1.3.3
install ok: channel://pear.php.net/Console_Getopt-1.2.3
install ok: channel://pear.php.net/Structures_Graph-1.0.2
install ok: channel://pear.php.net/XML_Util-1.2.1
install ok: channel://pear.php.net/PEAR-1.9.0

PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

The 'pear' command is now at your service at c:\php\pear.bat

* WINDOWS ENVIRONMENT VARIABLES *
For convenience, a REG file is available under c:\php\PEAR_ENV.reg

This file creates ENV variables for the current user.
Double-click this file to add it to the current user registry.

Press any key to continue . . .

Adicione os repositórios do PHPUnit e atualize-os:

C:\>pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded

C:\>pear channel-discover pear.symfony-project.com
Adding Channel "pear.symfony-project.com" succeeded
Discovery of channel "pear.symfony-project.com" succeeded

C:\>pear update-channels
Updating channel "doc.php.net"
Channel "doc.php.net" is up to date
Updating channel "pear.php.net"
Channel "pear.php.net" is up to date
Updating channel "pear.phpunit.de"
Channel "pear.phpunit.de" is up to date
Updating channel "pear.symfony-project.com"
Channel "pear.symfony-project.com" is up to date
Updating channel "pecl.php.net"
Channel "pecl.php.net" is up to date

C:\>pear upgrade-all
Will upgrade channel://pear.php.net/archive_tar
Will upgrade channel://pear.php.net/pear
Will upgrade channel://pear.php.net/structures_graph
downloading Archive_Tar-1.3.7.tgz ...
Starting to download Archive_Tar-1.3.7.tgz (17,610 bytes)
......done: 17,610 bytes
downloading PEAR-1.9.1.tgz ...
Starting to download PEAR-1.9.1.tgz (293,587 bytes)
...done: 293,587 bytes
downloading Structures_Graph-1.0.3.tgz ...
Starting to download Structures_Graph-1.0.3.tgz (30,191 bytes)
...done: 30,191 bytes
upgrade-all ok: channel://pear.php.net/Archive_Tar-1.3.7
upgrade-all ok: channel://pear.php.net/Structures_Graph-1.0.3
upgrade-all ok: channel://pear.php.net/PEAR-1.9.1

PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

Instalando PHPUnit 3.4.14

C:\>pear install phpunit/PHPUnit
Did not download optional dependencies: pear/Image_GraphViz, pear/Log, symfony/YAML,
use --alldeps to download automatically

phpunit/PHPUnit can optionally use package "pear/Image_GraphViz" (version >= 1.2.1)
phpunit/PHPUnit can optionally use package "pear/Log"
phpunit/PHPUnit can optionally use package "symfony/YAML" (version >= 1.0.2)
phpunit/PHPUnit can optionally use PHP extension "soap"
phpunit/PHPUnit can optionally use PHP extension "xdebug" (version >= 2.0.5)

downloading PHPUnit-3.4.14.tgz ...
Starting to download PHPUnit-3.4.14.tgz (254,983 bytes)
.....................................................done: 254,983 bytes
install ok: channel://pear.phpunit.de/PHPUnit-3.4.14

É isso! Espero que gostem.

 

10jun/100

Contatos do Google usando curl do php

Neste artigo mostrarei um exemplo de como pegar os contatos de uma conta Google, sem usar o Zend Gdata. Utilizando o CURL do PHP, criei uma classe controller para cakephp, assim é possível fazer uma requisição Ajax, com retorno Json e tratar esse retorno da maneira que bem entender. Eu li em outros blogs como fazer funcionar o Zend Framework com Zend Gdata no cakephp, se você estiver utilizando o Zend Framework, acredito que seja a melhor maneira, mas se não quiser utilizar o Zend Gdata, aqui está uma alternativa:

<?php
class contactsController extends AppController {

    public $uses = null;

    public function index ()
    {
        $this->layout = '';
        $this->googleLogin('foo@exemple.com', 'MyPassword');

        //Retorno na tela para debugar
        echo '<pre>';
        print_r($this->getGoogleFriends());
        echo '</pre>';
    }

    public function googleLogin ($email, $password) {
        if ($this->Session->read('googleAuth')) {
            return true;
        }
        $data = array(
            'accountType' => 'GOOGLE',
            'Email' => $email,
            'Passwd' => $password,
            'service' => 'cp',
            'source' => 'test-oauth-1.0',
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/accounts/ClientLogin');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        $output = curl_exec($ch);
        $info = curl_getinfo($ch);
        preg_match('/Auth=.+/', $output, $tempArray);
        if ($info['http_code'] != 200 or empty($tempArray)) {
            return false;
        }
        $auth = 'Authorization: GoogleLogin auth=' . substr($tempArray[0], 5);
        $this->Session->write('googleAuth', $auth);
        return true;
    }

    public function getGoogleFriends ($maxResults = 10000) {
        $url = "http://www.google.com/m8/feeds/contacts/default/full?max-results={$maxResults}&alt=json";
        $output = $this->getGoogleResource($url);
        if (empty($source)) {
            return false;
        }
        return $output;
    }

    public function getGoogleResource ($url) {
        if (is_null($this->Session->read('googleAuth'))) {
            return false;
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($this->Session->read('googleAuth')));
        $output = curl_exec($ch);
        $info = curl_getinfo($ch);
        if ($info['http_code'] != 200) {
            return false;
        }
        return $output;
    }

}
?>

Espero que gostem =]
[]'s

 

16abr/101

Cores nas linhas do Grid ExtJS

Uma coisa muito difícil de se encontrar nos tutoriais de ExtJs é como colorir as linhas de uma grid conforme um determinado dado de uma linha muda, aqui estou para salvar você, com minha humilde experiência em ExtJs vos apresento:

Primeiramente, crie os estilos:

&lt;style type=&quot;text/css&quot;&gt;
.red {background:red !important;}
.green {background:green !important;}
.default-color {background:silver !important;}
&lt;/style&gt;

depois o grid:

	var store = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({url: '/principais/getprocessosexecucao'}),
        reader: new Ext.data.JsonReader({
            root: 'data',
            id: 'id'
        }, [
            {name: 'opcoes', mapping: 'opcoes'},
            {name: 'comando', mapping: 'Agendamento.comando'},
            {name: 'inicio', mapping: 'Execucao.inicio'},
            {name: 'fim', mapping: 'Execucao.fim'},
            {name: 'status', mapping: 'Execucao.status'}
        ]),
        remoteSort: false
    });

	var grid = new Ext.grid.EditorGridPanel({
		   frame: false,
		   title: 'Tarefas agendadas',
		   height: 300,
		   store: store,
		   stripeRows: true,
           loadMask: true,
           selModel: new Ext.grid.RowSelectionModel({singleSelect: true}),
		   columns: [
                      { header: 'Opções', dataIndex: 'opcoes', width: 100 },
		      { header: 'Agendamento', width: 190, sortable: true, dataIndex: 'comando' },
		      { header: 'Inicio', width: 120, sortable: true, dataIndex: 'inicio' },
		      { header: 'Fim', width: 120, sortable: true, dataIndex: 'fim' },
		      { header: 'Status', width: 80, sortable: true, dataIndex: 'status' }
		    ],
            /* O segredo está aqui: viewConfig */
            viewConfig: { getRowClass: function(record) { return getRowClass(record); } },
		    renderTo: 'topic-grid'
		});

	store.load();

	grid.render('topic-grid');

depois de renderizado o grid, criamos uma função que vai trocar as cores das linhas:

    function getRowClass(record) {
        if (record.data.status != 0) {
            return 'red';
        }

        if (record.data.TestCell &lt;= 5) {
            return 'green';
        }

        return 'default-color';
    }

Espero que gostem =]
[]'s

13abr/100

tratando submit do form com jQuery

Hoje tive que tratar um formulário e estou postando como tratar um formulário com jQuery. É muito simples, você põe o ID do formulário. No evento submit você intercepta e faz o tipo de tratamento que quizer, a melhor forma de exemplificar este método inteligente de validação de formulário é mostrando, segue o código-fonte para vocês analizarem... E outra pessoal, aqui não quero ensinar jQuery, se virem, o código fonte já ta bom demais.

Espero que gostem,
Ta aí

$('#agendamento').submit(function() {
    var periodo_dia = ($('#PrincipaisPeriodo2').is(':checked'));

   /**
    * Se for agendamento para 1 dia verificar se tem tempo definido
    * não tem coringa
    */
    if ( periodo_dia ) {
        var teste  = $('#hora :selected').text() != '*'
                  &amp;&amp; $('#minuto :selected').text() != '*';

        if ( teste ) {
            var data = $('#data').val();

            if ( data != '' ) {
                // Pode passar
            } else {
                alert('Verifique o campo Data');
                return false;
            }

        } else {
            alert('Verifique os campos: Data / Hora / Minuto');
            return false;
        }

    }

    var comando = $.trim($('#AgendamentoComando').val());

    if ( comando != '' ) {
        // Pode passar
    } else {
        alert('Verifique o comando');
        return false;
    }
});
8abr/100

Extjs combo selecionado valor padrão

Uma coisa muito difícil de se encontrar nos tutoriais de ExtJs é como colorir as linhas de uma grid conforme um determinado dado de uma linha muda, aqui estou para salvar você, com minha humilde experiência em ExtJs vos apresento:

Primeiramente, crie os estilos:

<style type="text/css">
.red {background:red !important;}
.green {background:green !important;}
.default-color {background:silver !important;}
</style>

depois o grid:

	var store = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({url: '/principais/getprocessosexecucao'}),
        reader: new Ext.data.JsonReader({
            root: 'data',
            id: 'id'
        }, [
            {name: 'opcoes', mapping: 'opcoes'},
            {name: 'comando', mapping: 'Agendamento.comando'},
            {name: 'inicio', mapping: 'Execucao.inicio'},
            {name: 'fim', mapping: 'Execucao.fim'},
            {name: 'status', mapping: 'Execucao.status'}
        ]),
        remoteSort: false
    });

	var grid = new Ext.grid.EditorGridPanel({
		   frame: false,
		   title: 'Tarefas agendadas',
		   height: 300,
		   store: store,
		   stripeRows: true,
           loadMask: true,
           selModel: new Ext.grid.RowSelectionModel({singleSelect: true}),
		   columns: [
                      { header: 'Opções', dataIndex: 'opcoes', width: 100 },
		      { header: 'Agendamento', width: 190, sortable: true, dataIndex: 'comando' },
		      { header: 'Inicio', width: 120, sortable: true, dataIndex: 'inicio' },
		      { header: 'Fim', width: 120, sortable: true, dataIndex: 'fim' },
		      { header: 'Status', width: 80, sortable: true, dataIndex: 'status' }
		    ],
            /* O segredo está aqui: viewConfig */
            viewConfig: { getRowClass: function(record) { return getRowClass(record); } },
		    renderTo: 'topic-grid'
		});

	store.load();

	grid.render('topic-grid');

depois de renderizado o grid, criamos uma função que vai trocar as cores das linhas:

    function getRowClass(record) {
        if (record.data.status != 0) {
            return 'red';
        }

        if (record.data.TestCell <= 5) {
            return 'green';
        }

        return 'default-color';
    }

Espero que gostem =]
[]'s