<?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>GustavoHenrique.net &#187; Django</title>
	<atom:link href="http://blog.gustavohenrique.net/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gustavohenrique.net</link>
	<description>Tecnologia e Software Livre</description>
	<lastBuildDate>Wed, 25 Jan 2012 10:34:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Deploy no tomcat usando django-jython</title>
		<link>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/</link>
		<comments>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 23:11:57 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=377</guid>
		<description><![CDATA[Muitos dizem que o futuro do java está na jvm, que a linguagem em si vai morrer e a máquina virtual vai ser a principal plataforma de desenvolvimento capaz de executar código escrito em diversas linguagens. Previsões a parte, a idéia de rodar um código python em um servidor de aplicação java é no mínimo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/jython/" rel="attachment wp-att-378"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/04/jython.jpg" alt="Jython" title="jython" width="250" height="158" class="aligncenter size-full wp-image-378" /></a><br />
Muitos dizem que o futuro do java está na jvm, que a linguagem em si vai morrer e a máquina virtual vai ser a principal plataforma de desenvolvimento capaz de executar código escrito em diversas linguagens. Previsões a parte, a idéia de rodar um código python em um servidor de aplicação java é no mínimo interessante.<br />
Nesse artigo vou mostar como fazer o deploy de um site em django + mysql no servidor tomcat no ubuntu 10.10.<br />
<span id="more-377"></span></p>
<h2>Introdução</h2>
<p>Jython é o responsável por tornar possível essa façanha. Segundo a wikipedia:<br />
&#8220;Jython é uma implementação da linguagem Python que gera bytecode para máquinas Java (JVM &#8211; Java Virtual Machine). Com ela é possível fazer o desenvolvimento de aplicações híbridas que unem código em Java e Python. Esta ferramenta é muito útil também para embutir uma linguagem para criação de scripts em aplicações que requerem este tipo de funcionalidade. Também inclui um compilador que converte código fonte Python em Java bytecode, permitindo que programadores Python possam escrever classes que possam ser utilizadas por um programa Java.&#8221;<br />
Nesse artigo vou usar o servidor tomcat por ser open source e fácil de instalar e configurar. Para fazer deploy no tomcat, é preciso antes criar um arquivo .war. Para isso vou instalar o django-jython que além de simplificar muito a criação do war facilita o acesso à banco de dados.<br />
Informações detalhadas sobre o funcionamento e arquitetura das tecnologias utilizadas podem ser encontradas nos seus respectivos sites.</p>
<h2>Instalação</h2>
<p>Antes de instalar é preciso dizer que utilizar diferentes versões do trio jython + django + django-jython pode não funcionar corretamente. Uma combinação que deu certo pra mim foram jython2.5.2, django-1.2.3 e django-jython-1.2.0, que são as versões utilizadas nesse artigo.</p>
<p>O primeiro passo é instalar o jython. Faça o download em <a href="http://sourceforge.net/projects/jython/files/jython/2.5.2/jython_installer-2.5.2.jar/download">no site do projeto</a> e instale no <code>/opt</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook ~$ java -jar jython_installer-2.5.2.jar</pre></div></div>

<p>Detalhes da instalação básica podem ser lidos na wiki <a href="http://wiki.python.org/jython/InstallationInstructions">http://wiki.python.org/jython/InstallationInstructions</a>.</p>
<p>Considerando que o virtualenv + virtualenv wrapper estão instalados, vou criar um novo ambiente virtual e instalar o django e o django-jython.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook ~$ mkvirtualenv --python=/opt/jython2.5.2/bin/jython --no-site-packages env_jython
Running virtualenv with interpreter /opt/jython2.5.2/bin/jython
New jython executable in env_jython/bin/jython
Installing setuptools............................done.
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/preactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/postactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/get_env_details
(env_jython)gustavo@notebook ~$
(env_jython)gustavo@notebook ~$ pip install django==1.2.3, django-jython==1.2</pre></div></div>

<h2>Configuração</h2>
<p>Django-jython implementa o pacote zxJDBC do jython que permite conectividade à banco de dados usando drivers JDBC.<br />
Para utilizar o mysql é preciso fazer o download do <a href="http://www.mysql.com/downloads/connector/j/5.1.html">mysql-connector-java-5.1.15-bin.jar</a>, adiciona-lo no <code>CLASSPATH</code> e alterar o <code>DATABASE_ENGINE</code> no <code>settings.py</code> do projeto. Supondo que já exista o projeto myproject criado em /var/www/django, vou criar um diretório lib e copiar o mysql-connector para dentro dele:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ mkdir -p /var/www/django/myproject/lib
(env_jython)gustavo@notebook ~$ cp mysql-connector-java-5.1.15-bin.jar /var/www/django/myproject/lib/
(env_jython)gustavo@notebook ~$ export CLASSPATH=&quot;$CLASSPATH:/var/www/django/myproject/lib/mysql-connector-java-5.1.15-bin.jar&quot;</pre></div></div>

<p>Alterando o <code>settings.py</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">DATABASES = <span style="color: black;">&#123;</span> 
    <span style="color: #483d8b;">'default'</span>: <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ENGINE'</span>: <span style="color: #483d8b;">'doj.backends.zxjdbc.mysql'</span>,
        <span style="color: #483d8b;">'NAME'</span>: <span style="color: #483d8b;">'jython_example'</span>,
        <span style="color: #483d8b;">'USER'</span>: <span style="color: #483d8b;">'username'</span>,
        <span style="color: #483d8b;">'PASSWORD'</span>: <span style="color: #483d8b;">'pass'</span>,
        <span style="color: #483d8b;">'HOST'</span>: <span style="color: #483d8b;">'localhost'</span>,
        <span style="color: #483d8b;">'PORT'</span>: <span style="color: #483d8b;">'3306'</span>,
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
INSTALLED_APPS = <span style="color: black;">&#40;</span>
    <span style="color: #808080; font-style: italic;"># outras apps aqui</span>
    <span style="color: #483d8b;">'doj'</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Se o projeto possuir alguma classe no models.py, pode executar o syncdb para criar as tabelas no mysql:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#40;</span>env_jython<span style="color: black;">&#41;</span>gustavo@notebook myproject$ jython manage.<span style="color: black;">py</span> syncdb</pre></div></div>

<p>Para finalizar, é preciso adicionar o projeto no <code>PYTHONPATH</code>. Insira o trecho abaixo no arquivo manage.py na linha 3:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span> 
PROJECT_ROOT_PATH = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>PROJECT_ROOT_PATH<span style="color: black;">&#41;</span></pre></div></div>

<p>Segundo a documentação é possível utilizar um test runner específico do django-jython que permite a saída dos resultados dos testes para um arquivo xml no mesmo formato dos gerados pelo Junit.</p>
<h2>Deploy</h2>
<p>Tomcat é fácil de instalar e possui uma interface web que permite fazer o upload do pacote tornando o deploy ridiculamente simples. Sua documentação é bastante completa e mostra em detalhes como instalar e configurar o ambiente.<br />
O primeiro passo é gerar um pacote war para deploy no tomcat. Ao adicionar <code>doj</code> em <code>INSTALLED_APPS</code> no settings.py, o django-jython adiciona uma task no manage.py para criação de pacotes. Essa task usa como base o diretório war_skel que por algum motivo não está presente na instalação via pip. Então&#8230; vamos criar:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ mkdir ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel
(env_jython)gustavo@notebook ~$ cd ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel
(env_jython)gustavo@notebook war_skel$ mkdir -p WEB-INF/lib WEB-INF/lib-python
(env_jython)gustavo@notebook war_skel$ touch application.py
(env_jython)gustavo@notebook war_skel$ touch WEB-INF/web.xml</pre></div></div>

<p>Conteúdo do <code>application.py</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span> <span style="color: #ff7700;font-weight:bold;">import</span> wsgi
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> handler<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">os</span>.<span style="color: black;">putenv</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;DJANGO_SETTINGS_MODULE&quot;</span>, <span style="color: #483d8b;">&quot;{{ settings.SETTINGS_MODULE }}&quot;</span><span style="color: black;">&#41;</span>
    h = wsgi.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> h<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span></pre></div></div>

<p>Conteúdo do <code>web.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #00bbdd;">&lt;!DOCTYPE web-app</span>
<span style="color: #00bbdd;">PUBLIC &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;</span>
<span style="color: #00bbdd;">&quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;web-app<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ project_name }}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/display-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   {{ project_name }} through WSGI with modjy
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;context-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>files.prefix<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Needed by fileservlet --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/context-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>modjy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.xhaus.modjy.ModjyJServlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>reload_on_mod<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;load-on-startup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/load-on-startup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.jruby.webapp.FileServlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  {% if settings.ADMIN_MEDIA_PREFIX %}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ settings.ADMIN_MEDIA_PREFIX }}*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  {% endif %}
&nbsp;
  {% if settings.MEDIA_URL %}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ settings.MEDIA_URL }}*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  {% endif %}
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>modjy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/web-app<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Lembram do download do mysql-connector-java? Vamos copia-lo também para o diretório <code>war_skel/WEB-INF/lib</code> para ser inserido no pacote war criado pelo manage.py.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ cp mysql-connector-java-5.1.15-bin.jar ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel/WEB-INF/lib/</pre></div></div>

