<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Chronosbox</title>
	
	<link>http://chronosbox.org/blog</link>
	<description>idéias e dicas de uma mente insana trabalhando com TI</description>
	<lastBuildDate>Thu, 02 Sep 2010 02:09:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>pt</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/chronosbox" /><feedburner:info uri="chronosbox" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Introdução ao PostgreSQL e HTML 5 (WTH!?)</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/6nDWHYD33Y0/postgres-slides-and-html5</link>
		<comments>http://chronosbox.org/blog/postgres-slides-and-html5#comments</comments>
		<pubDate>Thu, 02 Sep 2010 02:07:15 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[postgres]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=370</guid>
		<description><![CDATA[
O MySQL é um banco muito conhecido, e muitos sabem &#8216;usar&#8217;. O PostgreSQL já não é tão conhecido e muitos só já ouviram falar. Com este fato, a pouco tempo, comecei a desenvolver uma série de slides introdutórios ao PostgreSQL, tendo como alvo uma palestra na Lightcomm, empresa onde trabalho.
Os slides em si, são bastante introdutórios, [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>O MySQL é um banco muito conhecido, e muitos sabem &#8216;usar&#8217;. O PostgreSQL já não é tão conhecido e muitos só já ouviram falar. Com este fato, a pouco tempo, comecei a desenvolver uma série de slides introdutórios ao PostgreSQL, tendo como alvo uma palestra na <a title="Lightcomm" href="http://www.lightcomm.com.br/" target="_blank">Lightcomm</a>, empresa onde trabalho.</p>
<p>Os slides em si, são bastante introdutórios, apenas ao nível básico, então se quem conhece bem PostgreSQL quiser dar uma revisada eu ficaria muito honrado <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . A parte interessante destes slides para quem já conhece PostgreSQL e até mesmo para quem nunca mecheu, é que elas usam como &#8216;engine&#8217; os slides demonstrados no <a title="HTML5ROCKS" href="http://www.html5rocks.com/" target="_blank">html5rocks.com</a>, todo baseado em HTML5 / CSS3 / JS &#8230; Atualmente só testei ele no Chrome, e o resultado, na minha opnião foi muito bom.</p>
<p>Desenvolvi a palestra com muito conforto, pois é puro HTML / CSS, os slides ainda do <a title="HTML5ROCKS" href="http://www.html5rocks.com/" target="_blank">html5rocks.com</a> ainda vem com demos de uso de SVG, vídeo e áudio, o que pode realmente ser muito útil em palestra mais complexas (introdução ao Django por exemplo). Eu adotei esse método como o meu default para construção de slides, o código está no github <a href="http://github.com/chronossc/postgres_presentation/" target="_blank">[1]</a> e se quiser você pode fazer o download do pacote tgz / zip <a href="http://github.com/chronossc/postgres_presentation/downloads">[2]</a> <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Eu aconselho a experimentar! Quem quiser pode contribuir melhorando a palestra, traduzindo para outras línguas ou só me apontando bugs <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>[1]<a href="http://github.com/chronossc/postgres_presentation/">http://github.com/chronossc/postgres_presentation/</a></p>
<p>[2] <a href="http://github.com/chronossc/postgres_presentation/downloads">http://github.com/chronossc/postgres_presentation/downloads</a></p>
<p>See ya</p>
</div>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/6nDWHYD33Y0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/postgres-slides-and-html5/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/postgres-slides-and-html5</feedburner:origLink></item>
		<item>
		<title>JSONResponse – Trabalhando com JSON em Django, o jeito fácil.</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/WxuNUCQJfq0/jsonresponse-in-django</link>
		<comments>http://chronosbox.org/blog/jsonresponse-in-django#comments</comments>
		<pubDate>Wed, 14 Apr 2010 03:40:22 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Apps e extensões]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=294</guid>
		<description><![CDATA[Existem por ai dezenas de artigos e snippets sobre como trabalhar com 	JSON
 em Django, entretanto vi que a maioria é um pouco vaga e a solução envolve serializar com simplejson e mandar para o HttpResponse. Existem alguns detalhes que normalmente não se cobrem e eu apresento a maneira fácil de trabalhar e um exemplo [...]]]></description>
			<content:encoded><![CDATA[<p>Existem por ai dezenas de artigos e snippets sobre como trabalhar com 	<a href="http://www.json.org/">JSON</a><br />
 em <a href="http://www.djangoproject.com/">Django</a>, entretanto vi que a maioria é um pouco vaga e a solução envolve serializar com simplejson e mandar para o HttpResponse. Existem alguns detalhes que normalmente não se cobrem e eu apresento a maneira fácil de trabalhar e um exemplo funcional de JSON em um formulário.<br />
<span id="more-294"></span></p>
<h3> :: Problemas comuns ::</h3>
<p>Os problemas mais comuns que vejo ao trabalhar com JSON em qualquer lugar e não só em Django são:</p>
<ul>
<ol>1. Nem sempre é simples parsear os argumentos enviados</ol>
<ol>2. O simplejson da problemas com alguns tipos de objetos</ol>
<ol>3. Porque não termos um JSONResponse em vez de somente o HttpResponse <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ?</ol>
</ul>
<h3>:: A solução ::</h3>
<ul>
<ol>1. Criar um JSON serializer que manipula objetos que dão problema ao simplejson.dumps</ol>
<ol>2. Criar a JSONResponse, baseada na HttpResponse e no nosso novo serializer</ol>
<ol>3. Achar um meio fácil de parsear os argumentos enviados para obter o JSON
</ul>
<p>A JSONResponse usa o JSON serializer e retorna uma response com os parâmetros enviados pela view. Os parâmetros são os objetos a serem serializados.</p>
<p>Definido isso vamos criar uma APP Django chamada jsonui <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Ela tera 2 models, cidade e estado, 2 views, a main e a que retorna o json, um form simples e os arquivos response.py e utils.py com os métodos que usaremos para gerar o JSON bonitinho.</p>
<h4>:: O JSON serializer ::</h4>
<p>O serializer reside no utils, ele é divido em um JSONEncoder usado pelo simplejson que é responsável por interpretar os objetos que dariam problema, e no serializer propriamente dito que nada mais é um wrapper pro simplejson:</p>
<p class="file">Arquivo: <span class="name">jsonui/utils.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="co1"># -*- coding: utf-8 -*-</span>
&nbsp;
<span class="kw1">from</span> django.<span class="me1">utils</span> <span class="kw1">import</span> simplejson
<span class="kw1">from</span> django.<span class="me1">utils</span>.<span class="me1">encoding</span> <span class="kw1">import</span> force_unicode
<span class="kw1">from</span> django.<span class="me1">db</span>.<span class="me1">models</span>.<span class="me1">base</span> <span class="kw1">import</span> ModelBase
&nbsp;
<span class="kw1">class</span> LazyJSONEncoder<span class="br0">&#40;</span>simplejson.<span class="me1">JSONEncoder</span><span class="br0">&#41;</span>:
    <span class="st0">&quot;&quot;&quot; a JSONEncoder subclass that handle querysets and models objects.
    Add how handle your type of object here to use when when dump json&quot;&quot;&quot;</span>
    <span class="kw1">def</span> default<span class="br0">&#40;</span><span class="kw2">self</span>,o<span class="br0">&#41;</span>:
        <span class="co1"># this handles querysets and other iterable types</span>
        <span class="kw1">try</span>:
            iterable = <span class="kw2">iter</span><span class="br0">&#40;</span>o<span class="br0">&#41;</span>
        <span class="kw1">except</span> <span class="kw2">TypeError</span>:
            <span class="kw1">pass</span>
        <span class="kw1">else</span>:
            <span class="kw1">return</span> <span class="kw2">list</span><span class="br0">&#40;</span>iterable<span class="br0">&#41;</span>
&nbsp;
        <span class="co1"># this handlers Models</span>
        <span class="kw1">try</span>:
            <span class="kw2">isinstance</span><span class="br0">&#40;</span>o.__class__,ModelBase<span class="br0">&#41;</span>
        <span class="kw1">except</span> <span class="kw2">Exception</span>:
            <span class="kw1">pass</span>
        <span class="kw1">else</span>:
            <span class="kw1">return</span> force_unicode<span class="br0">&#40;</span>o<span class="br0">&#41;</span>
&nbsp;
        <span class="kw1">return</span> <span class="kw2">super</span><span class="br0">&#40;</span>LazyJSONEncoder,<span class="kw2">self</span><span class="br0">&#41;</span>.<span class="me1">default</span><span class="br0">&#40;</span>obj<span class="br0">&#41;</span>
&nbsp;
<span class="kw1">def</span> serialize_to_json<span class="br0">&#40;</span>obj,<span class="sy0">*</span>args,<span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:
    <span class="st0">&quot;&quot;&quot; A wrapper for simplejson.dumps with defaults as:
&nbsp;
    ensure_ascii=False
    cls=LazyJSONEncoder
&nbsp;
    All arguments can be added via kwargs
    &quot;&quot;&quot;</span>
&nbsp;
    kwargs<span class="br0">&#91;</span><span class="st0">'ensure_ascii'</span><span class="br0">&#93;</span> = kwargs.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">'ensure_ascii'</span>,<span class="kw2">False</span><span class="br0">&#41;</span>
    kwargs<span class="br0">&#91;</span><span class="st0">'cls'</span><span class="br0">&#93;</span> = kwargs.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">'cls'</span>,LazyJSONEncoder<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span class="kw1">return</span> simplejson.<span class="me1">dumps</span><span class="br0">&#40;</span>obj,<span class="sy0">*</span>args,<span class="sy0">**</span>kwargs<span class="br0">&#41;</span></pre></td></tr></table></div>

<h4>:: A JSONResponse ::</h4>
<p>A JSONResponse reside no response, basicamente ela recebe a lista, dicionário ou qualquer objeto que você envia para o JSONResponse e retorna serializado:</p>
<p class="file">Arquivo: <span class="name">jsonui/response.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="co1"># -*- coding: utf-8 -*-</span>
&nbsp;
<span class="kw1">from</span> utils <span class="kw1">import</span> serialize_to_json
<span class="kw1">from</span> django.<span class="me1">http</span> <span class="kw1">import</span> HttpResponseForbidden, HttpResponse
&nbsp;
<span class="kw1">class</span> JSONResponse<span class="br0">&#40;</span>HttpResponse<span class="br0">&#41;</span>:
    <span class="st0">&quot;&quot;&quot; JSON response class &quot;&quot;&quot;</span>
    <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>,content=<span class="st0">''</span>,json_opts=<span class="br0">&#123;</span><span class="br0">&#125;</span>,mimetype=<span class="st0">&quot;application/json&quot;</span>,<span class="sy0">*</span>args,<span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:
        <span class="st0">&quot;&quot;&quot;
        This returns a object that we send as json content using 
        utils.serialize_to_json, that is a wrapper to simplejson.dumps
        method using a custom class to handle models and querysets. Put your
        options to serialize_to_json in json_opts, other options are used by
        response.
        &quot;&quot;&quot;</span>
        <span class="kw1">if</span> content:
            content = serialize_to_json<span class="br0">&#40;</span>content,<span class="sy0">**</span>json_opts<span class="br0">&#41;</span>
        <span class="kw1">else</span>:
            content = serialize_to_json<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#93;</span>,<span class="sy0">**</span>json_opts<span class="br0">&#41;</span>
        <span class="kw2">super</span><span class="br0">&#40;</span>JSONResponse,<span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span>content,mimetype,<span class="sy0">*</span>args,<span class="sy0">**</span>kwargs<span class="br0">&#41;</span></pre></td></tr></table></div>

<h4>:: Botando pra funcionar na view. ::</h4>
<p>Sem mais rodeios, vamos ver como funciona. Nós temos duas views:</p>
<ul>
<li><em>mainview</em>: chama o form e renderiza um template com o código javascript necessário para executar o POST e renderizar o JSON que obtemos como resposta.</li>
<li><em>json_get_city</em>: responsável por retornar as cidades de acordo com o estado enviado.</li>
</ul>
<p></p>
<p class="file">Arquivo: <span class="name">urls.py</span> <span class="line">@ 17</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>17
18
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="br0">&#40;</span>r<span class="st0">'^$'</span>,<span class="st0">'jsonui.views.mainview'</span><span class="br0">&#41;</span>,
<span class="br0">&#40;</span>r<span class="st0">'^ajax/city/'</span>,<span class="st0">'jsonui.views.json_get_city'</span><span class="br0">&#41;</span>,</pre></td></tr></table></div>

<p class="file">Arquivo: <span class="name">jsonui/views.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="co1"># -*- coding: utf-8 -*-</span>
&nbsp;
<span class="kw1">from</span> django.<span class="me1">shortcuts</span> <span class="kw1">import</span> render_to_response
<span class="kw1">from</span> django.<span class="me1">template</span> <span class="kw1">import</span> RequestContext
&nbsp;
&nbsp;
<span class="kw1">from</span> models <span class="kw1">import</span> City,State
<span class="kw1">from</span> forms <span class="kw1">import</span> CityForm
&nbsp;
<span class="kw1">from</span> utils <span class="kw1">import</span> qdct_as_kwargs
<span class="kw1">from</span> response <span class="kw1">import</span> JSONResponse
&nbsp;
<span class="kw1">def</span> mainview<span class="br0">&#40;</span>request<span class="br0">&#41;</span>:
&nbsp;
    <span class="kw1">return</span> render_to_response<span class="br0">&#40;</span><span class="st0">'base.html'</span>,<span class="br0">&#123;</span><span class="st0">'form'</span>: CityForm<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>,
        context_instance=RequestContext<span class="br0">&#40;</span>request<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span class="kw1">def</span> json_get_city<span class="br0">&#40;</span>request<span class="br0">&#41;</span>:
&nbsp;
    <span class="kw1">if</span> <span class="kw1">not</span> request.<span class="me1">method</span> == <span class="st0">&quot;POST&quot;</span>:
        <span class="co1"># return all cities if any filter was send</span>
        <span class="kw1">return</span> JSONResponse<span class="br0">&#40;</span>City.<span class="me1">objects</span>.<span class="me1">order_by</span><span class="br0">&#40;</span><span class="st0">'name'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span class="co1"># get cities with request.POST as filter arguments</span>
    cities = City.<span class="me1">objects</span>.<span class="kw2">filter</span><span class="br0">&#40;</span><span class="sy0">**</span>qdct_as_kwargs<span class="br0">&#40;</span>request.<span class="me1">POST</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">order_by</span><span class="br0">&#40;</span><span class="st0">'name'</span><span class="br0">&#41;</span>
&nbsp;
    <span class="co1">#return JSONResponse with id and name</span>
    <span class="kw1">return</span> JSONResponse<span class="br0">&#40;</span>cities.<span class="me1">values</span><span class="br0">&#40;</span><span class="st0">'id'</span>,<span class="st0">'name'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>O método <em>qdct_as_kwargs</em> é responsável por retornar um dicionário que é passado parao método filter de um objeto a partir do request.POST ou request.GET. É uma magica legal que agiliza e muito a criação de views como essa.</p>
<p>Assim que a url /ajax/city/ recebe o POST ela obtem as cidades usando o <em>qdct_as_kwargs</em> e retorna a <em>JSONResponse</em>, no javascript a resposta é um JSON pronto para usar.</p>
<p class="file">Arquivo: <span class="name">jsonui/utils.py</span> <span class="line">@ 44</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>44
45
46
47
48
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="kw1">def</span> qdct_as_kwargs<span class="br0">&#40;</span>qdct<span class="br0">&#41;</span>:
kwargs=<span class="br0">&#123;</span><span class="br0">&#125;</span>
<span class="kw1">for</span> k,v <span class="kw1">in</span> qdct.<span class="me1">items</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:
    kwargs<span class="br0">&#91;</span><span class="kw2">str</span><span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#93;</span>=v
<span class="kw1">return</span> kwargs</pre></td></tr></table></div>

<p>O javascript responsável por mandar o POST esta no template <em>base.html</em> que é renderizado pela <em>mainview</em>. Este é o trecho relevante:</p>
<p class="file">Arquivo: <span class="name">templates/base.html</span> <span class="line">@ 10</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;color: #FCFFBA;">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    $<span class="br0">&#40;</span><span class="st0">&quot;#id_state&quot;</span><span class="br0">&#41;</span>.<span class="me1">change</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><span class="br0">&#123;</span>
        $.<span class="me1">post</span><span class="br0">&#40;</span>
            <span class="co1">// url to post</span>
            <span class="st0">&quot;/ajax/city/&quot;</span><span class="sy0">,</span>
            <span class="co1">// args</span>
            <span class="br0">&#123;</span>state__id<span class="sy0">:</span>$<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#125;</span><span class="sy0">,</span>
            <span class="co1">// response callback</span>
            <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="sy0">,</span>text<span class="sy0">,</span>xhrobject<span class="br0">&#41;</span><span class="br0">&#123;</span>
                <span class="co1">// uncomment if you wanna to see objects on firebug console</span>
                <span class="co1">//console.log(data,text,xhrobject)</span>
                $<span class="br0">&#40;</span><span class="st0">&quot;#id_city&quot;</span><span class="br0">&#41;</span>.<span class="me1">children</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
                    .<span class="me1">append</span><span class="br0">&#40;</span><span class="st0">&quot;&lt;option selected=<span class="es0">\&quot;</span>selected<span class="es0">\&quot;</span> value=<span class="es0">\&quot;</span><span class="es0">\&quot;</span>&gt;------&lt;/option&gt;&quot;</span><span class="br0">&#41;</span>
                <span class="kw1">for</span> <span class="br0">&#40;</span>i <span class="kw1">in</span> data<span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    i <span class="sy0">=</span> data<span class="br0">&#91;</span>i<span class="br0">&#93;</span>
                    $<span class="br0">&#40;</span><span class="st0">&quot;#id_city&quot;</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span>
                        <span class="st0">&quot;&lt;option value=<span class="es0">\&quot;</span>&quot;</span><span class="sy0">+</span>i.<span class="me1">id</span><span class="sy0">+</span><span class="st0">&quot;<span class="es0">\&quot;</span>&gt;&quot;</span><span class="sy0">+</span>i.<span class="kw3">name</span><span class="sy0">+</span><span class="st0">&quot;&lt;/option&gt;&quot;</span>
                    <span class="br0">&#41;</span>
                <span class="br0">&#125;</span>
            <span class="br0">&#125;</span><span class="br0">&#41;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>Este código executa um POST para /ajax/city/ e na volta preenche o select de cidades com o objeto retornado.</p>
<h3>:: Finalizando ::</h3>
<p>Reproduzindo javascripts similares e usando o qdct_as_kwargs e o JSONResponse como usado na view <em>json_get_city</em> você pode facílmente criar várias views ou até uma view mais genérica que pegue de qualquer modelo. Basta deixar a imaginação fluir <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Você pode baixar o projeto completo aqui: <a href="http://files.chronosbox.org/jsonproject.tbz2">jsonproject.tbz2</a> (<a href="http://files.chronosbox.org/jsonproject.tbz2.md5">MD5 Hash</a>) (<a href="http://chronosbox.org/jsonproject.tbz2">mirror</a>, <a href="http://chronosbox.org/jsonproject.tbz2.md5">mirror MD5</a>)</p>
<p>Eu construi ele usando Django 1.2, mas roda em qualquer versão acima da 1.0.</p>
<p>Divirta-se, contribua, comente <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Abraços!</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/WxuNUCQJfq0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/jsonresponse-in-django/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/jsonresponse-in-django</feedburner:origLink></item>
		<item>
		<title>Vim confs prontas para trabalhar com Python e Django</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/WE-1QBK24IM/read-to-work-vim-confs-for-python-and-django</link>
		<comments>http://chronosbox.org/blog/read-to-work-vim-confs-for-python-and-django#comments</comments>
		<pubDate>Sun, 07 Mar 2010 09:59:44 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[VIM - Vi IMproveded]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Colorscheme]]></category>
		<category><![CDATA[completion]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[jump]]></category>
		<category><![CDATA[manager]]></category>
		<category><![CDATA[matchit]]></category>
		<category><![CDATA[omni]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[snipmate]]></category>
		<category><![CDATA[vimrc]]></category>
		<category><![CDATA[wombat]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=280</guid>
		<description><![CDATA[Este fim de semana eu reescrevi meu .vimrc e gastei um tempo extra para fazer
as coisas funcionarem melhores para mim com python e django  . Eu acabei
fazendo um belo trabalho e agora estou codando com muito mais eficiência.
Os resultados são:

 Um .vimrc muito bem comentado e com muitas customizações.
 Suporte para python omnicomplete.
 Adição [...]]]></description>
			<content:encoded><![CDATA[<p>Este fim de semana eu reescrevi meu .vimrc e gastei um tempo extra para fazer<br />
as coisas funcionarem melhores para mim com python e django <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Eu acabei<br />
fazendo um belo trabalho e agora estou codando com muito mais eficiência.</p>
<p>Os resultados são:</p>
<ul>
<li> Um .vimrc muito bem comentado e com muitas customizações.</li>
<li> Suporte para python omnicomplete.</li>
<li> Adição dos paths python e django automáticos ao ambiente do vim.</li>
<li> Adição da DJANGO_SETTINGS_MODULE automaticamente ao ambiente do vim, para completar seu próprio código.</li>
<li> Suporte do SnipMate para código django e django templates.</li>
<li> Django templates com suporte para highlighting das tags e uso do &#8216;%&#8217; com o plugin matchit.</li>
<li> Python folding e suporte a python jumping.</li>
<li> O tema acinzentado wombat com algumas customizações minhas.</li>
<li> Um gerenciador de sessões para o Vim para facilitar sua vida em manter o ambiente de trabalho.</li>
</ul>
<p>Aqui estão os arquivos para download:</p>
<ul>
<li> <a href="http://chronosbox.org/vimconfs/vim-confs-latest.tbz2">vim-confs-latest.tbz2</a>: O arquivo tar compactado com todos os arquivos, descompacte na sua home.</li>
<li> <a href="http://chronosbox.org/vimconfs/vim-confs-latest.tbz2.md5">vim-confs-latest.tbz2.md5</a>: O md5sum do tar.</li>
</ul>
<p>Se você preferir, este é o endereço no github: <a href="http://github.com/chronossc/my-vim-confs">http://github.com/chronossc/my-vim-confs</a></p>
<p>O pacote não poderia ter sido criado sem alguns plugins e artigos, segue a referência:</p>
<ul>
<li> <a href="http://code.djangoproject.com/wiki/UsingVimWithDjango" target="_blank">UsingVimWithDjango do Django Wiki</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=2540" target="_blank">SnipMate vim plugin por Michael Sanders</a></li>
<li> <a href="http://github.com/robhudson/snipmate_for_django" target="_blank">SnipMate snippets for django por Rob Hudson</a> <a href="http://rob.cogit8.org/blog/2009/Sep/20/using-vim-and-snipmate-django/" target="_blank">(Demo)</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=39" target="_blank">Matchit vim plugin por Benji Fisher</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=1487" target="_blank">Updated Syntax highlighting for Django templates por Dave Hodder</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=1487" target="_blank">py_jump vim plugin por Sergiy Matusevych</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=1487" target="_blank">python fold vim plugin por Jorrit Wiersma</a></li>
<li> <a href="http://www.vim.org/scripts/script.php?script_id=2010" target="_blank">Session Manager for vim por Yuri Klubakov</a>
</ul>
<p>Adicionalmente (thx Handrus), eu sugiro para quem escreve muito HTML, dar uma olhada no <a href="http://jetpackweb.com/blog/2010/03/04/write-html-faster-with-sparkup-vim-and-textmate/" target="_blank">SparkUp vim and textmate plugin</a> <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Eu não testei, mas pareceu muito bom.</p>
<p>Muito obrigado a quem ler, a todos que escreveram os plugins, ao pessoal do canal #vim na freenode e a ótima documentação do vim!<br />
Agora bora codar com o vim <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>** Atualizado<br />
2010-03-07: Eu criei novamente o tar porque eu removi algumas mensagens de debug, então faça o download novamente se você já fez <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
2010-03-09: Eu criei novamente o tar, fiz alguns fixes e adicionei no github.</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/WE-1QBK24IM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/read-to-work-vim-confs-for-python-and-django/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/read-to-work-vim-confs-for-python-and-django</feedburner:origLink></item>
		<item>
		<title>Mudar charset e quebra de linha recursivamente no Linux</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/5D8OpSYHC1k/mudar-charset-e-quebra-de-linha-recursivamente-no-linux</link>
		<comments>http://chronosbox.org/blog/mudar-charset-e-quebra-de-linha-recursivamente-no-linux#comments</comments>
		<pubDate>Fri, 26 Feb 2010 18:50:46 +0000</pubDate>
		<dc:creator>Handrus Nogueira</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=273</guid>
		<description><![CDATA[A algum tempo atrás precisei passar uma aplicação web que utilizava quebras de linha no formato linux e charset iso-8859-1 (US-Latin) para UTF-8 com quebra de linha no formato windows. Na época codifiquei com a ajuda do chronos este script que agora compartilho:

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
#change extensions filter as you need ;)
find -type f &#124; egrep &#34;\.php&#124;\.css&#124;\.js&#124;\.html&#124;\.htm&#34; &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>A algum tempo atrás precisei passar uma aplicação web que utilizava quebras de linha no formato linux e charset iso-8859-1 (US-Latin) para UTF-8 com quebra de linha no formato windows. Na época codifiquei com a ajuda do chronos este script que agora compartilho:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;"><span class="co0">#!/bin/sh</span>
<span class="co0">#change extensions filter as you need ;)</span>
<span class="kw2">find</span> <span class="re5">-type</span> f <span class="sy0">|</span> <span class="kw2">egrep</span> <span class="st0">&quot;\.php|\.css|\.js|\.html|\.htm&quot;</span> <span class="sy0">|</span> <span class="kw2">egrep</span> <span class="re5">-v</span> <span class="st0">&quot;\.svn&quot;</span> <span class="sy0">&amp;</span>gt; .<span class="sy0">/</span>charset_list.txt;
<span class="kw1">while</span> <span class="kw2">read</span> <span class="re5">-r</span> line;<span class="kw1">do</span>
<span class="co0">#charset change</span>
iconv <span class="re5">-f</span> LATIN1 <span class="re5">-t</span> UTF-<span class="nu0">8</span> <span class="st0">&quot;<span class="es2">$line</span>&quot;</span> <span class="sy0">&amp;</span>gt; <span class="st0">&quot;<span class="es3">${line}</span>2&quot;</span>;
<span class="kw2">mv</span> <span class="st0">&quot;<span class="es3">${line}</span>2&quot;</span> <span class="st0">&quot;<span class="es2">$line</span>&quot;</span>;
<span class="co0">#we adopted dos format for line breaks</span>
unix2dos <span class="st0">&quot;<span class="es3">${line}</span>&quot;</span>;
<span class="kw1">done</span> <span class="sy0">&amp;</span>lt; .<span class="sy0">/</span>charset_list.txt <span class="sy0">&amp;</span>gt; .<span class="sy0">/</span>charset_after.log <span class="nu0">2</span><span class="sy0">&amp;</span>gt;<span class="sy0">&amp;</span>amp;<span class="nu0">1</span> <span class="co0">#receive list of params and send output to log</span></pre></td></tr></table></div>

<p>Explicações: O script gera uma lista com todos os arquivos da pasta onde ele se encontra e suas subpastas subsequentes (conforme o filtro explicado na segunda linha do código).<br />
Depois ele lê a lista e aplica as alterações num arquivo cópia. Move o arquivo sobre o anterior e depois altera as quebras de linha. Bastante simples, I LOVE BASH!</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/5D8OpSYHC1k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/mudar-charset-e-quebra-de-linha-recursivamente-no-linux/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/mudar-charset-e-quebra-de-linha-recursivamente-no-linux</feedburner:origLink></item>
		<item>
		<title>Migrando bases de dados LATIN1 para UTF-8 com o PostgreSQL</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/2KQ2mftB1Yg/moving-postgresql-databases-from-latim1-to-utf8</link>
		<comments>http://chronosbox.org/blog/moving-postgresql-databases-from-latim1-to-utf8#comments</comments>
		<pubDate>Sat, 06 Feb 2010 05:59:22 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Debian/Ubuntu]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Servidores]]></category>
		<category><![CDATA[clusters]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[iso-8859-1]]></category>
		<category><![CDATA[latin1]]></category>
		<category><![CDATA[pgsql]]></category>
		<category><![CDATA[psql]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[utf-8]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=264</guid>
		<description><![CDATA[Nos dias atuais é um padrão que todos os sites e servidores web rodem ao menos com UTF-8 como encoding default, entretanto pode-se encontrar casos onde ainda se roda LATIN1 ou até mesmo ASCII.
O caso que tratamos hoje é de um servidor Debian, versão 5.0.3 (lenny), que usava o encode LATIN1 quando instalado e configurado [...]]]></description>
			<content:encoded><![CDATA[<p>Nos dias atuais é um padrão que todos os sites e servidores web rodem ao menos com UTF-8 como encoding default, entretanto pode-se encontrar casos onde ainda se roda LATIN1 ou até mesmo ASCII.</p>
<p>O caso que tratamos hoje é de um servidor Debian, versão 5.0.3 (lenny), que usava o encode LATIN1 quando instalado e configurado o Postgresql, e não me deixava criar uma base de dados UTF-8, gerando o seguinte erro:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># su postgres -c 'createdb teste3  -E UTF-8'</span>
createdb: database creation failed: ERROR:  encoding UTF8 does not match server<span class="st_h">'s locale en_US
DETAIL:  The server'</span>s LC_CTYPE setting requires encoding LATIN1.</pre></div></div>

<p><span id="more-264"></span></p>
<h3>Porque??</h3>
<p>O Postgresql, quando roda pela primeira vez, cria um cluster usando o encode default do sistema, e após feito isso, não se pode alterar o encode do cluster. O cluster default é o main, em todas as intalações que eu vi. </p>
<p>No caso deste servidor o encode default (locales) era en_US, que para o Debian significa en_US.ISO-8859-1. Por default o Debian Lenny, nas minhas instalações do zero, usa en_US.UTF-8, então o servidor provavelmente deveria ser um antigo Debian Etch atualizado.</p>
<h3>A solução</h3>
<p>Depois de alguma pesquisa, descobri que, após configurar o encode do servidor para usar UTF-8, poderia criar um novo cluster que suportasse tal encode.</p>
<p>Vamos ao passo a passo da solução do problema.</p>
<ul>
<li><strong>Criando um novo cluster:</strong> Para criar um novo cluster no Debian, é bastante simples:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># pg_createcluster 8.3 utf8_cluster</span>
Creating new cluster <span class="br0">&#40;</span>configuration: <span class="sy0">/</span>etc<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster, data: <span class="sy0">/</span>var<span class="sy0">/</span>lib<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster<span class="br0">&#41;</span>...
Moving configuration <span class="kw2">file</span> <span class="sy0">/</span>var<span class="sy0">/</span>lib<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster<span class="sy0">/</span>postgresql.conf to <span class="sy0">/</span>etc<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster...
Moving configuration <span class="kw2">file</span> <span class="sy0">/</span>var<span class="sy0">/</span>lib<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster<span class="sy0">/</span>pg_hba.conf to <span class="sy0">/</span>etc<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster...
Moving configuration <span class="kw2">file</span> <span class="sy0">/</span>var<span class="sy0">/</span>lib<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster<span class="sy0">/</span>pg_ident.conf to <span class="sy0">/</span>etc<span class="sy0">/</span>postgresql<span class="sy0">/</span><span class="nu0">8.3</span><span class="sy0">/</span>utf8_cluster...
Configuring postgresql.conf to use port 5433...
&nbsp;
debian:~<span class="co0"># /etc/init.d/postgresql-8.3 restart</span></pre></div></div>

<p>O cluster vai rodar na primeira porta livre que achar depois da 5432, a não ser que você especifique. Para ter efeito, reinicia-se o Postgresql.</li>
<li><strong>Criando o usuário:</strong> Agora crie o usuário da base de dados, recomendo o mesmo nome e senha além de editar sua autenticação para trust no pg_hba.conf do seu cluster:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># su postgres -c &quot;createuser -P pyuser -p 5433&quot;</span>
Enter password <span class="kw1">for</span> new role:
Enter it again:
Shall the new role be a superuser? <span class="br0">&#40;</span>y<span class="sy0">/</span>n<span class="br0">&#41;</span> n
Shall the new role be allowed to create databases? <span class="br0">&#40;</span>y<span class="sy0">/</span>n<span class="br0">&#41;</span> n
Shall the new role be allowed to create <span class="kw2">more</span> new roles? <span class="br0">&#40;</span>y<span class="sy0">/</span>n<span class="br0">&#41;</span> n</pre></div></div>

</li>
<li><strong>Migrando as bases:</strong> Agora você deve migrar as bases de dados. Primeiro crie ela e depois faça um dump seguido de um psql, direto na linha de comando. Siga o exemplo:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># su postgres -c &quot;createdb teste3 -e -p 5433 -O pyuser&quot;</span>
CREATE DATABASE teste3 OWNER pyuser;</pre></div></div>

<p>Agora liste a base de dados:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># su postgres -c &quot;psql -l -p 5433&quot;</span>
        List of databases
   Name    <span class="sy0">|</span>  Owner   <span class="sy0">|</span> Encoding
-----------+----------+----------
 postgres  <span class="sy0">|</span> postgres <span class="sy0">|</span> UTF8
 template0 <span class="sy0">|</span> postgres <span class="sy0">|</span> UTF8
 template1 <span class="sy0">|</span> postgres <span class="sy0">|</span> UTF8	
 teste3    <span class="sy0">|</span> pyuser   <span class="sy0">|</span> UTF8
<span class="br0">&#40;</span><span class="nu0">4</span> rows<span class="br0">&#41;</span></pre></div></div>

<p>Após criar a base de dados, então faremos a população dela, atenção quanto as portas:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">debian:~<span class="co0"># pg_dump -U pyuser teste3 | psql -U pyuser -p 5433 teste3</span></pre></div></div>

</li>
<li><strong>Configurando sua aplicação:</strong> Esta é a parte mais simples, apenas altere a porta da sua aplicação para a porta do novo cluster.</li>
</ul>
<p>Repita os passos da criação da base de dados para cada base que precisa ser movida, e pronto, tudo funcionando agora com suporte a UTF-8.</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/2KQ2mftB1Yg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/moving-postgresql-databases-from-latim1-to-utf8/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/moving-postgresql-databases-from-latim1-to-utf8</feedburner:origLink></item>
		<item>
		<title>Configurando múltiplos ambientes Python</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/-XNGB1xzoko/setting-up-multiple-python-envrionments</link>
		<comments>http://chronosbox.org/blog/setting-up-multiple-python-envrionments#comments</comments>
		<pubDate>Wed, 27 Jan 2010 02:20:01 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[2.4]]></category>
		<category><![CDATA[2.5]]></category>
		<category><![CDATA[2.6]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[versions]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=259</guid>
		<description><![CDATA[Múltiplos ambientes python
Trabalhar com várias versões de ambientes python tem se tornado algo comum em minha vida, e acredito que um meio fácil de &#8217;setar&#8217; estes ambientes seja algo útil e  não tão simples para a maioria das pessoas.
Eu criei um simples bash script que seta este &#8216;ambiente&#8217;, trata-se de uma função que você [...]]]></description>
			<content:encoded><![CDATA[<h3>Múltiplos ambientes python</h3>
<p>Trabalhar com várias versões de ambientes python tem se tornado algo comum em minha vida, e acredito que um meio fácil de &#8217;setar&#8217; estes ambientes seja algo útil e  não tão simples para a maioria das pessoas.</p>
<p>Eu criei um simples bash script que seta este &#8216;ambiente&#8217;, trata-se de uma função que você cria no seu <em><strong>.bash_profile</strong></em>. Executa-se ela com a versão do python em seguida e pronto, seu ambiente esta configurado. Vamos ver no código como eu fiz, o script está com comentários em inglês:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;"><span class="kw3">export</span> <span class="re2">ORIGINALPATH</span>=<span class="re1">$PATH</span>
loadpyenv<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="co0"># $PV is our control variable, get from $1, first argument on shell</span>
    <span class="co0"># anything that you need to put here and depend for python version ${PV} is your var ;)</span>
    <span class="kw3">export</span> <span class="re2">PV</span>=$<span class="nu0">1</span>
    <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;<span class="es1">\n</span>:: Setting environ to use python <span class="es2">$PV</span>&quot;</span>
&nbsp;
    <span class="co0"># Put here various aliases that you can use</span>
    <span class="co0"># put a python alias</span>
    <span class="kw3">alias</span> <span class="re2">python</span>=<span class="st0">&quot;python<span class="es3">${PV}</span>&quot;</span>
    <span class="co0"># m and runserver a kick alias for Django common actions</span>
    <span class="kw3">alias</span> <span class="re2">m</span>=<span class="st0">&quot;python<span class="es3">${PV}</span> manage.py&quot;</span>
    <span class="kw3">alias</span> <span class="re2">runserver</span>=<span class="st0">&quot;python<span class="es3">${PV}</span> manage.py runserver :8000&quot;</span>
    <span class="co0"># easy and fast install of python packages, in right path with localpyinstall</span>
    <span class="kw3">alias</span> <span class="re2">localpyinstall</span>=<span class="st0">&quot;python<span class="es3">${PV}</span> setup.py install --prefix=~/.py/<span class="es3">${PV}</span>/&quot;</span>
    <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;<span class="es1">\n</span>:: New aliases&quot;</span>
    <span class="co0"># print aliases :)</span>
    <span class="kw3">alias</span> python m runserver localpyinstall
&nbsp;
    <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;<span class="es1">\n</span>:: New PATH&quot;</span>
    <span class="co0"># setup aplications path, be careful about not use $ORIGINALPATH.</span>
    <span class="co0">#</span>
    <span class="co0"># I use a path structure like that:</span>
    <span class="co0"># ~/.py/</span>
    <span class="co0"># |-- 2.4</span>
    <span class="co0"># |-- 2.5</span>
    <span class="co0"># `-- 2.6</span>
    <span class="kw3">export</span> <span class="re2">PATH</span>=<span class="st0">&quot;<span class="es3">${HOME}</span>/.py/<span class="es3">${PV}</span>/bin/:<span class="es3">${ORIGINALPATH}</span>&quot;</span>
    <span class="kw3">echo</span> <span class="re1">$PATH</span>
    <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;<span class="es1">\n</span>:: New PYTHON PATH&quot;</span>
    <span class="co0"># setup new python path, don't need to add system wide path, just our custom paths</span>
    <span class="kw3">export</span> <span class="re2">PYTHONPATH</span>=<span class="st0">&quot;<span class="es3">${HOME}</span>/.py/<span class="es3">${PV}</span>/lib/python<span class="es3">${PV}</span>/site-packages/&quot;</span>
    <span class="co0"># print more some info</span>
    python<span class="re1">$PV</span> <span class="re5">-c</span> <span class="st0">&quot;import sys;print sys.path&quot;</span>
    <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;<span class="es1">\n</span>:: Django version &amp;amp; file&quot;</span>
    python<span class="re1">$PV</span> <span class="re5">-c</span> <span class="st0">&quot;import django;print 'version %s ... file %s' % (django.get_version(),django.__file__);&quot;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Agora crie uma estrutura de diretórios com o comando:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">$ <span class="kw2">mkdir</span> <span class="re5">-pv</span> ~<span class="sy0">/</span>.py<span class="sy0">/</span><span class="br0">&#123;</span><span class="nu0">2.4</span>,<span class="nu0">2.5</span>,<span class="nu0">2.6</span><span class="br0">&#125;</span></pre></div></div>

<p>E cada vez que for usar uma versão diferente do python, carregue com:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">$ loadpyenv VERSÃO</pre></div></div>

<p>Onde VERSÃO é a versão escolhida do python.</p>
<h3>Várias versões do Python no <a href="http://www.gentoo.org">Gentoo</a></h3>
<p>O <a href="http://www.gentoo.org">Gentoo Linux</a>, minha distro do dia a dia, me dá um bom bonus quanto a múltiplas versões do python, configure no /etc/make.conf a seguinte linha:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;"><span class="re2">USE_PYTHON</span>=<span class="st0">&quot;2.4 2.5 2.6&quot;</span></pre></div></div>

<p>Instale os pythons nas versões escolhidas e execute o seguinte comando para re-compilar seus pacotes:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;">emerge $<span class="br0">&#40;</span>eix <span class="re5">-I</span> dev-python<span class="sy0">/*</span> <span class="sy0">|</span> <span class="kw2">grep</span> <span class="st0">&quot;\[I\]&quot;</span> <span class="sy0">|</span> <span class="kw2">cut</span> <span class="re5">-d</span><span class="st_h">' '</span> -f2<span class="br0">&#41;</span></pre></div></div>

<p><em>O <strong>eix</strong> é uma aplicação de indexação do portage, muito comum nas máquinas Gentoo.</em></p>
<p>Cada pacote python é recompilado para as 3 versões (no caso), mas tive problemas em compilar alguns pacotes para a 2.4, fiquem avisados <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bom, é isso, até mais!</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/-XNGB1xzoko" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/setting-up-multiple-python-envrionments/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/setting-up-multiple-python-envrionments</feedburner:origLink></item>
		<item>
		<title>Compilando fácil com Debian/Ubuntu</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/uiliXWQQn8s/compilando-facil-com-debianubuntu</link>
		<comments>http://chronosbox.org/blog/compilando-facil-com-debianubuntu#comments</comments>
		<pubDate>Sun, 03 Jan 2010 21:28:48 +0000</pubDate>
		<dc:creator>Handrus Nogueira</dc:creator>
				<category><![CDATA[Debian/Ubuntu]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Servidores]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=255</guid>
		<description><![CDATA[Como usuário do bom e velho gentoo, sempre senti falta da possibilidade de compilar softwares para ganhar uma certa performance. Principalmente em se tratando e softwares de uso em servidor, como Java, PHP, apache, mysql e porstgres. Nos meus testes sempre senti diferença entre as versões pré-compiladas e compilada in loco.
No Debian/Ubuntu a descoberta do [...]]]></description>
			<content:encoded><![CDATA[<p>Como usuário do bom e velho gentoo, sempre senti falta da possibilidade de compilar softwares para ganhar uma certa performance. Principalmente em se tratando e softwares de uso em servidor, como Java, PHP, apache, mysql e porstgres. Nos meus testes sempre senti diferença entre as versões pré-compiladas e compilada in loco.<br />
No Debian/Ubuntu a descoberta do apt-build me ajudou a contornar o problema com a mesma classe e <strong>quase</strong> a mesma eficiência que o portage.</p>
<p>Vamos ao passo-a-passo:</p>
<p>Para instalar o apt-build:<br />
<code>sudo apt-get install apt-build auto-apt</code></p>
<p>Configure para sua máquina:<br />
<code>dpkg-reconfigure apt-build</code><br />
Escolha sua arquitetura de processador e o nível de otimização, o indicado é o médio.<br />
As opções ficam salvas no arquivo <strong>/etc/apt/apt-build.conf</strong> ; Vamos apenas ajustar o número de processadores na ultima linha do arquivo altere-o para<br />
<code>make_options = " -j4"</code><br />
onde o número é igual ao número de &#8220;cores&#8221; + 1. Portanto um quadcore seria &#8220;-j5&#8243;.</p>
<p>Para evitar que os pacotes compilados sejam atualizados pelos pacotes oficiais vamos editar o arquivo <strong>/etc/apt/preferences</strong> adicionando:<br />
<code>Package: *<br />
Pin: release o=apt-build<br />
Pin-Priority: 990</code></p>
<p>Não se esqueça de adicionar os repositórios de código fonte (deb-src) e pronto!<br />
Agora ao invés do tradicional apt-get install
<pacote> utilize <code>apt-build install
<pacote></code></p>
<p>Exemplo: sudo apt-build install xchat emesene</p>
<p>Tutorial rápido sobre apt-build:</p>
<p><strong>apt-build install &#8211;reinstall
<pack></strong> para reinstalar<br />
<strong>apt-build upgrade</strong> Upgrade nos softwares instalados<br />
<strong>apt-build world</strong> Recompila todo o sistema<br />
<strong>apt-build remove programa</strong> Remove o programa<br />
<strong>apt-build clean-build</strong> Remove pacotes compilados<br />
<strong>apt-build clean-sources</strong> Remove os códigos fonte baixados.</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/uiliXWQQn8s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/compilando-facil-com-debianubuntu/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/compilando-facil-com-debianubuntu</feedburner:origLink></item>
		<item>
		<title>Manipulando erros Http 403 (permissão negada) no Django</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/dHupWDpSIFE/manipulando-erros-http-403-permissao-negada-no-django</link>
		<comments>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django#comments</comments>
		<pubDate>Tue, 24 Nov 2009 20:35:59 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Apps e extensões]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[403]]></category>
		<category><![CDATA[denied]]></category>
		<category><![CDATA[forbidden]]></category>
		<category><![CDATA[Http403]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[negado]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=240</guid>
		<description><![CDATA[Neste post, apresento um novo Middleware, concebido para tratar erros 403 (Http Forbidden, permissão negada) como trabalhamos com os erros 404 no Django.]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Recentemente, precisei usar o módulo <a href="http://docs.djangoproject.com/en/dev/topics/auth/#permissions">Auth do Django e suas permissões</a>. É bastante interessante como você pode definir permissões por módulo e usar nas views, templates, etc.</p>
<p>Nosso código de hoje vem da necessidade de trabalhar facilmente com <a href="http://en.wikipedia.org/wiki/HTTP_403">permissões negadas</a>, onde o Django fornece apenas um <a href="http://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses">HttpResponseForbidden</a>, o que não é exatamente interessante de manipular, pois o ideal seria algo como a manipulação de erros 404.</p>
<p>Com essa necessidade desenvolvi um <a href="http://docs.djangoproject.com/en/dev/topics/http/middleware/">Middleware</a> que intercepta exceções <a href="http://en.wikipedia.org/wiki/HTTP_403">Http403</a> (vem junto com o pacote), e retorna uma das seguintes opções, na ordem de prioridade:</p>
<ol>
<li>Uma view customizada, configurada usando handler403 no seu urls.py</li>
<li>Renderiza o template 403.html</li>
<li>Renderiza um template Hardcoded</li>
</ol>
<p>Para usar o Middleware, siga os procedimentos:</p>
<ol>
<li>Baixe o projeto no fim deste post, vamos usa-lo de exemplo, ele se chama http403project.</li>
<li>Descompacte e copie o arquivo http.py para algum lugar do seu projeto, no http403project ele fica na raiz.</li>
<li>Adicione o middleware ao settings.py:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;">MIDDLEWARE_CLASSES = <span class="br0">&#40;</span>
      <span class="co1"># ...</span>
      <span class="st0">'http403project.http.Http403Middleware'</span>,
<span class="br0">&#41;</span></pre></div></div>

</li>
<li>De raise na view, ex:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span class="kw1">from</span> http <span class="kw1">import</span> Http403
<span class="kw1">def</span> Http403View<span class="br0">&#40;</span>request<span class="br0">&#41;</span>:
  <span class="kw1">raise</span> Http403<span class="br0">&#40;</span>u<span class="st0">&quot;This is custom message for permission denied.&quot;</span><span class="br0">&#41;</span></pre></div></div>

</li>
<li>Configure sua view customizada ou template se desejar. Seu template deve ter o nome de 403.html, sua view recebe os argumentos request e exception, o argumento exception contem a mensagem enviada pelo usuário <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . No projeto exemplo ele está renderizando o template 403.html, mas existe uma view de exemplo bastante simples no arquivo urls.py
</li>
</ol>
<p><strong>Projeto:</strong> <a href="http://chronosbox.org/blog/django-projects/http403project.tgz">http403project.tgz</a></p>
<p>Ok, é isto, super simples, por hoje é só <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , divirtam-se!</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/dHupWDpSIFE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django</feedburner:origLink></item>
		<item>
		<title>Pensamento rápido – “ilike” SQL</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/55lpm5TuZVA/pensamento-rapido-ilike-sql</link>
		<comments>http://chronosbox.org/blog/pensamento-rapido-ilike-sql#comments</comments>
		<pubDate>Fri, 04 Sep 2009 15:18:31 +0000</pubDate>
		<dc:creator>Handrus Nogueira</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Multi Database]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=237</guid>
		<description><![CDATA[Hoje vi um post num dos blogs que acompanho, onde um camarada disse ter conseguido 1000% de melhora na performance de uma aplicação trocando um:

SELECT * FROM TABLE WHERE fieldname ILIKE 'abc%';

Para

SELECT * FROM TABLE WHERE lower&#40;fieldname&#41; LIKE 'abc%';

(diferença de ilike para lower&#8230; like)
Eu achei tosco (hehehe), óbviamente que esse ganho absurdo só pode ter [...]]]></description>
			<content:encoded><![CDATA[<p>Hoje vi um post num dos blogs que acompanho, onde um camarada disse ter conseguido 1000% de melhora na performance de uma aplicação trocando um:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;color: #FCFFBA;"><span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> <span class="kw1">TABLE</span> <span class="kw1">WHERE</span> fieldname ILIKE <span class="st0">'abc%'</span>;</pre></div></div>

<p>Para</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;color: #FCFFBA;"><span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> <span class="kw1">TABLE</span> <span class="kw1">WHERE</span> lower<span class="br0">&#40;</span>fieldname<span class="br0">&#41;</span> <span class="kw1">LIKE</span> <span class="st0">'abc%'</span>;</pre></div></div>

<p>(diferença de ilike para lower&#8230; like)<br />
Eu achei tosco (hehehe), óbviamente que esse ganho absurdo só pode ter ocorrido numa massa gigantesca de dados e provavelmente num campo sem índice.<br />
Mas a minha dica é outra:<br />
Além do ganho em performance o &#8220;ilike&#8221; não é suportado no mysql e sqlite.Portanto seu uso é extremamente desaconselhável, principalmente se você estiver trabalhando com Django, Rails ou qualquer aplicação que forneça um layer multi-db.<br />
Claro que nos frameworks citados acima o único jeito de fazer isso é forçar o uso de &#8220;ilike&#8221;, suas ORMs conseguem lidar com situações assim muito bem.</p>
<p><strong>Conclusão</strong><br />
Evite  &#8220;ilike&#8221; em queries de sql, use o  &#8220;lower()&#8230; like&#8221; ou &#8220;upper&#8230; like&#8221;; E se lembre de mudar sua variável para upper/lower!</p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/55lpm5TuZVA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/pensamento-rapido-ilike-sql/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/pensamento-rapido-ilike-sql</feedburner:origLink></item>
		<item>
		<title>Atualize o hosts.deny para bloquear tentativas de brute force</title>
		<link>http://feedproxy.google.com/~r/chronosbox/~3/5FtNYKvXrU4/update-hosts-deny-script</link>
		<comments>http://chronosbox.org/blog/update-hosts-deny-script#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:14:22 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Servidores]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[brute force]]></category>
		<category><![CDATA[hosts.deny]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=232</guid>
		<description><![CDATA[Ai embaixo um simples script para você bloquear hosts tentando brute force no seu SSH, muitas das vezes pode sanar o problema de ter uma porta diferente pro ssh  
O script varre o /var/log/messages para detectar tentativas de invasão, pega os hosts, e adiciona no /etc/hosts.deny
Código:

#!/bin/bash&#60;/code&#62;
&#160;
cp /etc/hosts.deny /var/tmp/hosts.deny
&#160;
# Jun  8 00:39:43 mintaka sshd[23332]: [...]]]></description>
			<content:encoded><![CDATA[<p>Ai embaixo um simples script para você bloquear hosts tentando brute force no seu SSH, muitas das vezes pode sanar o problema de ter uma porta diferente pro ssh <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>O script varre o /var/log/messages para detectar tentativas de invasão, pega os hosts, e adiciona no /etc/hosts.deny</p>
<p>Código:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: #FCFFBA;"><span class="co0">#!/bin/bash&lt;/code&gt;</span>
&nbsp;
<span class="kw2">cp</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny <span class="sy0">/</span>var<span class="sy0">/</span>tmp<span class="sy0">/</span>hosts.deny
&nbsp;
<span class="co0"># Jun  8 00:39:43 mintaka sshd[23332]: User root from 222.77.183.51 not allowed because not listed in AllowUsers</span>
<span class="kw2">egrep</span> <span class="st0">&quot;<span class="es4">$(date +%b)</span> (<span class="es4">$(date +%d)</span>|<span class="es4">$(date +%e)</span>).*User .* from [a-z0-9\.]* not allowed because not listed in AllowUsers&quot;</span> <span class="sy0">/</span>var<span class="sy0">/</span>log<span class="sy0">/</span>messages <span class="sy0">|</span> <span class="kw2">sed</span> <span class="re5">-e</span> <span class="st_h">'s/.* from \([a-z0-9\.]*\) .*/\1/'</span> <span class="sy0">|</span> <span class="kw2">sort</span> <span class="sy0">|</span> <span class="kw2">uniq</span> <span class="sy0">|</span> <span class="kw2">sed</span> <span class="re5">-e</span> <span class="st_h">'s/^/ALL:/'</span> <span class="sy0">&amp;</span>gt; <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny ;
<span class="co0">#Jun  8 11:54:33 mintaka sshd[31221]: Invalid user bob from 62.204.145.224</span>
<span class="kw2">egrep</span> <span class="st0">&quot;<span class="es4">$(date +%b)</span> (<span class="es4">$(date +%d)</span>|<span class="es4">$(date +%e)</span>).*Invalid user .* from [a-z0-9\.]*$&quot;</span> <span class="sy0">/</span>var<span class="sy0">/</span>log<span class="sy0">/</span>messages <span class="sy0">|</span> <span class="kw2">sed</span> <span class="re5">-e</span> <span class="st_h">'s/.*Invalid user .* from//'</span> <span class="sy0">|</span> <span class="kw2">sort</span> <span class="sy0">|</span> <span class="kw2">uniq</span> <span class="sy0">|</span> <span class="kw2">sed</span> <span class="re5">-e</span> <span class="st_h">'s/^/ALL:/'</span> <span class="sy0">&amp;</span>gt;<span class="sy0">&amp;</span>gt; <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny ;
&nbsp;
<span class="kw2">diff</span> <span class="re5">-u</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny <span class="sy0">/</span>var<span class="sy0">/</span>tmp<span class="sy0">/</span>hosts.deny <span class="sy0">&amp;</span>amp;<span class="sy0">&amp;</span>gt;<span class="sy0">/</span>dev<span class="sy0">/</span>null <span class="sy0">||</span> <span class="br0">&#40;</span><span class="kw3">echo</span> <span class="st0">&quot;** hosts.deny updated **&quot;</span> ; <span class="kw2">cat</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny<span class="br0">&#41;</span></pre></div></div>

<p>Script funcionando:<br />
<code><br />
Sep  2 16:55:02 mintaka -- MARK --<br />
Sep  2 13:58:10 mintaka sshd[20790]: Did not receive identification string from 189.2.118.72<br />
Sep  2 13:58:34 mintaka sshd[20795]: Invalid user suporte from 189.2.118.72<br />
# Tentativa de brute force<br />
Sep  2 13:58:41 mintaka sshd[20798]: Invalid user suporte from 189.2.118.72<br />
Sep  2 13:58:43 mintaka sshd[20800]: Invalid user suporte from 189.2.118.72<br />
Sep  2 13:58:46 mintaka sshd[20802]: Invalid user suporte from 189.2.118.72<br />
Sep  2 13:58:49 mintaka sshd[20804]: Invalid user suporte from 189.2.118.72<br />
Sep  2 13:58:51 mintaka sshd[20806]: Invalid user suporte from 189.2.118.72<br />
Sep  2 13:59:24 mintaka sshd[20817]: Did not receive identification string from 189.2.118.72<br />
# Script roda<br />
** hosts.deny updated **<br />
ALL:74.221.239.100<br />
ALL: 189.2.118.72<br />
ALL: 200.27.79.101<br />
ALL: 74.221.239.100<br />
# E os hosts agora estão bloqueados<br />
Sep  2 14:00:09 mintaka sshd[20826]: Invalid user teste2008 from 189.2.118.72<br />
Sep  2 14:00:10 mintaka sshd[20864]: refused connect from 189.2.118.72 (189.2.118.72)<br />
</code></p>
<p>Eu rodo em minha máquina a cada 2 minutos <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/chronosbox/~4/5FtNYKvXrU4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/update-hosts-deny-script/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://chronosbox.org/blog/update-hosts-deny-script</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 1.162 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-01 23:24:57 --><!-- Compression = gzip -->
