<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Log4Dev &#187; Tutorial</title>
	<atom:link href="http://log4dev.com/category/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://log4dev.com</link>
	<description></description>
	<lastBuildDate>Mon, 03 Oct 2011 22:20:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
	<div id='fb-root'></div>
					<script type='text/javascript'>
						window.fbAsyncInit = function()
						{
							FB.init({appId: null, status: true, cookie: true, xfbml: true});
						};
						(function()
						{
							var e = document.createElement('script'); e.async = true;
							e.src = document.location.protocol + '//connect.facebook.net/pt_BR/all.js';
							document.getElementById('fb-root').appendChild(e);
						}());
					</script>	
						<item>
		<title>HgInit</title>
		<link>http://log4dev.com/2010/04/20/hginit/</link>
		<comments>http://log4dev.com/2010/04/20/hginit/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 15:02:50 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Ferramentas]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=736</guid>
		<description><![CDATA[Eu já twittei sobre isso, e já salvei no del.icio.us do Log4Dev. Mas dada a qualidade do material, acho que vale a pena comentar rapidamente aqui. O Joel Spolsky escreveu um excelente artigo/tutorial sobre o Mercurial, sistema de controle de versão distribuído (DCVS para os íntimos) que anda na moda ultimamente. O endereço é http://hginit.com. [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/04/20/hginit/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Eu já <a href="http://twitter.com/log4dev/status/9870112215">twittei</a> sobre isso, e já salvei no <a href="http://delicious.com/log4dev">del.icio.us do Log4Dev</a>. Mas dada a qualidade do material, acho que vale a pena comentar rapidamente aqui. O <strong>Joel Spolsky </strong>escreveu um excelente artigo/tutorial sobre o <a href="http://mercurial.selenic.com/">Mercurial</a>, sistema de controle de versão distribuído (DCVS para os íntimos) que anda na moda ultimamente.</p>

<p><a href="http://log4dev.com/wp-content/uploads/2010/04/hg.jpeg"><img class="aligncenter size-full wp-image-737" title="Hg Init" src="http://log4dev.com/wp-content/uploads/2010/04/hg.jpeg" alt="Hg Init" width="275" height="141" /></a></p>

<p>O endereço é <a title="HgInit" href="http://hginit.com">http://hginit.com</a>. O conteúdo serve tanto para aqueles que já se convenceram da utilidade e precisam entender o modus operandi (que foi o meu caso), como para os céticos que não deram muita bola e precisam ser convencidos.</p>

<p>E acreditem: o texto convenceu até <strong>The One Who Can&#8217;t Be Named</strong>.</p>

<p>Não é pouca porcaria não&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/04/20/hginit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pro Git</title>
		<link>http://log4dev.com/2009/10/05/pro-git/</link>
		<comments>http://log4dev.com/2009/10/05/pro-git/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 18:29:53 +0000</pubDate>
		<dc:creator>Raphael Lullis</dc:creator>
				<category><![CDATA[Ferramentas]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=660</guid>
		<description><![CDATA[Semana passada eu estava buscando material de referência para algumas configurações do Git e achei um livro muito bom, chamado Pro Git. O livro foi escrito por Scott Chacon e publicado pela Apress. Como o livro foi publicado sob a licença do Creative Commons, está aberto para traduções e até mesmo adaptações. No verdadeiro espírito [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2009/10/05/pro-git/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Semana passada eu estava buscando material de referência para algumas configurações do Git e achei um livro muito bom, chamado <a href="http://progit.org/">Pro Git</a>. O livro foi escrito por Scott Chacon e publicado pela Apress. Como o livro foi publicado sob a licença do Creative Commons, está aberto para traduções e até mesmo adaptações.</p>

<p>No verdadeiro espírito de <em>eating your own dog food</em>, o autor do livro colocou o código-fonte do livro no GitHub e qualquer pessoa pode fazer um fork, para fazer modificações no material. Vi que a tradução para pt_br foi iniciada, mas ainda estava tímida. Ato contínuo, fiz um <a href="http://github.com/lullis/progit">fork</a> do projeto e comecei a fazer a tradução.</p>

<p>A minha idéia é completar a tradução e colocar aqui no site, em uma seção separada. Obviamente, não é algo que vai ficar pronto em uma semana, ainda mais se eu fizer sozinho. Então, fica a dica: se você quer aprender a mexer com o Git, ajudar a fazer a tradução do livro <em>enquanto</em> usa o Git é o casamento perfeito entre teoria e prática.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2009/10/05/pro-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RampUp</title>
		<link>http://log4dev.com/2009/05/19/rampup/</link>
		<comments>http://log4dev.com/2009/05/19/rampup/#comments</comments>
		<pubDate>Tue, 19 May 2009 20:02:13 +0000</pubDate>
		<dc:creator>Alexandre Barbosa</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=567</guid>
		<description><![CDATA[Dica rápida para aqueles que estão interessados em aprender sobre tecnologias de desenvolvimento da microsoft (ASP.NET, VB, desenvolvimento para Windows Mobile, etc) &#8211; RampUp. Acabei de me inscrever na &#8220;trilha&#8221; de desenvolvimento de aplicações mobile. A organização do curso me pareceu bastante boa, dividido em várias etapas, com exemplos e exercícios. Ao fim de cada [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2009/05/19/rampup/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Dica rápida para aqueles que estão interessados em aprender sobre tecnologias de desenvolvimento da microsoft (ASP.NET, VB, desenvolvimento para Windows Mobile, etc) &#8211; <a href="http://msdn.microsoft.com/en-us/rampup/default.aspx" target="_blank">RampUp</a>.</p>

<p>Acabei de me inscrever na &#8220;trilha&#8221; de <strong>desenvolvimento de aplicações mobile</strong>. A organização do curso me pareceu bastante boa, dividido em várias etapas, com exemplos e exercícios. Ao fim de cada &#8220;trilha&#8221; você recebe recompensas  - descontos em certificações, por exemplo.</p>

<p>Fica aqui a sugestão. Se quiserem, deixem aqui comentários sobre o que acharam do RampUp.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2009/05/19/rampup/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Para que complicar se podemos simplificar?</title>
		<link>http://log4dev.com/2009/02/21/para-que-complicar-se-podemos-simplificar/</link>
		<comments>http://log4dev.com/2009/02/21/para-que-complicar-se-podemos-simplificar/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 02:31:50 +0000</pubDate>
		<dc:creator>Leonardo Garcia</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[aplicativo]]></category>
		<category><![CDATA[associar]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[simplificar]]></category>
		<category><![CDATA[tipo de arquivo]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=439</guid>
		<description><![CDATA[Até para fazer um contraponto em relação aos meus dois artigos anteriores (aqui e aqui), é bom falar um pouco sobre as decisões corretas na evolução dos programas que vivenciei recentemente. Até porque o mundo não é feito só de erros, não é mesmo? O problema é que nós sempre guardamos mais na memória as [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2009/02/21/para-que-complicar-se-podemos-simplificar/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Até para fazer um contraponto em relação aos meus dois artigos anteriores (<a href="http://log4dev.com/2009/02/13/a-nova-ortografia-e-o-redesenho-de-software/">aqui</a> e <a href="http://log4dev.com/2009/02/18/para-que-facilitar-se-podemos-complicar-2/">aqui</a>), é bom falar um pouco sobre as decisões corretas na evolução dos programas que vivenciei recentemente. Até porque o mundo não é feito só de erros, não é mesmo? O problema é que nós sempre guardamos mais na memória as coisas negativas. Ou, na verdade, as coisas positivas nem sempre são notadas, já que elas facilitam a nossa vida.</p>

<p>Recentemente eu tive uma experiência muito interessante com o Gnome do Fedora 10. Em geral, em versões anteriores do Gnome, associar um tipo de arquivo a um determinado aplicativo era uma tarefa não muito trivial (ou pelo menos eu não tinha achado uma solução mais fácil para isso). Quando precisava associar um tipo de arquivo a um aplicativo eu tinha que achar onde ficava o arquivo texto de configuração que o Gnome utilizava para guardar este tipo de informação e editá-lo manualmente. Nada fácil. Muito menos para usuários comuns, que, em geral, não tem traquejo com arquivos de configuração ou nem imaginam que eles existem.</p>

<p>O problema é que quando migrei para o Fedora 10, fui logo procurando este arquivo para alterar algumas das associações padrão do Fedora que não me agradam muito. Até achei um arquivo que parecia fazer isso. Mas depois de editá-lo não obtive o resultado esperado&#8230;</p>

<p>Já estava até perdendo minhas esperanças quando, nem me lembro mais porque, decidi clicar com o botão direito em um arquivo e escolher a opção &#8220;Propriedades&#8221; no pop-up menu. Não é que na janela de propriedades do arquivo existe uma aba específica para você definir qual programa o Gnome deve utilizar para abrir aquele tipo de arquivo!? Extremamente fácil (e devo confessar, intuitivo). Minha mente viciada com procedimentos mais complicados não foi capaz de sacar qual seria o procedimento mais fácil e intuitivo neste caso.</p>

<p>O pior é que depois eu fique pensando que eu acho que já tinha visto esta opção lá em versões anteriores do Gnome. Ou seja, provavelmente eu estava viciado na solução difícil para o problema.</p>

<p>E é aí, meus caros leitores, onde mora o perigo: às vezes nossa mente fica viciada em enxergar o problema do ponto de vista que estamos acostumados. Sabe aquele papo bem estadunidense de &#8220;pensar fora da caixa&#8221;? Pois é, ele é bem apropriado neste contexto. Sempre vale a pena pararmos para ver se não existe realmente uma maneira mais fácil e intuitiva de fazermos as coisas.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2009/02/21/para-que-complicar-se-podemos-simplificar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Para que facilitar se podemos complicar</title>
		<link>http://log4dev.com/2008/03/05/para-que-facilitar-se-podemos-complicar/</link>
		<comments>http://log4dev.com/2008/03/05/para-que-facilitar-se-podemos-complicar/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 22:51:37 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Linux Ferramentas Redes]]></category>

		<guid isPermaLink="false">http://log4dev.com/2008/03/05/para-que-facilitar-se-podemos-complicar/</guid>
		<description><![CDATA[Por Ricardo Capitanio Estava eu com o pequeno problema de montar a infraestrutura necessária para acessar um repositório SVN por HTTPS. Traduzindo em miúdos: precisava configurar um &#8220;Virtual Host&#8221; com SSL no Apache. Não pretendo virar especialista em Linux, nem em Apache e muito menos em SSL. Apenas tentei fazer o óbvio em tempos de [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2008/03/05/para-que-facilitar-se-podemos-complicar/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div><strong>Por Ricardo Capitanio</strong></p>

<p>Estava eu com o pequeno problema de montar a infraestrutura necessária para acessar um repositório <strong>SVN  </strong>por <strong>HTTPS</strong>. Traduzindo em miúdos: precisava configurar um &#8220;Virtual Host&#8221; com <strong>SSL </strong>no <strong>Apache</strong>. Não pretendo virar especialista em Linux, nem em Apache e muito menos em SSL. Apenas tentei fazer o óbvio em tempos de Internet: achar um tutorial para isso. E tutoriais não faltam.</p>

<p>Só que no meio do caminho tinha uma pedra: eu estava utilizando o Kubuntu 7. Nos n+1 tutoriais que encontrei falavam de um tal de script <em>apache2-ssl-certificate </em> para a geração do certificado, inclusive os <em>Howtos</em> do <em>&#8220;Ubuntu Forums&#8221;.</em><em> </em>Procurei como de costume no <em>/usr/sbin</em>, mas o dito cujo não estava lá. Instalei novamente o pacote <em>apache2.2-commons,  </em>mas ele  teimou em não aparecer.</p>

<p>Foi quando novamente recorri ao Google e encontrei a <a href="https://launchpad.net/ubuntu/+source/apache2/+bug/77675" target="_blank">seguinte thread</a>, que discute justamente o problema descrito:
<blockquote>Bug #77675: apache2-ssl-certificate is nowhere to be found once apache2 is installed as of feisty.</blockquote>
Como em qualquer trhead relacionada à software livre, o leitor encontrará lá uma <em>emocionante</em> discussão, em que várias <em>soluções</em> paliativas são sugeridas. Lá pelas tantas, um post de um tal de <a href="https://launchpad.net/%7Eshawarma" target="_blank">Soren Hansen</a> (um dos colaboradores do Ubuntu) termina com a discussão:
<blockquote>I&#8217;m rejecting this bug, as the ssl-cert package provides make-ssl-cert and also usr/share/ssl-cert/ssleay.cnf.
If you feel that this is not sufficient, feel free to reopen this bug.</blockquote>
Muito bem! É um típico exemplo em que por algum motivo não se pensa no usuário.  A retirada do script deve ter algum motivo técnico, talvez economizar alguns KBytes. Mas isso me custou alguns minutos a mais somente para executar uma única ridícula linha do tutorial. Com certeza, a perda de tempo não só minha mas de outros vários usuários não foi levada em consideração.</p>

<p>Eu nunca terei uma distribuição Linux própria, mas se esse for o seu caso, pense bem antes de remover alguns KBytes da sua. Ah&#8230; a solução que adotei? Estava naquela thread, bem <a href="https://launchpad.net/ubuntu/+source/apache2/+bug/77675/comments/15" target="_blank">aqui.</a></p>

<p><strong>[Ricardo Capitanio é Engenheiro de Computação formado pela UNICAMP, e tem um longo registro de terrorismo contra call centers, Telefônica, Claro, e agora Ubuntu]</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2008/03/05/para-que-facilitar-se-podemos-complicar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Especial de Natal Log4Dev: construindo um site de notícias usando Python &#8211; Parte 3</title>
		<link>http://log4dev.com/2007/12/26/especial-de-natal-log4dev-construindo-um-site-de-noticias-usando-python-parte-3/</link>
		<comments>http://log4dev.com/2007/12/26/especial-de-natal-log4dev-construindo-um-site-de-noticias-usando-python-parte-3/#comments</comments>
		<pubDate>Wed, 26 Dec 2007 05:58:06 +0000</pubDate>
		<dc:creator>Raphael Lullis</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://log4dev.com/2007/12/26/especial-de-natal-log4dev-construindo-um-site-de-noticias-usando-python-parte-3/</guid>
		<description><![CDATA[Já falei muito. Vamos começar? Instalação O web.py é um módulo escrito em Python. Você pode instalá-lo junto com os outros pacotes de sua instalação em Python, ou pode simplesmente copiar a pasta com o código para algum local que esteja dentro do seu Python Path. A instalação direta pode ser feita pelos métodos já [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2007/12/26/especial-de-natal-log4dev-construindo-um-site-de-noticias-usando-python-parte-3/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Já falei muito. Vamos começar?
<h3>Instalação</h3>
O web.py é um módulo escrito em Python. Você pode instalá-lo junto com os outros pacotes de sua instalação em Python, ou pode simplesmente copiar a pasta com o código para algum local que esteja dentro do seu Python Path.</p>

<p>A instalação direta pode ser feita pelos métodos já tradicionais. Usando easy_install, por exemplo. Há pacotes fornecidos pela Debian, também.</p>

<p>Se você quiser, você pode baixar no site o código da <a href="http://webpy.org/static/web.py-0.22.tar.gz">última versão liberada</a>. Se fizer isso, você vai pegar a pasta &#8220;web&#8221; e colocar no na sua pasta de código, da mesma forma que você faria com um outro módulo desenvolvido por terceiros.
<h3>Aplicativo Mínimo</h3>
O que nós sabemos sobre HTTP?
<ul>
    <li>Que é um protocolo de aplicação, ou seja, é um protocolo para a transmissão de dados pertencentes a uma aplicação que se utiliza de arquitetura cliente/servidor.</li>
    <li>Que o servidor HTTP recebe requisições e deve fornecer respostas .</li>
    <li>Que cada requisição indica um método (uma ação) que deve ser tomado sobre um recurso disponível no servidor. Em outras palavras, se um cliente envia uma requisição <strong>GET /images/company<em>logo.gif</strong>, podemos entender que o cliente deseja obter (<strong>GET</strong>) o recurso <strong>/images/company</em>logo.gif.</strong></li>
    <li>Que existem vários métodos: GET, HEAD, POST, PUT, DELETE&#8230; cada um sendo usado para indicar uma intenção diferente do cliente em relação ao recurso.</li>
</ul>
O web.py fornece um servidor web básico, indicado para a fase de desenvolvimento/debug/testes. Vamos colocar esse servidor pra funcionar. Vamos ver como fica um  aplicativo mínimo, onde o servidor responde com um &#8220;Hello&#8221; para cada requisição GET que for feita, independente do recurso solicitado. Como fazer isso?</p>

<p>Para isso, o servidor do web.py precisa:
<ul>
    <li>De uma indicação de quais recursos ele deve prover uma resposta.</li>
    <li>Como responder, para cada método.</li>
</ul>
As 8 linhas abaixo fazem isso.
<pre>import web</pre>
<pre>urls = (</pre>
<pre>    '/(.*)', 'index'</p>

<p>)</pre>
<pre>class index:</pre>
<pre>    def GET(self, resource):</p>

<pre><code>    print "Hello, dude. Are you really trying to GET /%s?" % resource&lt;/pre&gt;
</code></pre>

<p><pre>if <strong>name</strong> == '<strong>main</strong>': web.run(urls, globals())</pre>
Praticamente auto-explicativo, não é mesmo? Define-se uma variável que contém uma lista, tomada aos pares. O primeiro elemento desse par é uma expressão regular e o segundo é o nome de uma classe. Essa lista é passada como parâmetro para o servidor web, que passa a usar a classe definida para atender as requisições que dão match entre a URL requisitada e a expressão regular declarada por você.</p>

<p>A nossa classe "index" possui um método GET, que vai responder com o "Hello, dude. E mostrar qual foi o recurso solicitado pelo cliente". Salvando esse arquivo (chamado "code.py", por exemplo), basta invocar o interpretador Python
<pre>
$python code.py</pre>
e teremos um servidor rodando na porta 8080. Se quiser mudar a porta-padrão, é só passar como parâmetro na hora de iniciar o script.</p>

<p>Você vai ver que usamos o velho <em>print </em>para a parte de resposta. O web.py (na versão 0.22) altera o descritor de arquivo stdout, e faz com que qualquer coisa que seria normalmente enviada para o console seja enviada para o socket que foi aberto para o cliente. Se você desejar monitorar alguma coisa no console, a função a ser usada é web.debug().</p>

<p>Bem, se você conseguiu colocar o servidor para rodar e seu browser recebe a resposta, creio que está tudo bem com o seu setup do web.py. Podemos partir para o próximo passo e adicionar algumas funcionalidades para o nosso serviço.</p>

<p><strong><em>Observação importante:</em></strong> Essa série não é um texto para aprendermos técnicas de análise ou de projeto de software. Portanto, não estranhe a forma que vamos montar o webapp, ou até mesmo a falta de "best practices" no desenvolvimento. Por exemplo, usaremos um único arquivo para todo o sistema, sem separar por classes ou funcionalidades. Vamos trabalhar de forma bastante iterativa e , para cada funcionalidade proposta que exercite algum novo conceito, vamos verificar quais são as mudanças necessárias no nosso código e adaptar o código para isso.
<h3></h3>
<h3>1) Criando a página para enviar links.</h3>
Poderíamos começar o nosso site criando a página principal, onde todos os links são listados. Mas precisamos ter um sistema inicial que permita que os links sejam incluídos, não é mesmo?</p>

<p>Vamos começar por aí, então. Vamos criar uma página onde o usuário preenche um formulário com um único campo de texto, representando um link. Esse link precisará ser salvo. Para tanto, vamos utilizar um servidor de banco de dados e criar uma tabela "Link", na qual cada link possui um número de identificação, uma url e uma data de publicação.
<pre>CREATE TABLE Link (</pre>
<pre>   id serial PRIMARY KEY,</p>

<pre><code>url varchar(512) NOT NULL,

date_published timestamp NOT NULL DEFAULT NOW()&lt;/pre&gt;
</code></pre>

<p><pre>);</pre>
Para a funcionalidade desejada, necessitamos:
<ul>
    <li>uma forma de apresentar um formulário com o campo de texto para o usuário.</li>
    <li>uma forma de processar o formulário.</li>
    <li>uma forma de fazer "sanitização de dados". Qualquer dado que é enviado pelo usuário é potencialmente perigoso, ainda mais se for um dado que será usado para construir consultas SQL.</li>
    <li>ser capazes de inserirmos os dados no banco de dados.</li>
</ul>
Mais uma vez, o web.py pode nos ajudar com essa tarefa. O web.py contém um módulo para a manipulação de formulários. Nele, define-se uma lista de input fields (nos moldes do HTML: text, dropdown, radio, checkbox, etc) e uma série de atributos desses inputs (nome, tamanho, valores default), além de uma série de <strong>funções de validação </strong>desses campos de entrada.</p>

<p>Para ilustrar, vejamos o formulário definido abaixo:
<pre>SubmitForm = form.Form(
        form.Textbox('url',
                     form.Validator('Deve começar com "http://"', lambda x: x.startswith('http://')),
                     description='Link'),
        form.Button('Enviar!', type="submit")
        )</pre>
<pre></pre>
Temos um objeto Form, com um campo de texto e um botão. O campo de texto será obrigatoriamente uma string que começa com a substring "http://".</p>

<p>Dois métodos importantes: <strong>Form.render() </strong>e <strong>Form.validates()</strong> . O primeiro retorna uma string que é a representação HTML de cada um dos inputs que ele contém, o segundo verifica se os valores contidos em um formulário satisfazem todos as funções de validação. Muito mais pode ser feito com isso, e você pode verificar isso na <a href="http://webpy.org/form">documentação de form em web.py</a>.</p>

<p>Para a parte de banco de dados, precisamos apenas definir quais os parâmetros de configuração para a conexão com o banco de dados. Depois que a conexão estiver estabelecida, usaremos os métodos adequados para a construção de queries SQL: <strong>web.insert()</strong>, <strong>web.select()</strong>, <strong>web.update()</strong> e <strong>web.delete()</strong>. Esses métodos todos precisam apenas do nome da tabela e de eventuais parâmetros opcionais (colocar um "limit" no tamanho da lista de resultados de um select, por exemplo) .</p>

<p>Colocando tudo junto:
<pre># -<em>- coding: utf-8 -</em>-</p>

<p>import web
from web import db, form</p>

<p>urls = (
     '/submit', 'submit',
 )</p>

<p>class submit:
    SubmitForm = form.Form(
        form.Textbox('url',
                     form.Validator('Deve começar com "http://"', lambda x: x.startswith('http://')),
                     description='Link'),
        form.Button('Enviar!', type="submit")
        )</p>

<pre><code>page_content = '&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;form id="new_link" action="/submit" method="post"&amp;gt;%s&amp;lt;/form&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
def GET(self):
    frm = submit.SubmitForm()
    print submit.page_content % frm.render()
def POST(self):
    frm = submit.SubmitForm()
    if frm.validates():
        i = web.input()
        web.insert('Link', url=i.url)
        print "Link enviado com sucesso."
    else:
        print submit.page_content % ("&amp;lt;p&amp;gt;Houve algo errado com o preenchimento&amp;lt;/p&amp;gt;" + frm.render())
</code></pre>

<p>if <strong>name</strong> == "<strong>main</strong>":
    web.config.db<em>parameters = dict(dbn  = 'postgres', # servidores aceitos 'postgres', 'mysql' ou 'firebird'
                                    db   = 'nome</em>do<em>servidor',
                                    user = 'usuario</em>do_servidor',
                                    pw   = 'senha')
    web.run(urls, globals(), web.reloader)</pre>
Preste atenção aos seguintes detalhes:
<ul>
    <li>Cria-se uma instância do formulário SubmitForm a cada requisição, seja para GET ou para POST. Se não fizermos isso, o formulário pode conter os valores de uma outra requisição feita por um outro usuário.</li>
    <li>validates() tem como parâmetro default o valor de <em>web.input()</em>. <em>web.input()</em> é um método que retorna um objeto do tipo Storage contendo os pares chaves/valores enviados na querystring. Um objeto Storage funciona como um dictionary, com a diferença que seus elementos podem ser acessados por d.foo ao invés de d['foo'].</li>
    <li>Definimos o dict que contém os parâmetros necessários para o banco de dados, e colocamos logo antes da linha com web.run(). Parte do trabalho do web.run() é carregar o contexto do ambiente e inicializar a conexão com o banco de dados.</li>
    <li>Só pode ser feita conexão com um banco de dados. Essa é uma limitação grave da versão atual do web.py, que será corrigida na próxima versão.</li>
    <li>Adicionamos um parâmetro opcional ao web.run, chamado web.reloader. Essa diretiva permite que o servidor recarregue o código a cada requisição. Isso permite que você faça alterações no código e veja imediatamente o resultado, sem necessitar parar/reiniciar o servidor.</li>
</ul>
O app já é capaz de cadastrar os links. Amanhã (<em>update: vai ficar pro ano que vem, pessoal. Mas prometo que isso essa série chega ao seu fim antes da sua decoração de natal, ok?</em>) vamos ver como utilizar o esquema de templates do web.py para apresentar os links, além do sistema de autenticação de usuários.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2007/12/26/especial-de-natal-log4dev-construindo-um-site-de-noticias-usando-python-parte-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Joel, sobre codificação de caracteres</title>
		<link>http://log4dev.com/2007/04/23/joel-sobre-codificacao-de-caracteres/</link>
		<comments>http://log4dev.com/2007/04/23/joel-sobre-codificacao-de-caracteres/#comments</comments>
		<pubDate>Mon, 23 Apr 2007 20:09:21 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Teoria]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://blog.job4dev.com/?p=130</guid>
		<description><![CDATA[Hoje descobri este artigo do Joel Spolsky sobre codificação de caracteres e UNICODE. Bem didático e interessante, sobretudo quando se desenvolve interfaces pra Web.]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2007/04/23/joel-sobre-codificacao-de-caracteres/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Hoje descobri <a href="http://www.joelonsoftware.com/articles/Unicode.html">este artigo</a> do <strong>Joel Spolsky</strong> sobre <strong>codificação de caracteres</strong> e <strong>UNICODE</strong>.</p>

<p>Bem didático e interessante, sobretudo quando se desenvolve interfaces pra Web.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2007/04/23/joel-sobre-codificacao-de-caracteres/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