<p>Agora vem a parte de gerar o pacote war. Entre no diretório do projeto e execute a task war do manage.py. Mas antes certifique-se de ter executado o syncdb:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ cd /var/www/django/myproject
(env_jython)gustavo@notebook myproject$ jython manage.py war</pre></div></div>

<p>Se tudo deu certo, foi gerado um pacote war no diretório de um nível acima do projeto (/var/www/myproject.war).<br />
Com o tomcat rodando, acesse o endereço <a href="http://localhost:8080/manager/html">http://localhost:8080/manager/html</a>, clique em &#8220;Select WAR file to upload&#8221; e depois no botão deploy.</p>
<h2>Conclusão</h2>
<p>Embora o jython não tenha um desenvolvimento muito acelerado, vimos que já é possível utilizar um projeto django com acesso à banco de dados com muita facilidade e poucas alterações.<br />
Em termos de desempenho não tenho qualquer informação que possa compartilhar com vocês, e caso alguém tenha algum caso de sucesso (ou mesmo insucesso) seria legal compartilhar com a comunidade.<br />
Lembrando que o django-jython 1.2 possui backend estável apenas para os bancos de dados oracle, mysql e postgresql.</p>
<h2>Links</h2>
<p><a href="http://www.jython.org/downloads.html/">http://www.jython.org/downloads.html/</a><br />
<a href="http://packages.python.org/django-jython/quickstart.html">http://packages.python.org/django-jython/quickstart.html</a><br />
<a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deploy múltiplas versões do Django no Nginx com VirtualEnv</title>
		<link>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/</link>
		<comments>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 14:31:14 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=370</guid>
		<description><![CDATA[Nginx (pronuncia-se engine-x) é um servidor web que está ganhando muita popularidade como alternativa ao apache por ser rápido, robusto e fácil de configurar. Nesse artigo vou mostar como fazer o deploy de dois projetos usando versões diferentes do Django usando o virtualenv + nginx no ubuntu 10.10. Introdução Nginx foi desenvolvido inicialmente em 2002 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/nginx-logo/" rel="attachment wp-att-371"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/04/nginx-logo-300x77.png" alt="" title="nginx-logo" width="300" height="77" class="aligncenter size-medium wp-image-371" /></a><br />
Nginx (pronuncia-se engine-x) é um servidor web que está ganhando muita popularidade como alternativa ao apache por ser rápido, robusto e fácil de configurar.<br />
Nesse artigo vou mostar como fazer o deploy de dois projetos usando versões diferentes do Django usando o virtualenv + nginx no ubuntu 10.10.<br />
<span id="more-370"></span></p>
<h2>Introdução</h2>
<p>Nginx foi desenvolvido inicialmente em 2002 por Igor Sysoev para servir um site russo chamado Rambler que tinha milhares de requisições por dia. Entre suas características estão o baixo consumo de cpu e memória (pois usa um processo por core para gerenciar varias conexões) e o formato dos arquivos de configuração que são mais simples de entender e modificar do que os do apache.<br />
Entre os grandes sites que o utilizam, podemos destacar o wordpress e sourceforge.</p>
<p>VirtualEnv é um software que permite criar um ambiente python único e exclusivo para cada projeto. Não entrarei em detalhes sobre seu funcionamento então recomendo uma lida no artigo <a href="http://hltbra.blogspot.com/2010/05/gerenciando-ambientes-virtuais-e.html">Gerenciando Ambientes Virtuais</a> que explica melhor sobre o assunto.</p>
<h2>Instalação</h2>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo apt-get install nginx
$ sudo pip install virtualenv, virtualenvwrapper</pre></div></div>

<h2>Configuração</h2>
<p>Por padrão o arquivo de configuração é o <code>/etc/nginx/nginx.conf</code>. Vamos modifica-lo e deixar como abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">user www-data;
worker_processes 2;
&nbsp;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
&nbsp;
http {
    include     /etc/nginx/mime.types;
    access_log  /var/log/nginx/access.log;
    sendfile        on;
    keepalive_timeout  65;
    tcp_nodelay        on;
    gzip  on;
    gzip_disable &quot;MSIE [1-6]\.(?!.*SV1)&quot;;
&nbsp;
    server {
        server_name project-1-0;
        listen 80;
&nbsp;
        location /media {
            autoindex on;
            alias /var/www/project_1_0/media;
            expires 31d;
        }
&nbsp;
        location /admin_media {
            autoindex on;
            alias /var/www/project_1_0/media/admin;
            expires 31d;
        }
&nbsp;
        location / { 
            root /var/www/project_1_0;
            fastcgi_pass 127.0.0.2:8000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
        }   
    }
&nbsp;
    server {
        server_name project-1-3;
        listen 80; 
&nbsp;
        location /media {
            autoindex on; 
            alias /var/www/project_1_3/media;
            expires 31d;
        }
&nbsp;
        location /admin_media {
            autoindex on; 
            alias /var/www/project_1_3/media/admin;
            expires 31d;
        }
&nbsp;
        location / { 
            root /var/www/project_1_3;
            fastcgi_pass 127.0.0.3:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
       }
    }
}</pre></div></div>

<p>Pode-se dizer que o arquivo de configuração do nginx é uma lista de diretivas organizadas em uma estrutura lógica. Nginx é modular e cada módulo possui um conjunto específico de diretivas. Na configuração acima, todas as diretivas fazem parte do <code>core</code> do nginx, exceto as diretivas <code>fastcgi</code> que fazem parte do módulo FastCGI. Esse módulo é incluído por padrão na compilação do nginx, sendo assim não é preciso ativa-lo.<br />
Nginx trabalha com um sistema de blocos. Um configuração mínima requer os principais blocos: <code>http</code>, <code>server</code> e <code>location</code>.</p>
<p>O bloco <code>http</code> é responsável por tratar requisições desse tipo. Ele pode conter um ou mais blocos <code>server</code> que contém configurações para um virtual host. Cada <code>server</code> pode ter um ou mais blocos <code>location</code>. Esse por sua vez possui configurações para um determinado url pattern.<br />
Na configuração acima foram criados dois blocos <code>server</code> (um para cada projeto) e cada um possui três blocos <code>location</code> contendo configurações para arquivos estáticos e para os projetos em django.</p>
<p>Algumas diretivas podem ser colocadas na raiz do arquivo, fora dos blocos. Diretivas assim são chamadas de diretivas globais e afetam as demais configurações.<br />
Sobre algumas diretivas:</p>
<p><code>user www-data</code><br />
Define o usuário do nginx. Coloquei o mesmo usado pelo apache mas nada impede de usar outro. Apenas lembre-se de atribuir as devidas permissões nos diretórios dos projetos para esse user.</p>
<p><code>worker_processes 2</code><br />
Define o número de processos executados por core da CPU. No meu caso, uso uma CPU Core 2 Duo.</p>
<p><code>error_log /var/log/nginx/error.log</code><br />
Caminho para o arquivo de log de erros.</p>
<p><code>pid /var/run/nginx.pid</code><br />
Caminho para o arquivo contendo o PID do nginx.</p>
<p><code>include /etc/nginx/mime.types</code><br />
Similar à função include usada em algumas linguagens. Insere o conteúdo do arquivo externo no trecho indicado.</p>
<p><code>access_log /var/log/nginx/access.log</code><br />
Caminho para o arquivo de log de acessos.</p>
<p><code>sendfile on</code><br />
Se habilitado, nginx usa <code>sendfile kernel call</code> para gerenciar transmissão de arquivos. Se desabilitado, ele próprio gerencia a transmissão. Dependendo da localização física do arquivo, isso pode afetar a performance.</p>
<p><code>keepalive_timeout 65</code><br />
Tempo de espera do servidor para fechar conexões <code>keep-alive</code>.</p>
<p><code>tcp_nodelay on</code><br />
Habilita ou não a opção TCP_NODELAY para conexões <code>keep-alive</code>. TCP_NODELAY é usado para um único propósito; desabilitar o algoritmo de buffer Nagle. Deve ser habilitado apenas para aplicações que enviam frequentemente requests sem necessidade de obter um response imediato.</p>
<p><code>gzip on</code><br />
Habilita compressão gzip.</p>
<p><code>gzip_disable "MSIE [1-6]\.(?!.*SV1)"</code><br />
Desabilita a compressão gzip para requests cujo o User-Agent no cabeçalho http combine com a expressão regular. Nesse caso, desabilita para o internet explorer.</p>
<p><code>server_name project-1-0</code><br />
Associa um ou mais hostnames ao bloco <code>server</code>. O nginx verifica o <code>Host</code> no cabeçalho do request e seleciona o primeiro bloco que combina.</p>
<p><code>listen 80</code><br />
Escuta na porta 80 (padrão http).</p>
<p><code>autoindex on</code><br />
Exibe os arquivos do diretório.</p>
<p><code>alias /var/www/project_1_0/media</code><br />
Define a location /media como um atalho para o diretório media do projeto.</p>
<p><code>expires 31d</code><br />
Define o tempo de expiração do conteúdo. Nesse caso, 31 dias. </p>
<p><code>root /var/www/project_1_0</code><br />
Caminho do projeto.</p>
<p><code>fastcgi_pass 127.0.0.2:8000</code><br />
Endereço e porta do servidor web usado pelo django. Ex.: python manage.py runfcgi host=127.0.0.2 port=8000 pidfile=/var/run/project_1_0.pid</p>
<p><code>fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name<br />
fastcgi_param PATH_INFO $fastcgi_script_name<br />
fastcgi_param REQUEST_METHOD $request_method<br />
fastcgi_param QUERY_STRING $query_string<br />
fastcgi_param CONTENT_TYPE $content_type<br />
fastcgi_param CONTENT_LENGTH $content_length<br />
fastcgi_param SERVER_PORT $server_port<br />
fastcgi_param SERVER_NAME $server_name<br />
fastcgi_param SERVER_PROTOCOL $server_protocol</code><br />
Repassa os parâmetros do request recebido pelo nginx para o servidor fastcgi.</p>
<p>Para finalizar a configuração, vamos editar o <code>/etc/hosts</code> e adicionar dois virtual hosts referentes aos projetos.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo /etc/hosts
&nbsp;
127.0.0.2   project-1-0.localdomain project-1-0
127.0.0.3   project-1-3.localdomain project-1-3</pre></div></div>

<p>Notem que estou utilizando dois IPs de loopback, ou seja, visível somente na máquina local.</p>
<h2>Criando os Projetos</h2>
<p>Agora vem a parte mais fácil. Vamos criar dois ambientes virtuais (env-1.0 e env-1.3) e instalar o django-1.0 em um e o django-1.3 no outro.<br />
Dentro de cada ambiente vou criar um projeto que vai exibir a versão do django em uso.<br />
O único pacote python obrigatório a ser instalado é o flup, que é uma coleção de módulos WSGI.<br />
Vou usar o virtualenv + virtualenv wrapper e como já havia dito não entrarei em detalhes sobre essas ferramentas.</p>
<h3>Ambiente 1.0</h3>
<p>Criando o ambiente env-1.0 e o projeto dentro do diretório /var/www:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook www$ mkvirtualenv --no-site-packages env-1.0
(env-1.0)gustavo@notebook www$ pip install django==1.0, flup
(env-1.0)gustavo@notebook www$ django-admin startproject project_1_0</pre></div></div>

<p>Modificando o arquivo <code>project_1_0/urls.py</code> para exibir a versão do django na tela:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
<span style="color: #ff7700;font-weight:bold;">import</span> django
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^version/$'</span>, <span style="color: #ff7700;font-weight:bold;">lambda</span> request:HttpResponse<span style="color: black;">&#40;</span>django.<span style="color: black;">VERSION</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Executando o servidor fastcgi:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env-1.0)gustavo@notebook project_1_0$ python manage.py runfcgi host=127.0.0.2 port=8000 pidfile=/tmp/project_1_0.pid</pre></div></div>

<p>Agora basta testar. Abra o navegador e digite http://project-1-0/. Se tudo deu certo então será exibido na tela a versão do Django, no caso &#8220;10final&#8221;.</p>
<h3>Ambiente 1.3</h3>
<p>Criando o ambiente env-1.3 e o projeto:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook www$ mkvirtualenv --no-site-packages env-1.3
(env-1.3)gustavo@notebook www$ pip install django==1.3, flup
(env-1.3)gustavo@notebook www$ django-admin startproject project_1_3</pre></div></div>

<p>Modificando o arquivo <code>project_1_3/urls.py</code> para exibir a versão do django na tela:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> patterns, include, url 
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
<span style="color: #ff7700;font-weight:bold;">import</span> django
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^version/$'</span>, <span style="color: #ff7700;font-weight:bold;">lambda</span> request:HttpResponse<span style="color: black;">&#40;</span>django.<span style="color: black;">VERSION</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Executando o servidor fastcgi:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env-1.3)gustavo@notebook project_1_3$ python manage.py runfcgi host=127.0.0.3 port=9000 pidfile=/tmp/project_1_3.pid</pre></div></div>

<p>Abra o navegador e digite http://project-1-3/. Deve ser exibido na tela a versão do Django, &#8220;130final0&#8243;.</p>
<h2>Conclusão</h2>
<p>Esse artigo mostrou uma forma simplista de servir dois projetos usando versões diferentes do django no nginx. Na configuração foram criados blocos <code>location</code> para servir arquivos estáticos como /media e /admin_media porém nos projetos não me aprofundei em alterar o settings.py para isso.</p>
<p>O Nginx possui a diretiva <code>include</code> que permite inserir trechos de configuração localizados em outros arquivos no arquivo de configuração principal. Sendo assim, como boa prática, é indicado colocar a configuração de cada projeto em arquivos separados. No ubuntu 10.10 o diretório <code>/etc/nginx</code> possui dois sub-diretórios, <code>sites-available</code> e <code>sites-enabled</code>, similar ao apache2. A idéia é colocar os arquivos de configuração referentes a cada projeto dentro de <code>sites-available</code> e criar um link simbólico em <code>sites-enabled</code> para habilitar seu uso.<br />
Quem quiser conhecer melhor esse fantástico servidor web, recomendo a leitura do livro Nginx HTTP Server, que inclusive serviu como base para esse artigo.</p>
<h2>Links</h2>
<p><a href="http://nginx.org/">Nginx Project Page</a><br />
<a href="http://planet.nginx.org/">Planet Nginx</a><br />
<a href="https://www.packtpub.com/nginx-http-server-for-web-applications/book">Nginx HTTP Server Book</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Liberado código fonte do tipsforlinux.com</title>
		<link>http://blog.gustavohenrique.net/2010/09/liberado-codigo-fonte-do-tipsforlinux-com/</link>
		<comments>http://blog.gustavohenrique.net/2010/09/liberado-codigo-fonte-do-tipsforlinux-com/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 16:55:32 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[tipsforlinux]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=280</guid>
		<description><![CDATA[Essa semana foi lançado o site tipsforlinux.com, meu projeto pessoal open source desenvolvido em Django. O site é um blog, cuja função é ser um repositório de dicas e truques sobre GNU/Linux. Possui um visual simples e leve possibilitando uma navegação agradável até mesmo nos navegadores em modo texto. O site não chega a ser [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/09/tipsforlinux.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2010/09/tipsforlinux.jpg" alt="tipsforlinux.com" title="tipsforlinux" width="263" height="68" class="aligncenter size-full wp-image-281" /></a></p>
<p>Essa semana foi lançado o site tipsforlinux.com, meu projeto pessoal open source desenvolvido em Django. O site é um blog, cuja função é ser um repositório de dicas e truques sobre GNU/Linux. Possui um visual simples e leve possibilitando uma navegação agradável até mesmo nos navegadores em modo texto. O site não chega a ser uma idéia inovadora, na verdade ele surgiu da vontade de programar novamente em Django.<br />
O projeto utiliza as apps django-tagging, django-pagination, django-socialauth, django-contact-form, python-twitter, comments e sitemaps e o codigo está disponibilizado no github.</p>
<p>Site:<br />
<a href="http://tipsforlinux.com" title="TipsForLinux">http://tipsforlinux.com</a></p>
<p>Código:<br />
<a href="http://github.com/gustavohenrique/TipsForLinux" title="Codigo">http://github.com/gustavohenrique/TipsForLinux</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2010/09/liberado-codigo-fonte-do-tipsforlinux-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Por que Django?</title>
		<link>http://blog.gustavohenrique.net/2010/06/por-que-django/</link>
		<comments>http://blog.gustavohenrique.net/2010/06/por-que-django/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 00:00:51 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=272</guid>
		<description><![CDATA[Django é o framework ideal para os que buscam agilidade e simplicidade. Um dos recursos que mais gosto é o Admin, uma poderosa interface para produzir conteúdo. Simples de usar, bastante customizável e com um visual agradável, bastante útil durante a fase de desenvolvimento e ideal para pequenos projetos com ausência de um designer na [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/06/django.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2010/06/django.jpg" alt="" title="django" width="180" height="82" class="aligncenter size-full wp-image-276" /></a></p>
<p><a href="http://www.djangoproject.com">Django</a> é o <a href="http://pt.wikipedia.org/wiki/Framework">framework</a> ideal para os que buscam agilidade e simplicidade. Um dos recursos que mais gosto é o Admin, uma poderosa interface para produzir conteúdo.  Simples de usar, bastante customizável e com um visual agradável, bastante útil durante a fase de desenvolvimento e ideal para pequenos projetos com ausência de um designer na equipe. Outras caracteristicas interessantes são:</p>
<ul>
<li>API para autenticação de usuários com suporte à grupos e níveis de acesso, que permite a criação de permissões personalizadas para cada página, classe ou método;</li>
<li>Sistema de cache que torna mais rápido o carregamento das páginas e o acesso ao banco de dados;</li>
<li>Sistema de templates utilizando HTML, com suporte a herança e Template Tags &#8211; uma linguagem de templates para manipulação de conteúdo dinamicamente. É possível criar suas próprias com código Python e utiliza-las em qualquer parte do projeto;</li>
<li>Trabalhar com formulários e extremamente simples e há diversos tipos de validações disponíveis como por exemplo e-mail, cpf e endereço IP;</li>
<li>ORM compatível com os bancos de dados mais utilizados no mercado;</li>
<li>Paginação é uma tarefa trivial;</li>
<li>Incrível suporte à internacionalização;</li>
<li>É multiplataforma;</li>
<li>Documentação bem completa e de fácil entendimento;</li>
<li>Comunidade altamente ativa.</li>
</ul>
<p>Por utilizar <a href="http://www.python.org">Python</a>, é compatível com uma grande variedade de bibliotecas para trabalhar com xml, json, webservices, restful, graficos, relatorios, imagens e etc. Sem dúvida uma ótima escolha para quem procura agilidade com produtividade.</p>
<p>Essa foi minha opinião expressada no debate <strong>Django vs. Ruby on Rails</strong>, matéria da revista <a href="http://www.revistatidigital.com.br">TiDigital</a> (<a href="http://www.arteccom.com.br/revistatidigital/downloads/16/sumario_16.pdf">edição 16 de junho/2010</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2010/06/por-que-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django usando Pisa para converter HTML para PDF</title>
		<link>http://blog.gustavohenrique.net/2010/02/django-usando-pisa-para-converter-html-para-pdf/</link>
		<comments>http://blog.gustavohenrique.net/2010/02/django-usando-pisa-para-converter-html-para-pdf/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 18:02:49 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[pisa]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=235</guid>
		<description><![CDATA[Pisa é um conversor de HTML/XHTML/CSS para PDF, escrito em Python e baseado nas bibliotecas Reportlab, PyPDF, TechGame Networks CSS e HTML5lib. Seu foco principal não é gerar páginas perfeitas para impressão, mas utilizar HTML e CSS para gerar PDFs dentro de aplicações. A instalação pode ser feita através do código no site do projeto [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/02/tower_pisa.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2010/02/tower_pisa.jpg" alt="Torre de Pisa" title="Torre de Pisa" width="130" height="200" class="aligncenter size-full wp-image-236" /></a></p>
<p>Pisa é um conversor de HTML/XHTML/CSS para PDF, escrito em Python e baseado nas bibliotecas Reportlab, PyPDF, TechGame Networks CSS e HTML5lib. Seu foco principal não é gerar páginas perfeitas para impressão, mas utilizar HTML e CSS para gerar PDFs dentro de aplicações.<br />
A instalação pode ser feita através do código no <a href="http://pypi.python.org/pypi/pisa/" target="_blank">site do projeto</a> ou pelo comando <code>easy_install pisa</code>.</p>
<p>Crie um arquivo chamado <code>report.py</code> dentro do diretório do projeto contendo o código abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django <span style="color: #ff7700;font-weight:bold;">import</span> http
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">loader</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_template
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> Context
<span style="color: #ff7700;font-weight:bold;">import</span> ho.<span style="color: black;">pisa</span> <span style="color: #ff7700;font-weight:bold;">as</span> pisa
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cStringIO</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">StringIO</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cgi</span>, <span style="color: #dc143c;">os</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> fetch_resources<span style="color: black;">&#40;</span>uri, rel<span style="color: black;">&#41;</span>:
    path = <span style="color: #483d8b;">'/path/para/diretorio/contendo/imagens/a/serem/exibidas'</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> path
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> write_to_pdf<span style="color: black;">&#40;</span>template_src, context_dict, filename<span style="color: black;">&#41;</span>:
    template = get_template<span style="color: black;">&#40;</span>template_src<span style="color: black;">&#41;</span>
    context = Context<span style="color: black;">&#40;</span>context_dict<span style="color: black;">&#41;</span>
    html  = template.<span style="color: black;">render</span><span style="color: black;">&#40;</span>context<span style="color: black;">&#41;</span>
    result = <span style="color: #dc143c;">StringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    pdf = pisa.<span style="color: black;">pisaDocument</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">StringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span>html.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;UTF-8&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, result, link_callback=fetch_resources<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> pdf.<span style="color: black;">err</span>:
        response = http.<span style="color: black;">HttpResponse</span><span style="color: black;">&#40;</span>mimetype=<span style="color: #483d8b;">'application/pdf'</span><span style="color: black;">&#41;</span>
        response<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Content-Disposition'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'attachment; filename=%s.pdf'</span> <span style="color: #66cc66;">%</span> filename
        response.<span style="color: black;">write</span><span style="color: black;">&#40;</span>result.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> response
    <span style="color: #ff7700;font-weight:bold;">return</span> http.<span style="color: black;">HttpResponse</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Problema ao gerar PDF: %s'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">cgi</span>.<span style="color: black;">escape</span><span style="color: black;">&#40;</span>html<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>E agora, dentro de uma <code>view</code>, é preciso importar o arquivo <code>report.py</code> e chamar a função <code>write_to_pdf</code> para fazer a conversão:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># views.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> report <span style="color: #ff7700;font-weight:bold;">import</span> write_to_pdf
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> listar_clientes_cadastrados<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    clientes = Cliente.<span style="color: black;">objects</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> write_to_pdf<span style="color: black;">&#40;</span><span style="color: #483d8b;">'relatorio.html'</span>, <span style="color: black;">&#123;</span><span style="color: #483d8b;">'clientes'</span>: clientes<span style="color: black;">&#125;</span>, <span style="color: #483d8b;">'nome_do_arquivo_pdf'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>A função <code>write_to_pdf</code> recebe como parâmetro o nome do arquivo HTML que será convertido, as variáveis que serão tratadas dentro desse arquivo e o nome que o arquivo PDF sem a extensão. Retorna o download do arquivo PDF.</p>
<p>Conforme citado no início do post, a conversão não é perfeita. Por exemplo, às vezes uma tabela apresenta mínimas deformações, não fica igual como na versão HTML. Apesar disso Pisa é uma ótima solução que muitas vezes ajuda bastante e, como puderam ver, é muito fácil de usar.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2010/02/django-usando-pisa-para-converter-html-para-pdf/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Formulários dinâmicos no Django</title>
		<link>http://blog.gustavohenrique.net/2010/01/formularios-dinamicos-no-django/</link>
		<comments>http://blog.gustavohenrique.net/2010/01/formularios-dinamicos-no-django/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 18:23:47 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=221</guid>
		<description><![CDATA[Um formulário dinâmico é aquele que o usuário pode definir quais campos vão existir. O programador não precisa criar código para cada formulário. Imagine um sistema que necessite de diversos tipos de formulários. Tarefa no mínimo entediante para o responsável pela manutenção. E se o usuário puder criar e modificar um formulário por uma interface [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/FormFill.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/FormFill.jpg" alt="FormFill" title="FormFill" width="250" height="166" class="aligncenter size-full wp-image-222" /></a></p>
<p>Um formulário dinâmico é aquele que o usuário pode definir quais campos vão existir. O programador não precisa criar código para cada formulário.<br />
Imagine um sistema que necessite de diversos tipos de formulários. Tarefa no mínimo entediante para o responsável pela manutenção. E se o usuário puder criar e modificar um formulário por uma interface gráfica fácil de usar? Seria muito bom para o programador!<br />
O segredo desse dinamismo é o uso de metaclasses, que são classes cujas instâncias também são classes.<br />
O truque é criar em tempo de execução uma metaclasse da classe <code>forms.Form</code>. Atributos dos campos como label, tipo, max length etc, podem ficar armazenados no banco de dados. Os valores dos campos podem ficar em outra tabela com uma referência de chave estrangeira. Usando o ORM do Django é muito simples, e de quebra já ganha uma interface gráfica para administrar tudo (admin).<br />
Sendo assim, o usuário poderia montar os campos do formulário definindo um label, tipo de campo, se é obrigatório ou não, valor padrão&#8230; e essas informações ficarão no armazenadas no BD. Fica fácil criar um código para pegar essas informações, criar uma nova classe <code>Form</code> em tempo de execução, instância-la e renderizar no template.</p>
<p>Exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># views.py</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">views</span>.<span style="color: black;">generic</span>.<span style="color: black;">simple</span> <span style="color: #ff7700;font-weight:bold;">import</span> direct_to_template
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> forms, fields
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> montar_formulario_dinamico<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    campos_dinamicos = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'nome'</span>: fields.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>max_length=<span style="color: #ff4500;">100</span>, required=<span style="color: #008000;">True</span>, label=<span style="color: #483d8b;">'Nome'</span>, initial=<span style="color: #483d8b;">'Gustavo'</span><span style="color: black;">&#41;</span>,
        <span style="color: #483d8b;">'idade'</span>: fields.<span style="color: black;">IntegerField</span><span style="color: black;">&#40;</span>label=<span style="color: #483d8b;">'Idade'</span>, min_value=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>,
        <span style="color: #483d8b;">'email'</span>: fields.<span style="color: black;">EmailField</span><span style="color: black;">&#40;</span>max_length=<span style="color: #ff4500;">200</span>, required=<span style="color: #008000;">False</span>, label=<span style="color: #483d8b;">'E-mail'</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    FormDinamico = <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>, <span style="color: black;">&#40;</span>forms.<span style="color: black;">Form</span>,<span style="color: black;">&#41;</span>, campos_dinamicos<span style="color: black;">&#41;</span>
    form = FormDinamico<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> direct_to_template<span style="color: black;">&#40;</span>request, <span style="color: #483d8b;">'formulario.html'</span>, extra_context=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'formulario'</span>: form<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Fica a dica!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2010/01/formularios-dinamicos-no-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Servidor Linux com Proxy e Controle de Banda – Parte 3</title>
		<link>http://blog.gustavohenrique.net/2010/01/servidor-linux-com-proxy-e-controle-de-banda-%e2%80%93-parte-3/</link>
		<comments>http://blog.gustavohenrique.net/2010/01/servidor-linux-com-proxy-e-controle-de-banda-%e2%80%93-parte-3/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 19:00:10 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[qos]]></category>
		<category><![CDATA[shell script]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=210</guid>
		<description><![CDATA[Finalmente consegui escrever a última parte do artigo. Nas partes 1 e 2 mostrei como configurar um servidor Linux para firewall e controle de banda, usando scripts que fazem a leitura de um arquivo texto contendo as informações dos pontos de rede (IP, MAC, velocidade de download e upload&#8230;). Entretanto, acessar o servidor e ficar [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/firewall.jpg"><img class="aligncenter size-full wp-image-219" title="firewall" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/firewall.jpg" alt="firewall" width="300" height="240" /></a><br />
Finalmente consegui escrever a última parte do artigo. <img src='http://blog.gustavohenrique.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
Nas partes 1 e 2 mostrei como configurar um servidor Linux para firewall e controle de banda, usando scripts que fazem a leitura de um arquivo texto contendo as informações dos pontos de rede (IP, MAC, velocidade de download e upload&#8230;). Entretanto, acessar o servidor e ficar editando um arquivo texto, na minha opinião é muito chato, possui risco de falha humana e apenas quem tem acesso ao servidor pode fazer isso. Para resolver esse contratempo foi desenvolvido o <a href="http://github.com/gustavohenrique/bandcontrol/" target="_blank">Bandcontrol</a>, um pequeno sistema web que armazena os dados dos pontos de rede em um banco de dados e gera o arquivo texto usado pelos shell scripts.<br />
O sistema foi desenvolvido em <a href="http://www.djangobrasil.org" target="_blank">Django</a>, personalizando o <a target="_blank">Admin</a>. Vou mostrar apenas como instalar e usar. O código fonte está disponível para consulta de programadores, curiosos e simpatizantes.<br />
<span id="more-210"></span></p>
<h2>Instalação</h2>
<p>Há diversas maneiras de se instalar um sistema feito em django. Vou mostrar como fazer o deploy usando Apache2 com o módulo mod_wsgi.<br />
O ambiente completo usa Apache2, sqlite3, python-2.6 e Django-1.1.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">root@localhost# apt-get install apache2 libapache2-mod-wsgi sqlite3 python-pysqlite2 python-django</pre></div></div>

<p>O diretório web padrão do Apache no Ubuntu é o <code>/var/www</code>. Vamos manter assim. Faça o download do <a>Bandcontrol</a> pelo site <a href="http://github.com/gustavohenrique/bandcontrol">github.com</a> (no site, clique no botão Download Source), descompacte no <code>/var/www</code>, renomeie o diretório para <code>bandcontrol</code> e altere o dono/grupo de acordo com o usuário do apache.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">root@localhost: /var/www# tar zxvf gustavohenrique-bandcontrol-XXXXXX.tar.gz
root@localhost: /var/www# mv gustavohenrique-bandcontrol-XXXXXX bandcontrol
root@localhost: /var/www# chown www-data.www-data -Rf bandcontrol</pre></div></div>

<p>Os shell scripts usam o <code>Iptables</code> para firewall e <code>TC</code> para controle de banda. É necessário permissão de super usuário para executar esses comandos. Vamos configurar o <code>sudo</code> para que o usuário do Apache possa executar tais comandos como root.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">root@localhost: /var/www# visudo</pre></div></div>

<p>Adicione essas linhas no arquivo <code>/etc/sudoers</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># No Ubuntu o iptables e o tc estao dentro do /sbin
Cmd_Alias BANDCONTROL = /sbin/iptables, /sbin/tc
www-data  ALL = (ALL) NOPASSWD: BANDCONTROL</pre></div></div>

<h3>Configuracao do Apache</h3>
<p>Configure um virtualhost no apache criando o arquivo <code>/etc/apache2/sites-enabled/bandcontrol</code> contendo:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">WSGIRestrictStdout Off
NameVirtualHost bandcontrol
&nbsp;
        ServerAdmin webmaster@localhost
        LimitInternalRecursion 1000
        ServerName bandcontrol
&nbsp;
&nbsp;
                Options ExecCGI FollowSymLinks MultiViews
                AllowOverride FileInfo
                MultiviewsMatch Handlers
                Order deny,allow
                Allow from all
&nbsp;
&nbsp;
        ErrorLog /var/log/apache2/bandcontrol_error.log
        CustomLog /var/log/apache2/bandcontrol_access.log combined
&nbsp;
        WSGIScriptAlias /     &quot;/var/www/bandcontrol/config.wsgi&quot;
&nbsp;
        Alias /admin_media/ &quot;/usr/lib/pymodules/python2.6/django/contrib/admin/media/&quot;
        Alias /media/           &quot;/var/www/bandcontrol/media/&quot;</pre></div></div>

<p>Edite o <code>/etc/hosts</code> e adicione:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">127.0.0.2     bandcontrol</pre></div></div>

<h3>Configuracao do Bandcontrol</h3>
<p>Altere o arquivo <code>/var/www/bandcontrol/config.wsgi</code> ajustando o diretório de instalação do Django. O padrão do Ubuntu é <code>/usr/lib/pymodules/python2.6/django</code>. Nesse arquivo também é configurado o diretório do bandcontrol:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
PROJECT_ROOT_PATH = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, PROJECT_ROOT_PATH<span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/usr/lib/pymodules/python2.6/django/'</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/var/www'</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span>=<span style="color: #483d8b;">'settings'</span>
<span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>
application = django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> bandcontrol.<span style="color: black;">monitor</span>
bandcontrol.<span style="color: black;">monitor</span>.<span style="color: black;">start</span><span style="color: black;">&#40;</span>interval=<span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span></pre></div></div>

<p>No arquivo <code>/var/www/bandcontrol/settings.py</code> é possível fazer mais alterações.<br />
Para definir as interfaces de rede e classe IP utilizada na rede, edite os arquivos <code>/var/www/bandcontrol/scripts/CONFIG</code> e <code>/var/www/bandcontrol/scripts/firewall</code>.</p>
<p><!-- Cada vez que alterar algum arquivo <code>.py</code> do <code>bandcontrol</code> será necessário atualizar o arquivo <code>config.wsgi</code> para que as alterações surtam efeito. Para isso usamos o comando <code>touch config.wsgi</code>. Outras alternativas são reiniciar o Apache ou utilizar um arquivo <code>monitor.py</code> descrito em artigo anterior nesse mesmo blog. --><br />
Por padrão é utilizado o banco de dados sqlite3. Você pode escolher usar o MySQL ou PostgreSQL editando o arquivo <code>/var/www/bandcontrol/settings.py</code>.<br />
Para criar o BD, entre no diretório do bandcontrol e execute o comando <code>manage.py syncdb</code>. Digite <code>yes</code> para confirmar a criação do super usuário. Forneça um login, e-mail e senha:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">root@localhost: /var/www/bandcontrol# python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table django_admin_log
Creating table rede_plano
Creating table rede_pontorede
&nbsp;
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'root'): gustavo
E-mail address: eu@gustavohenrique.net
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for admin.LogEntry model
Installing index for rede.PontoRede model</pre></div></div>

<p>Reinicie o Apache para que as alterações tenham efeito.</p>
<h2>Utilização</h2>
<p>Abra o browser e acesse <strong>http://bandcontrol/</strong>.<br />
Reparem que no campo de endereço da URL e os nomes de usuário utilizados não condizem com o que foi exemplificado nesse artigo. Bom... estou com preguiça para alterar as imagens, então vamos desconsiderar esse "bug".</p>
<p>Entre com o login e senha criados no passo anterior.<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela0.jpg"><img class="aligncenter size-medium wp-image-211" title="bandcontrol_tela0" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela0-300x217.jpg" alt="bandcontrol_tela0" width="300" height="217" /></a></p>
<p>Tela inicial do sistema.<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela1.jpg"><img class="aligncenter size-medium wp-image-212" title="bandcontrol_tela1" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela1-300x217.jpg" alt="bandcontrol_tela1" width="300" height="217" /></a></p>
<p>Clique em Planos e vamos criar alguns.<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela2.jpg"><img class="aligncenter size-medium wp-image-213" title="bandcontrol_tela2" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela2-300x217.jpg" alt="bandcontrol_tela2" width="300" height="217" /></a></p>
<p>Volte à tela inicial, clique em Pontos de Rede. No menu superior há opção para executar o firewall, parar o controle de banda e exibir os IPs conectados ao servidor. Sempre que fizer alguma alteração no sistema deve executar o firewall para ativar as mudanças.<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela3.jpg"><img class="aligncenter size-medium wp-image-214" title="bandcontrol_tela3" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela3-300x217.jpg" alt="bandcontrol_tela3" width="300" height="217" /></a></p>
<p>Em exibir IPs conectados, para adicionar um IP no sistema forneça uma descrição única, escolha o plano e clique em [+].<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela4.jpg"><img class="aligncenter size-medium wp-image-215" title="bandcontrol_tela4" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela4-300x217.jpg" alt="bandcontrol_tela4" width="300" height="217" /></a></p>
<p>O bandcontrol permite criar outros usuários com acesso ao sistema. Trabalha com permissões e grupos. Cortesia do Django \o/<br />
<a href="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela5.jpg"><img class="aligncenter size-medium wp-image-216" title="bandcontrol_tela5" src="http://blog.gustavohenrique.net/wp-content/uploads/2010/01/bandcontrol_tela5-300x217.jpg" alt="bandcontrol_tela5" width="300" height="217" /></a></p>
<h2>Conclusão</h2>
<p>Bandcontrol foi uma daquelas coisas "pra ontem". Foi feito em uma tarde de terça-feira. Tal velocidade se deve ao framework Django.<br />
Esse artigo foi escrito um pouco de cada vez, por isso há grandes chances de algo sair errado. Há muito material disponível na web sobre deploy de projetos em Django. Em caso de dúvidas estarei disposto a ajudar.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2010/01/servidor-linux-com-proxy-e-controle-de-banda-%e2%80%93-parte-3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mais um site em Django: xsol.com.br</title>
		<link>http://blog.gustavohenrique.net/2009/07/mais-um-site-em-django-xsol-com-br/</link>
		<comments>http://blog.gustavohenrique.net/2009/07/mais-um-site-em-django-xsol-com-br/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 20:05:39 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Curiosidades]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[xsol]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=126</guid>
		<description><![CDATA[Faz algumas semanas que já se encontra no ar um novo site brasileiro desenvolvido em Django, da empresa Xsol Tecnologia em Documentos. Trata-se de um e-commerce cujo código está sendo modificado (alguns detalhes, por questões de segurança) para em breve ser disponibilizado como open source. O tempo gasto para codificar o site levou aproximadamente 40 [...]]]></description>
			<content:encoded><![CDATA[<p>Faz algumas semanas que já se encontra no ar um novo site brasileiro desenvolvido em Django, da empresa <a href="http://www.xsol.com.br" target="_blank">Xsol Tecnologia em Documentos</a>. Trata-se de um e-commerce cujo código está sendo modificado (alguns detalhes, por questões de segurança) para em breve ser disponibilizado como open source.<br />
O tempo gasto para codificar o site levou aproximadamente 40 horas. Devo isso graças à dupla Django + JQuery que agiliza a vida de qualquer desenvolvedor.<br />
Quem quiser conferir, acesse <a href="http://www.xsol.com.br">http://www.xsol.com.br</a>.</p>
<div id="attachment_127" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.gustavohenrique.net/wp-content/uploads/2009/07/site_mini_xsol1.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2009/07/site_mini_xsol-300x225.jpg" alt="Xsol Tecnologia em Documentos" title="Screenshot xsol.com.br" width="300" height="225" class="size-medium wp-image-127" /></a><p class="wp-caption-text">Xsol Tecnologia em Documentos</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2009/07/mais-um-site-em-django-xsol-com-br/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jqDjangoGrid &#8211; plugin JQuery com Django para criar datagrids</title>
		<link>http://blog.gustavohenrique.net/2009/07/jqdjangogrid-plugin-jquery-django-datagrid/</link>
		<comments>http://blog.gustavohenrique.net/2009/07/jqdjangogrid-plugin-jquery-django-datagrid/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 16:26:11 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=118</guid>
		<description><![CDATA[jqDjangoGrid é um plugin para JQuery com uma aplicação plugável do Django para criar um datagrid. Fácil de instalar e customizar, possui ordenação de resultados e pesquisa usando ajax. Atualmente não suporta recurso de inserir ou alterar registros diretamente no datagrid, mas possui um método genérico para remoção de registros e outro que retorna a [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_119" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.gustavohenrique.net/wp-content/uploads/2009/07/jqdjangogrid1.jpg"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2009/07/jqdjangogrid-300x158.jpg" alt="Tela do jqDjangoGrid" title="jqdjangogrid" width="300" height="158" class="size-medium wp-image-119" /></a><p class="wp-caption-text">Tela do jqDjangoGrid</p></div>
<p>jqDjangoGrid é um plugin para JQuery com uma aplicação plugável do Django para criar um datagrid.<br />
Fácil de instalar e customizar, possui ordenação de resultados e pesquisa usando ajax.<br />
Atualmente não suporta recurso de inserir ou alterar registros diretamente no datagrid, mas possui um método genérico para remoção de registros e outro que retorna a PK (Primary Key) do objeto selecionado.<br />
<span id="more-118"></span></p>
<h2>INTRODUÇÃO</h2>
<p>Neste artigo mostrarei como é fácil instalar e usar o jqDjangoGrid. Todos os códigos estão comentados para ajudar à quem precisar fazer alguma modificação, por isso eu aconselho a usar algum compactador de código javascript se for usar em ambiente de produção.<br />
O tema padrão é o mesmo utilizado em um artigo anterior sobre datagrid com django, usando tons cinzas e azul. É fácil criar novos temas, bastar alterar o arquivo CSS e substituir as imagens.</p>
<p><del datetime="2009-07-29T12:14:53+00:00">Estou disponibilizando 2 arquivos para download, um contendo apenas o jqDjangoGrid e o outro contendo uma aplicação de exemplo (Um cadastro de bookmarks)</del>. É necessária a biblioteca <a href="http://www.jquery.com" target="_blank">JQuery</a> para funcionar. Os pacotes estão com a versão 1.3.2 dessa biblioteca.</p>
<p>Download:</p>
<p>Baixe a última versão com um exemplo no site github.com.<br />
<a href="http://github.com/gustavohenrique/jqdjangogrid">Código no GitHub</a></p>
<h2>INSTALAÇÃO E UTILIZAÇÃO</h2>
<p>Instalação:</p>
<ol>
<li>Descompacte o pacote jqdjangogrid.tar.gz;</li>
<li>copie o diretório jqdjangogrid, que é a app em django, para o diretório do seu projeto;</li>
<li>Copie os arquivos .js para o diretório de arquivos javascript do seu projeto (dento do MEDIA_ROOT);</li>
<li>Copie o diretório themes para o diretório de arquivos CSS do seu projeto (também dentro do MEDIA_ROOT)</li>
</ol>
<p>Utilização:</p>
<p>Insira jqdjangogrid em INSTALLED_APPS localizada no settings.py e depois crie uma regra no urls.py.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">INSTALLED_APPS = <span style="color: black;">&#40;</span>
    <span style="color: #808080; font-style: italic;"># outras apps instaladas aqui</span>
    <span style="color: #483d8b;">'jqdjangogrid'</span>,
<span style="color: black;">&#41;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: #808080; font-style: italic;"># suas outras regras aqui</span>
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^jqdjangogrid/'</span>, include<span style="color: black;">&#40;</span><span style="color: #483d8b;">'jqdjangogrid.urls'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Inclua uma referência para os arquivos jqdjangogrid.css, jquery.js e jqdjangogrid.js dentro do template HTML principal. Ex.:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
&lt;link rel=&quot;StyleSheet&quot; type=&quot;text/css&quot; href=&quot;/path_to_your_css/css/themes/default/jqdjangogrid.css&quot;&gt;
&lt;script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot; src=&quot;/path_to_your_js/jquery.js&quot;&gt;&lt;/script&gt;
&lt;script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot; src=&quot;/path_to_your_js/jqdjangogrid.js&quot;&gt;&lt;/script&gt;
...</pre></div></div>

<p>Crie um div qualquer para servir como contâiner para o datagrid.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div id=&quot;mydatagrid&quot;&gt;&lt;/div&gt;</pre></div></div>

<p>Agora é só criar um objeto datagrid passando as configurações. Abaixo um exemplo com as configurações básicas criado no momento em que a página é carregada:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">&lt;!-- dentro da tag head --&gt;
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#mydatagrid'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">datagrid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">'appLabel'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'myapp'</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">'modelName'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'MyClassName'</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">'cols'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;pk&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;label&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;width&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;10px&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;field1&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;label&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Campo 1&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;width&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;100px&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;field2&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;label&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Campo 2&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;width&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;300px&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Assim, ao carregar a página, será criado um datagrid contendo 3 colunas. Quando o nome da coluna for pk, vai aparecer um radio input cujo valor é a chave primária. Os outros atributos do campo são largura e label que vai aparecer no datagrid.</p>
<p>Conheça outros recursos na próxima página.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2009/07/jqdjangogrid-plugin-jquery-django-datagrid/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Integrando PagSeguro com Django</title>
		<link>http://blog.gustavohenrique.net/2009/07/integrando-pagseguro-com-django/</link>
		<comments>http://blog.gustavohenrique.net/2009/07/integrando-pagseguro-com-django/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 16:57:09 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[PagSeguro]]></category>
		<category><![CDATA[urllib]]></category>
		<category><![CDATA[Webservices]]></category>

		<guid isPermaLink="false">http://www.gustavohenrique.net/brogui/?p=113</guid>
		<description><![CDATA[Nesse artigo mostrarei de uma maneira rápida e resumida como integrar o meio de pagamento PagSeguro à uma loja virtual com carrinho próprio. O código é simples e pode ser adaptado para o uso com outros serviços de pagamento como por exemplo o Pagamento Digital. INTRODUÇÃO O funcionamento da integração com o PagSeguro é simples: [...]]]></description>
			<content:encoded><![CDATA[<p>Nesse artigo mostrarei de uma maneira rápida e resumida como integrar o meio de pagamento <a href="http://www.pagseguro.com.br" target="_blank">PagSeguro</a> à uma loja virtual com carrinho próprio. O código é simples e pode ser adaptado para o uso com outros serviços de pagamento como por exemplo o <a href="http://www.pagamentodigital.com.br" target="_blank">Pagamento Digital</a>.<br />
<span id="more-113"></span></p>
<h2>INTRODUÇÃO</h2>
<p>O funcionamento da integração com o PagSeguro é simples:</p>
<ol>
<li>Preenchimento do form com dados do pedido:<br />
      Uma view do site renderiza um template contendo um form com campos ocultos (input type=&#8221;hidden&#8221;) preenchidos com dados sobre o pedido.
  </li>
<li>Envio dos dados à URL do pagseguro:<br />
      O form é submetido via POST para a URL do PagSeguro que recebe os dados do pedido e exibe a tela de escolha da forma de pagamento.
  </li>
<li>Envio dos dados sobre a transação:<br />
      Após o comprador escolher a forma de pagamento, o robô do PagSeguro envia em segundo plano um POST para a URL de retorno configurada pelo vendedor no site do PagSeguro. Em seguida redireciona o comprador para essa mesma URL de retorno.
  </li>
</ol>
<p>A parte mais complicada é no passo 3, onde ocorre a comunicação em segundo plano (invisível ao usuário, não aparece no browser).<br />
O robô do PagSeguro envia um POST para a URL de retorno definida pelo vendedor. Então é preciso verificar nessa URL se houve alguma requisição via POST. Então o método da view envia uma requisição ao PagSeguro, também em segundo plano, contendo os mesmos dados obtidos via POST e um código único (token) definido no painel de configuração da conta no site do PagSeguro. Após verificado a autenticidade da transação, os dados são armazenados no banco de dados para que o cliente possa acompanhar o status do pedido diretamente no seu site.</p>
<h2>MÃO NA MASSA</h2>
<p>Não será abordado quais campos e tipos de dados que devem ser enviados ao PagSeguro. Essas informações estão bem documentadas no site do mesmo.<br />
No momento apenas será descrito como verificar a autenticidade da transação.</p>
<p>Vamos criar uma app chamada utils. Dentro do diretório dessa app, criamos o arquivo pagamentolib.py.</p>
<pre>
$ python manage.py startapp utils
$ vim utils/pagamentolib.py
</pre>
<p>Eis o código do pagamentolib.py:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>, <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Pagamento<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _conectar<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, url, params<span style="color: black;">&#41;</span>:
        query_str = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
        req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>url, query_str<span style="color: black;">&#41;</span>
        f = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
        conteudo = f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> conteudo
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _enviar<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, url, params<span style="color: black;">&#41;</span>:
        retorno = <span style="color: #008000;">self</span>._conectar<span style="color: black;">&#40;</span>url, params<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> retorno.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'verificado'</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">False</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> PagSeguro<span style="color: black;">&#40;</span>Pagamento<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> processar<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #dc143c;">token</span>, params, url=<span style="color: #483d8b;">'https://pagseguro.uol.com.br/Security/NPI/Default.aspx'</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> params:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">False</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            lista = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> params.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                lista.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>key,params<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            lista.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Comando'</span>, <span style="color: #483d8b;">'validar'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            lista.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Token'</span>, <span style="color: #dc143c;">token</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._enviar<span style="color: black;">&#40;</span>url, lista<span style="color: black;">&#41;</span></pre></div></div>

<p>Como exemplo, nossa URL de retorno é http://www.seusite.com/concluir/, que chama o método <code>concluir</code> contido na app <code>carrinho</code></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">views</span>.<span style="color: black;">generic</span>.<span style="color: black;">simple</span> <span style="color: #ff7700;font-weight:bold;">import</span> direct_to_template
<span style="color: #ff7700;font-weight:bold;">from</span> meuprojeto.<span style="color: black;">utils</span>.<span style="color: black;">pagamentolib</span> <span style="color: #ff7700;font-weight:bold;">import</span> PagSeguro
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> concluir<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Descricao:
    Armazena os dados do pedido e exibe a tela de pedido concluido.
    Verifica se o robo do PagSeguro enviou os dados do pedido via POST, e
    então armazena no banco de dados.
    Por fim, exibe a tela de pedido concluido com sucesso.
    &quot;&quot;&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> request.<span style="color: black;">method</span> == <span style="color: #483d8b;">'POST'</span>:
        <span style="color: #808080; font-style: italic;"># token gerado no painel de controle do PagSeguro</span>
        <span style="color: #dc143c;">token</span> = <span style="color: #483d8b;">'12345699CA2AAAF4599EA697BB2F7FFF'</span>
        p = PagSeguro<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        retorno = p.<span style="color: black;">processar</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">token</span>, request.<span style="color: black;">POST</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> retorno == <span style="color: #008000;">True</span>:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                <span style="color: #808080; font-style: italic;"># Cadastra os dados recebidos no banco de dados.</span>
                <span style="color: #808080; font-style: italic;"># Utilize o request.POST.get('nomedocampo') para obter os valores</span>
            <span style="color: #ff7700;font-weight:bold;">except</span>:
                <span style="color: #ff7700;font-weight:bold;">pass</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponse<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Ok'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponse<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Error'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #808080; font-style: italic;"># Carrega tela contendo a mensagem de compra realizada</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> direct_to_template<span style="color: black;">&#40;</span>request,<span style="color: #483d8b;">'carrinho/concluir.html'</span><span style="color: black;">&#41;</span></pre></div></div>

<h2>SERVIDOR DE TESTE</h2>
<p>No site da Visie (empresa parceira do PagSeguro) está disponível para download uma aplicação feita em python que simula o servidor do PagSeguro. Com esse servidor de testes é possível verificar se a integração está enviando e recebendo os dados corretamente. É um servidor semelhante ao que acompanha o Django.</p>
<ol>
<li>
Faça o download em: <a href="http://visie.com.br/pagseguro/pagseguro_testserver_v0.21.zip" target="_blank">http://visie.com.br/pagseguro/pagseguro_testserver_v0.21.zip</a> e Descompacte em qualquer diretório.
</li>
<li>
Entre no diretório <code>pagseguroMockup</code>, edite o arquivo <code>settings.py</code> e altere o valor da variável <code>retornourl</code> para sua URL de retorno em ambiente de teste. Altere também dentro do arquivo <code>pagseguro.py</code> na linha 77 onde está &#8216;ProdId&#8217; por &#8216;ProdID&#8217;.
</li>
<li>
Insira a linha <code>127.0.0.1	pagseguro.uol.com.br	pagseguro</code> no arquivo <code>/etc/hosts</code>. Agora basta executar o comando <code>sudo python PagSeguroServer.py</code> para iniciar o servidor de testes. Ctrl + C para sair.
</li>
</ol>
<h2>CONCLUSÃO</h2>
<p>O que foi mostrado nesse artigo também serve com base para comunicação com webservices de outros serviços de pagamento on-line. Eu aconselho a quem estiver pensando em desenvolver um e-commerce que utilize algum serviço desse tipo a não se prender em apenas um. Deixem pré-configurado uma segunda alternativa caso venha a ter problemas com a primeira.<br />
Fiquei decepcionado quando não encontrei exemplos em Python no site do PagSeguro. Na minha opinião, se uma empresa disponibiliza um webservice e ganha sobre isso, deveria investir melhor na documentação e principalmente no suporte.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2009/07/integrando-pagseguro-com-django/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

