<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>coisas lunix</title>
	<atom:link href="http://fiorix.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fiorix.wordpress.com</link>
	<description>oops! kernel panic!</description>
	<lastBuildDate>Wed, 02 Dec 2009 02:04:35 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='fiorix.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/aecb7c0f2a82f625338a31ff23f30860?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>coisas lunix</title>
		<link>http://fiorix.wordpress.com</link>
	</image>
			<item>
		<title>imac, kernel panic!</title>
		<link>http://fiorix.wordpress.com/2009/12/01/imac-kernel-panic/</link>
		<comments>http://fiorix.wordpress.com/2009/12/01/imac-kernel-panic/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 02:04:35 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=387</guid>
		<description><![CDATA[Jogando Urban Terror, as vezes trava.

A foto amarela e sem foco é cortesia do iPhone.

cash:~ lame$ uname -a
Darwin cash.local 10.2.0 Darwin Kernel Version 10.2.0: Tue Nov  3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386 i386
cash:~ lame$ sudo sysctl machdep.cpu
machdep.cpu.vendor: GenuineIntel
machdep.cpu.brand_string: Intel(R) Core(TM)2 Duo CPU     E8335  @ 2.66GHz
machdep.cpu.features:  FPU VME DE PSE TSC MSR PAE MCE CX8 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=387&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Jogando <a href="http://www.urbanterror.net/">Urban Terror</a>, as vezes trava.</p>
<p style="text-align:left;"><a href="http://fiorix.files.wordpress.com/2009/12/img_00951.jpg"><img class="aligncenter size-full wp-image-392" title="mac kernel panic 1" src="http://fiorix.files.wordpress.com/2009/12/img_00951.jpg?w=509&#038;h=425" alt="" width="509" height="425" /></a><a href="http://fiorix.files.wordpress.com/2009/12/img_00941.jpg"><img class="aligncenter size-full wp-image-393" title="mac kernel panic 2" src="http://fiorix.files.wordpress.com/2009/12/img_00941.jpg?w=509&#038;h=382" alt="" width="509" height="382" /></a></p>
<p style="text-align:left;">A foto amarela e sem foco é cortesia do iPhone.</p>
<p style="text-align:left;">
<div id="_mcePaste">cash:~ lame$ uname -a</div>
<div id="_mcePaste">Darwin cash.local 10.2.0 Darwin Kernel Version 10.2.0: Tue Nov  3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386 i386</div>
<p>cash:~ lame$ sudo sysctl machdep.cpu<br />
machdep.cpu.vendor: GenuineIntel<br />
machdep.cpu.brand_string: Intel(R) Core(TM)2 Duo CPU     E8335  @ 2.66GHz<br />
machdep.cpu.features:  FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM SSE3 MON DSCPL VMX EST TM2 SSSE3 CX16 TPR PDCM SSE4.1</p>
Posted in misc  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=387&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/12/01/imac-kernel-panic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/12/img_00951.jpg" medium="image">
			<media:title type="html">mac kernel panic 1</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/12/img_00941.jpg" medium="image">
			<media:title type="html">mac kernel panic 2</media:title>
		</media:content>
	</item>
		<item>
		<title>sobre o chrome os</title>
		<link>http://fiorix.wordpress.com/2009/11/24/sobre-o-chrome-os/</link>
		<comments>http://fiorix.wordpress.com/2009/11/24/sobre-o-chrome-os/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:23:44 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[rede]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[chromium]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[halt]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[operating system]]></category>
		<category><![CDATA[reboot]]></category>
		<category><![CDATA[reiniciar]]></category>
		<category><![CDATA[senha]]></category>
		<category><![CDATA[sistema operacional]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[usuário]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=382</guid>
		<description><![CDATA[Depois de todo o alvoroço sobre o Chrome OS, finalmente baixei e pude conferir. Usando este link, tive que criar uma conta e após confirmar o cadastro pelo email, pude baixar uma imagem de VMware e criei a máquina virtual usando o Fusion.
O boot é realmente rápido, e logo aparece a primeira tela: login. Procurei [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=382&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://fiorix.files.wordpress.com/2009/11/google-chrome-logo.jpg"><img class="alignleft size-thumbnail wp-image-383" title="google-chrome-logo" src="http://fiorix.files.wordpress.com/2009/11/google-chrome-logo.jpg?w=150&#038;h=107" alt="" width="150" height="107" /></a>Depois de todo o alvoroço sobre o <a href="http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html">Chrome OS,</a> finalmente baixei e pude conferir. Usando <a href="http://gdgt.com/google/chrome-os/download/">este link</a>, tive que criar uma conta e após confirmar o cadastro pelo email, pude baixar uma imagem de <a href="http://www.vmware.com/">VMware</a> e criei a máquina virtual usando o <a href="http://www.vmware.com/products/fusion/">Fusion</a>.</p>
<p>O boot é realmente rápido, e logo aparece a primeira tela: login. Procurei um pouco e descobri que o usuário e senha é o mesmo do <a href="https://www.google.com/accounts/">Google Accounts</a>. Porém, não funcionou pra mim, e tudo que consegui foi um erro informando: <em>Network not connected and offline login fail</em>.</p>
<p>Usando a rede da máquina virtual como NAT ou Bridge, não fez com que o login funcionasse. Procurando mais um pouco, encontrei a solução: usuário <em>chronos</em>, sem senha.</p>
<p>Usei um pouco, procurei algo sobre configuração de resolução, e nada. Também, não há botão algum para desligar ou reiniciar o sistema operacional. Logo, procurando um pouco mais, descobri como abrir um terminal: Ctrl-Alt-T. É um linux, bem simples e pequeno, com a interface baseada em GTK, e o <a href="http://code.google.com/chromium/">Chromium</a>.</p>
<p>Nada especial, mas essa simplicidade é bem interessante.</p>
<p><a href="http://fiorix.files.wordpress.com/2009/11/screen-shot-2009-11-24-at-3-14-07-pm.png"><img class="aligncenter size-medium wp-image-384" title="ChronOS main window" src="http://fiorix.files.wordpress.com/2009/11/screen-shot-2009-11-24-at-3-14-07-pm.png?w=300&#038;h=171" alt="" width="300" height="171" /></a></p>
<p>Para virar root, pode-se usar o sudo, e a senha é <em>chronos</em>. Não tem muito o que fazer no terminal, apenas um <em>sudo reboot</em> ou <em>sudo halt</em>.</p>
<p>Curti.</p>
<p>Pra quem ainda não baixou o <a href="http://www.chromium.org/">Chromium</a>, aqui tem todos <em>snapshots</em> para os sistemas operacionais suportados: <a href="http://build.chromium.org/buildbot/snapshots/">http://build.chromium.org/buildbot/snapshots/</a></p>
Posted in rede, sistema Tagged: chrome, chromium, console, halt, login, operating system, reboot, reiniciar, senha, sistema operacional, terminal, usuário <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/382/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/382/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/382/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/382/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/382/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/382/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/382/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/382/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/382/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/382/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=382&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/11/24/sobre-o-chrome-os/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/11/google-chrome-logo.jpg?w=150" medium="image">
			<media:title type="html">google-chrome-logo</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/11/screen-shot-2009-11-24-at-3-14-07-pm.png?w=300" medium="image">
			<media:title type="html">ChronOS main window</media:title>
		</media:content>
	</item>
		<item>
		<title>mongodb e twisted</title>
		<link>http://fiorix.wordpress.com/2009/09/26/mongodb-e-twisted/</link>
		<comments>http://fiorix.wordpress.com/2009/09/26/mongodb-e-twisted/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 07:44:44 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[pymonga]]></category>
		<category><![CDATA[pymongo]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=377</guid>
		<description><![CDATA[Há algum tempo venho fazendo testes com o MongoDB pra casos específicos onde um RDBM tradicional como MySQL ou PostgreSQL não se encaixa muito bem.
Um dos casos onde um banco de dados baseado em objetos como o MongoDB se encaixa perfeitamente, é em um dos meus sistemas comerciais de telefonia, o Nuswit.
Lá, o usuário pode [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=377&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft" style="border-right:20px solid white;" title="Mongo Database" src="http://media.mongodb.org/logo-mongoDB.png" alt="" width="152" height="63" />Há algum tempo venho fazendo testes com o <a href="http://www.mongodb.org/">MongoDB</a> pra casos específicos onde um <a href="http://en.wikipedia.org/wiki/Relational_database_management_system">RDBM</a> tradicional como <a href="http://www.mysql.com/">MySQL</a> ou <a href="http://www.postgresql.org/">PostgreSQL</a> não se encaixa muito bem.</p>
<p>Um dos casos onde um banco de dados baseado em objetos como o MongoDB se encaixa perfeitamente, é em um dos meus sistemas comerciais de telefonia, o <a href="http://nuswit.com/">Nuswit</a>.</p>
<p>Lá, o usuário pode criar uma campanha de tele mensagem e colocar variáveis, que serão usadas para ligar para as pessoas e falar algumas coisas dinâmicas, <a href="http://www.loquendo.com/">sintetizando o texto em voz</a>. Hoje, cada vez que o usuário cria uma campanha, pode importar uma <a href="http://en.wikipedia.org/wiki/Microsoft_Excel_file_format#File_formats">planilha</a> ou arquivo <a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV</a>, e então o sistema uma cria nova tabela no <a href="http://www.sqlite.org/">Sqlite</a> com os campos que o usuário definiu na campanha, de acordo com essas tais variáveis.</p>
<p>Por isso, não é possível ter uma tabela estática, muito menos fazer relacionamentos pra usar a tabela no estilo chave=valor, pois essa mesma tabela é usada pros relatórios que o usuário baixa após o término da campanha.</p>
<p>Nesse caso, o MongoDB se encaixa perfeitamente. É muito mais simples criar uma <a href="http://www.mongodb.org/display/DOCS/Collections">coleção de dados</a> com o mesmo nome da campanha, e importar <a href="http://www.mongodb.org/display/DOCS/BSON">documentos tipo JSON</a> (nome=x, telefone=y, cpf=z) do que criar uma nova tabela com esses campos.</p>
<p>Além do mais, a <a href="http://github.com/mongodb/mongo-python-driver/blob/master/examples/simple_demo.py">API do pymongo</a> é muito mais decente do que qualquer coisa parecida com <a href="http://en.wikipedia.org/wiki/SQL">SQL</a>, pois os <em>databases</em> e <em>collections </em>são objetos do Python.</p>
<p>O único problema com o <a href="http://github.com/mongodb/mongo-python-driver">pymongo</a> é que ele foi feito pra controlar e manter um <em>pool</em> de conexões com o banco, totalmente síncrono. Pra usar o pymongo em servidores como os que tenho feito ultimamente, assíncronos, baseados em <a href="http://twistedmatrix.com/">Twisted</a>, é necessário mandar todas as chamadas do banco pra um thread (usando <a href="http://python.net/crew/mwh/apidocs/twisted.internet.base.ReactorBase.html#callInThread">callInThread</a> ou <a href="http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.threads.deferToThread.html">deferToThread</a>).</p>
<p>Pra solucionar esse problema, passei a frequentar o <a href="http://freenode.net/">#mongodb na freenode</a>, e em contato com o <a href="http://github.com/mdirolf">autor do pymongo</a>, acabei criando uma versão assíncrona do driver, baseado em Twisted, que mantém o mesmo estilo da API original.</p>
<p>Agora, a integração entre Twisted e MongoDB está muito mais decente, usando <span style="font-size:x-large;"><a href="http://github.com/fiorix/mongo-async-python-driver">pymonga</a></span>.</p>
Posted in programação, python, sql Tagged: mongo, mongodb, pymonga, pymongo, python, twisted <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/377/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/377/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/377/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/377/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/377/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/377/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/377/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/377/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/377/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/377/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=377&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/09/26/mongodb-e-twisted/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://media.mongodb.org/logo-mongoDB.png" medium="image">
			<media:title type="html">Mongo Database</media:title>
		</media:content>
	</item>
		<item>
		<title>tornado</title>
		<link>http://fiorix.wordpress.com/2009/09/22/tornado/</link>
		<comments>http://fiorix.wordpress.com/2009/09/22/tornado/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 03:40:05 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[rede]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[tornado]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=375</guid>
		<description><![CDATA[Logo após o Facebook comprar o FriendFeed por meros U$50 milhões, não demorou pra começarem a publicar software gratuito.
O primeiro da fila foi o servidor e framework web usado pelo FriendFeed, chamado Tornado.
O FriendFeed é famoso por sua integração com Facebook, Twitter e Google. O que ninguém sabia, é que boa parte dessa integração é [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=375&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft" style="border-right:20px solid white;" title="tornado web" src="http://www.tornadoweb.org/static/tornado.png" alt="" width="140" height="35" />Logo após o <a href="http://www.facebook.com/">Facebook</a> comprar o <a href="http://friendfeed.com/">FriendFeed</a> por meros <a href="http://www.techcrunch.com/2009/08/10/pics-the-facebookfriendfeed-deal-signed-under-the-cover-of-night/">U$50 milhões</a>, não demorou pra começarem a publicar software gratuito.</p>
<p>O primeiro da fila foi o servidor e framework web usado pelo FriendFeed, chamado <a href="http://www.tornadoweb.org/">Tornado</a>.</p>
<p>O FriendFeed é famoso por sua integração com Facebook, <a href="http://twitter.com/">Twitter</a> e <a href="http://www.google.com/reader/">Google</a>. O que ninguém sabia, é que boa parte dessa integração é feita direto no servidor e framework web. Ainda, um dos recursos mais legais é o stream de dados do servidor assíncrono, também conhecido como <a href="http://en.wikipedia.org/wiki/Comet_%28programming%29">comet</a>, que permite <a href="http://en.wikipedia.org/wiki/Push_technology#Long_polling">long polling</a> consumindo o mínimo de recursos.</p>
<p>É interessante como nos últimos anos essas tecnologias avançam no ambiente web. Na década de 90, a coisa mais moderna era desenvolver um <a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a> isolado, em <a href="http://www.perl.org/">Perl</a>, que era executado pelo <a href="http://apache.org/">Apache</a>, que por sua vez distribuía as requisições para um de seus <a href="http://httpd.apache.org/docs/2.0/mod/prefork.html">processos usando um pool</a>.</p>
<p>Depois, o procedimento de executar um programa externo foi se tornando um pouco ultrapassado, e o CGI foi parar <em>dentro </em>do Apache, com nomes como <a href="http://www.php.net/">PHP</a> e <a href="http://www.adobe.com/products/coldfusion/">Coldfusion</a>. Nessa época, enfiaram até <a href="http://www.java.com/">Java</a> dentro do Apache, colocaram o nome de <a href="http://tomcat.apache.org/">Tomcat</a> nele, e os CGIs passaram a se chamar <a href="http://java.sun.com/products/servlet/">Servlets</a>.</p>
<p>Anos depois, fizeram o mesmo com o <a href="http://python.org/">Python</a>, e colocaram lá dentro do Apache o <a href="http://www.modpython.org/">mod_python</a>. No caso específico do Python, foram ainda mais longe: criaram um protocolo padrão para aplicativos web se comunicar com servidores web, chamado <a href="http://wsgi.org/wsgi/">WSGI</a>, e também foi parar dentro do Apache com nome de <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a>.</p>
<p>Me lembro de cada uma dessas etapas, das dificuldades e dos benefícios de cada uma dessas adaptações. Programei em todas essas linguagens, nos últimos 15 anos. Meia vida.</p>
<p>Mais recentemente, antigas tecnologias como o <a href="http://www.fastcgi.com/">FastCGI</a> reabriram o caminho para aplicativos web 2.0. Servidores mais leves que o Apache, como o <a href="http://www.lighttpd.net/">lighttpd</a> e <a href="http://nginx.net/">nginx</a> começaram a ganhar muito espaço em sites com <a href="http://highscalability.com/">grande volume de acesso</a>, por consumirem menos recursos trabalhando de forma assíncrona.</p>
<p>Mas antes do Apache, já existiam diversos serviços de rede que usavam o conceito de conexão assíncrona. Os <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat">servidores de irc</a>, por exemplo, já formavam redes com centenas, e depois milhares, e depois centenas de milhares de usuários simultâneos, no bate-papo infinito.</p>
<p>Quanto mais o ambiente web cresce, mais pessoas acessam sites. Esses sites precisam de mais servidores, e esses servidores precisam de mais recursos. Usar conexões assíncronas permite <a href="http://www.kegel.com/c10k.html">aceitar mais pessoas simultâneas, consumindo menos recursos</a> que tecnologias baseadas em <a href="http://en.wikipedia.org/wiki/Thread_%28computer_science%29">thread</a>, por exemplo. É uma espécie de redução de custo com otimização de recurso, ao mesmo tempo. Para programadores, é um conceito bem diferente do tradicional, especialmente para web, e exige um pouco de cérebro para se adaptar.</p>
<p>Os sistemas operacionais já vêm evoluindo suas internas para aceitar mais e mais conexões simultâneas, consumindo menos e menos recursos. Nomes como epoll, kqueue e /dev/poll estão cada vez mais no dia-a-dia dos programadores. E facilitadores como a <a href="http://www.monkey.org/~provos/libevent/">libevent</a> também.</p>
<p>O resultado disso é que os novos frameworks para aplicativos web já possuem servidores web embutidos, como é o caso do Tornado, <a href="twistedmatrix.com/trac/wiki/TwistedWeb">Twisted Web</a>, <a href="http://merbivore.com/">Merb</a>, etc etc&#8230; Na frente deles, lighttpd e nginx fazem a distribuição de carga, e milhares de conexões web simultâneas, em um único computador físico, começa a se tornar realidade.</p>
Posted in rede, sistema Tagged: asynchronous, tornado, web <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/375/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/375/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/375/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/375/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/375/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/375/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/375/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/375/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/375/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/375/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=375&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/09/22/tornado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://www.tornadoweb.org/static/tornado.png" medium="image">
			<media:title type="html">tornado web</media:title>
		</media:content>
	</item>
		<item>
		<title>atualização pro snow leopard</title>
		<link>http://fiorix.wordpress.com/2009/09/16/atualizacao-pro-snow-leopard/</link>
		<comments>http://fiorix.wordpress.com/2009/09/16/atualizacao-pro-snow-leopard/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 04:43:23 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[sistema]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=372</guid>
		<description><![CDATA[Coisas que você precisa saber antes de atualizar pro Snow Leopard, Mac OS X 10.6:

Logo após a atualização, é comum &#8220;quebrar&#8221; o sistema de autenticação. Aquela janela que costuma aparecer solicitando seu usuário e senha para desbloquear as propriedades de configuração, e também pra atualizar o Mac OS. Comigo aconteceu nos dois Macs, e a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=372&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Coisas que você precisa saber antes de atualizar pro <a href="http://www.apple.com/macosx/">Snow Leopard</a>, Mac OS X 10.6:</p>
<ol>
<li>Logo após a atualização, é comum &#8220;quebrar&#8221; o sistema de autenticação. Aquela janela que costuma aparecer solicitando seu usuário e senha para desbloquear as propriedades de configuração, e também pra atualizar o Mac OS. Comigo aconteceu nos dois Macs, e a solução é remover no diretório do seu usuário, o diretório Library/Preferences/ByHost</li>
<li>O <a href="http://developer.apple.com/mac/">Xcode</a> continua, mas o gcc na linha de comando não. Logo após atualizar pro Snow Leopard, terá que reinstalar o Xcode. Pode apagar manualmente o /Developer e /Library/Developer, pois não servem pra mais nada. A versão mais atual é o 3.2</li>
<li>De fato, <a href="http://www.macports.org/">MacPorts</a> também vai pro espaço. Tudo que você já tem no port continua funcionando, menos o comando port. É necessário baixar a versão pro Snow Leopard, e depois de instalar, atualizar tudo que você tem: sudo port -v selfupdate; sudo port -v upgrade &#8211;force installed</li>
<li>Programas como o <a href="http://www.ambrosiasw.com/utilities/snapzprox/">Snapz Pro</a> não reconhecem mais sua licença, e a única maneira de resolver é mandando e-mail pro <a href="mailto:help@ambrosiasw.com">help@ambrosiasw.com</a>. Tentei ir no site, na sessão <a href="http://www.ambrosiasw.com/account/">my account</a>, mas também estava quebrado &#8211; dei azar!</li>
<li><a href="http://www.vmware.com/products/fusion/">VMware Fusion</a> e afins, só funcionam com kernel 32 bits. <a href="http://blogs.vmware.com/teamfusion/2009/08/vmware-fusion-2-and-max-os-x-snow-leopard-even-better.html">Já existe um beta</a> pro kernel 64 bits, mas não funciona direito.</li>
</ol>
<p>Por enquanto, foi isso que rolou por aqui. Assim que encontrar mais alguma zica, publico aqui.</p>
Posted in sistema  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/372/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/372/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/372/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/372/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/372/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/372/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/372/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/372/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/372/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/372/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=372&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/09/16/atualizacao-pro-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>
	</item>
		<item>
		<title>mais sobre crawlers e spiders</title>
		<link>http://fiorix.wordpress.com/2009/09/09/mais-sobre-crawlers-e-spiders/</link>
		<comments>http://fiorix.wordpress.com/2009/09/09/mais-sobre-crawlers-e-spiders/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 07:48:19 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rede]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[beautifulsoup]]></category>
		<category><![CDATA[cooperator]]></category>
		<category><![CDATA[crawler]]></category>
		<category><![CDATA[generators]]></category>
		<category><![CDATA[inlinecallbacks]]></category>
		<category><![CDATA[lxml]]></category>
		<category><![CDATA[mercadolivre]]></category>
		<category><![CDATA[spider]]></category>
		<category><![CDATA[task]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=365</guid>
		<description><![CDATA[No mês passado escrevi um artigo com um programa para capturar todos os items da primeira página de cada categoria do MercadoLivre.
Lá, lidava com alguns problemas como:

limite de concorrência no download das páginas
processamento de html em thread, síncrono
manter a maior parte do processo assíncrono, para ganhar tempo e CPU

Depois disso, precisei fazer umas alterações no [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=365&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft size-full wp-image-345" style="border:5px solid white;" title="logo_mercadolivre" src="http://fiorix.files.wordpress.com/2009/08/logo_mercadolivre.jpg?w=62&#038;h=62" alt="logo_mercadolivre" width="62" height="62" />No mês passado escrevi um <a href="http://fiorix.wordpress.com/2009/08/19/twisted-crawler-alvo-mercadolivre/">artigo com um programa para capturar todos os items da primeira página de cada categoria do MercadoLivre</a>.</p>
<p>Lá, lidava com alguns problemas como:</p>
<ul>
<li>limite de concorrência no download das páginas</li>
<li>processamento de html em thread, síncrono</li>
<li>manter a maior parte do processo assíncrono, para ganhar tempo e CPU</li>
</ul>
<p>Depois disso, precisei fazer umas alterações no código e acabei modificando um pouco programa, usando outras técnicas como:</p>
<ul>
<li><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.task.Cooperator.html">cooperação de tarefas para limitar a concorrência</a></li>
<li><a href="http://codespeak.net/lxml/">processamento de html inline, mais rápido</a> (pois usa backend em C)</li>
<li><a href="http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks">encadear algumas funções, executando inline</a></li>
</ul>
<p>Cada item desta lista corresponde aos itens da lista mais acima, respectivamente.</p>
<p>O esquema de cooperação do twisted é muito melhor que o <em>Controller</em> que havia criado anteriormente. Porém, muito mais complicado para jovens aprendizes. Recomendo <a href="http://jcalderone.livejournal.com/24285.html">este link</a> para mais detalhes.</p>
<p>Sobre o processamento do html, vale a pena <a href="http://codespeak.net/lxml/lxmlhtml.html">verificar o lxml</a>. Antes, havia usado <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>, que é muito bom, mas perde violentamente em desempenho e suporte a <a href="http://www.microsoft.com/FRONTPAGE/">broken-html</a>.</p>
<p>Por fim, o truque de usar <a href="http://blog.mekk.waw.pl/archives/14-Twisted-inlineCallbacks-and-deferredGenerator.html"><em>generators</em> para executar alguns callbacks inline</a> é incrível, e absurdamente prático em casos como esse, do programa abaixo.</p>
<p>O resultado é final é o mesmo, mas a melhoria em desempenho é absurda. Fiz alguns testes na minha máquina e obtive o seguinte:</p>
<ul>
<li>esta versão consome, em média, 20% menos de CPU</li>
<li>como não há necessidade de gravar os arquivos no disco, não consome disco</li>
<li>o processo todo ficou 657% mais rápido, <a href="http://www.youtube.com/watch?v=eKcHQPEYGcI">simplesmente</a></li>
<li>ainda, o código é muito menor +_+</li>
</ul>
<p>Veja ai:</p>
<pre class="brush: python;">
#!/usr/bin/env python
# coding: utf-8

from lxml import html
from twisted.web import client
from twisted.python import log
from twisted.internet import task, defer, reactor

class MercadoLivre:
    def __str__(self):
        return 'http://www.mercadolivre.com.br/jm/ml.allcategs.AllCategsServlet'

    def parse_categories(self, content):
        category = subcategory = ''
        doc = html.fromstring(content)
        for link in doc.iterlinks():
            el, attr, href, offset = link
            try: category = el.find_class('categ')[0].text_content()
            except: pass
            else: continue
            if category:
                try: subcategory = el.find_class('seglnk')[0].text_content()
                except: continue
                else: yield (href, category, subcategory)

    def parse_subcategory(self, content):
        doc = html.fromstring(content)
        for element in doc.find_class('col_titulo'):
            yield element[0].text_content()

class Engine:
    def finish(self, result):
        reactor.stop()

    @defer.inlineCallbacks
    def fetch_categories(self, link, parser):
        try:
            doc = yield client.getPage(link)
            defer.returnValue(parser(doc))
        except Exception, e:
            print e

    def fetch_subcategory(self, links, parser, limit):
        coop = task.Cooperator()
        work = (client.getPage(link[0]).addCallback(parser).addCallback(self.page_items, *link) for link in links)
        result = defer.DeferredList([coop.coiterate(work) for x in xrange(limit)])
        result.addCallback(self.finish)
        result.addErrback(log.err)

    def page_items(self, items, href, category, subcategory):
        print 'Categoria: %s / %s' % (category.encode('utf-8'), subcategory.encode('utf-8'))
        for item in items: print ' -&gt; %s' % item.encode('utf-8')
        print ''

def main(limit, *parsers):
    e = Engine()
    for parser in parsers:
        links = e.fetch_categories(str(parser), parser.parse_categories)
        links.addCallback(e.fetch_subcategory, parser.parse_subcategory, limit)

if __name__ == '__main__':
    reactor.callWhenRunning(main, 150, MercadoLivre())
    reactor.run()
</pre>
Posted in programação, python, rede, sistema Tagged: beautifulsoup, cooperator, crawler, generators, inlinecallbacks, lxml, mercadolivre, python, spider, task, twisted <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/365/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=365&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/09/09/mais-sobre-crawlers-e-spiders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/08/logo_mercadolivre.jpg" medium="image">
			<media:title type="html">logo_mercadolivre</media:title>
		</media:content>
	</item>
		<item>
		<title>novo serviço de geo localização</title>
		<link>http://fiorix.wordpress.com/2009/09/01/novo-servico-de-geo-localizacao/</link>
		<comments>http://fiorix.wordpress.com/2009/09/01/novo-servico-de-geo-localizacao/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 04:37:29 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[rede]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[free ip geolocation web service geoip gpl]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=359</guid>
		<description><![CDATA[Aos poucos, vou tirando meu serviço de Geo Localização do ar. Apesar de bastante acesso por dia no freegeoip.appspot.com, os problemas com o datastore do GAE me desanimam.
O serviço está no ar há cerca de 1 ano, e a média de acesso é de 10 e 15 requests por segundo. A recente redução das cotas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=359&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft size-thumbnail wp-image-361" style="margin-right:10px;" title="freegeoipnet" src="http://fiorix.files.wordpress.com/2009/09/freegeoipnet.png?w=150&#038;h=26" alt="freegeoipnet" width="150" height="26" />Aos poucos, vou tirando meu serviço de <a href="http://en.wikipedia.org/wiki/Geolocation">Geo Localização</a> do ar. Apesar de bastante acesso por dia no <a href="http://freegeoip.appspot.com">freegeoip.appspot.com</a>, os problemas com o <a href="http://code.google.com/appengine/docs/python/datastore/">datastore</a> do <a href="http://code.google.com/appengine/">GAE</a> me desanimam.</p>
<p>O serviço está no ar há cerca de 1 ano, e a média de acesso é de 10 e 15 requests por segundo. A recente <a href="http://blogoscoped.com/archive/2009-02-24-n67.html">redução das cotas</a> tiram o serviço do ar muitas vezes, e isso porque diminuí ao máximo o nível de processamento, e a maioria das buscas é feita em memória direto no <a href="http://code.google.com/appengine/docs/python/memcache/">memcache</a>.</p>
<p><img class="alignleft size-full wp-image-360" title="freegeoip-quotas" src="http://fiorix.files.wordpress.com/2009/09/freegeoip-quotas.png?w=510&#038;h=124" alt="freegeoip-quotas" width="510" height="124" /><br />
Apesar do sistema ainda funcionar, não tenho mais paciência pra atualizar os dados lá. O datastore não permite deletar os dados antigos de uma maneira simples, e por isso gasta muito processamento quando uso o <a href="http://code.google.com/appengine/docs/python/tools/uploadingdata.html">bulkloader</a>, ou mesmo a <a href="http://code.google.com/appengine/articles/remote_api.html">remote_api</a>.</p>
<p>Cansado de todos esses problemas, acabei pegando um <a href="http://en.wikipedia.org/wiki/Virtual_private_server">VPS</a> no <a href="http://www.slicehost.com/">slicehost.com</a> e fiz uma versão nova do sistema. Tornei o código fonte disponível pela <a href="http://www.gnu.org/licenses/gpl-2.0.html">GPL v2</a>, e daqui um tempo vou redirecionar o serviço do GAE pro slicehost.</p>
<p>Além de rodar mais rápido, é muito mais fácil pra atualizar o banco de dados de IPs, e tenho <a href="http://en.wikipedia.org/wiki/Unix_shell">shell</a> na máquina.</p>
<p>Se você costumava usar o serviço antigo, passe a usar o novo:</p>
<h1><a href="http://freegeoip.net">http://freegeoip.net</a></h1>
<p>Espero que em breve possa atualizar meu banco de dados usando a <a href="http://dev.w3.org/geo/api/spec-source.html">Geolocation API</a> que está sendo definida pelo <a href="http://www.w3.org/">W3C</a>.</p>
<p>Sobre o slicehost: é o melhor <a href="http://en.wikipedia.org/wiki/Web_hosting_service">serviço de hosting</a> que já encontrei, por um preço ótimo. O <a href="https://manage.slicehost.com/customers/new?referrer=587e3a4b99081782989884ea2fe74bf9">formulário de signup</a> é bem simples, e a configuração do ambiente é incrível. Ainda, permitem adicionar seus domínios direto no DNS deles, e apontar pras máquinas virtuais.</p>
Posted in rede, sistema Tagged: free ip geolocation web service geoip gpl <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/359/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=359&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/09/01/novo-servico-de-geo-localizacao/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/09/freegeoipnet.png?w=150" medium="image">
			<media:title type="html">freegeoipnet</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/09/freegeoip-quotas.png" medium="image">
			<media:title type="html">freegeoip-quotas</media:title>
		</media:content>
	</item>
		<item>
		<title>autenticação no google, pro appengine</title>
		<link>http://fiorix.wordpress.com/2009/08/20/autenticacao-no-google-pro-appengine/</link>
		<comments>http://fiorix.wordpress.com/2009/08/20/autenticacao-no-google-pro-appengine/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 22:05:47 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rede]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[autenticação]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google accounts]]></category>
		<category><![CDATA[redirecionamento]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[token]]></category>
		<category><![CDATA[urllib]]></category>
		<category><![CDATA[urllib2]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=350</guid>
		<description><![CDATA[Acabo de resolver um problema que vem me irritando muito nos últimos meses: sincronizar uma quande quantidade de dados com o appengine.
Depois de passar muita raiva com o bulkloader, que inevitavelmente acaba gerando esses Datastore Timeout, decidi fazer um outro esquema que funcionou muito melhor. Um dia coloco aqui, mas não agora.
O lance é que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=350&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft size-thumbnail wp-image-308" style="border-right:20px solid white;" title="Google AppEngine" src="http://fiorix.files.wordpress.com/2009/03/google_appengine-779483.png?w=89&#038;h=89" alt="Google AppEngine" width="89" height="89" />Acabo de resolver um problema que vem me irritando muito nos últimos meses: sincronizar uma quande quantidade de dados com o <a href="http://code.google.com/appengine/">appengine</a>.</p>
<p>Depois de passar muita raiva com o <a href="http://code.google.com/appengine/docs/python/tools/uploadingdata.html">bulkloader</a>, que inevitavelmente acaba gerando esses <a href="http://www.google.com/search?hl=en&amp;q=Datastore+Timeout">Datastore Timeout</a>, decidi fazer um outro esquema que funcionou muito melhor. Um dia coloco aqui, mas não agora.</p>
<p>O lance é que pra enviar os dados, habilitei o <a href="http://code.google.com/appengine/docs/python/config/appconfig.html#Secure_URLs">https</a> e também <a href="http://code.google.com/appengine/docs/python/config/appconfig.html#Requiring_Login_or_Administrator_Status">autenticação</a>. Assim, os blocos de dados podem ser sincronizados com segurança, apenas por um administrador da aplicação.</p>
<p>O problema foi fazer meu script se autenticar no <a href="https://www.google.com/accounts/">Google Accounts</a>. Apesar da <a href="http://code.google.com/appengine/docs/python/users/">API de autenticação</a> do appengine, preferi não usá-la pois não há necessidade no meu caso, e optei por usar o formulário genérico do Google.</p>
<p>Encontrei <a href="http://groups.google.co.in/group/google-appengine/browse_thread/thread/4c02a21cf5e613a3">este documento</a> com alguns exemplos e dúvidas, mas não foi suficiente. Finalmente, entendi como o negócio funciona:</p>
<ul>
<li>Faz um POST no serviço do Google Accounts enviando usuário, senha, nome de identificação e URL do app;</li>
<li>O Google Accounts irá fornecer um <a href="http://en.wikipedia.org/wiki/Session_token">token</a>, que então deve ser passado pro sistema de autenticação do próprio app (igual ao <a href="http://code.google.com/appengine/docs/python/tools/devserver.html">dev_appserver.py</a>)</li>
<li>Nesse último request, o Google fornece um <a href="http://en.wikipedia.org/wiki/HTTP_cookie">Cookie</a> chamado ACSID, que deverá ser usado em todos as próximas requisições.</li>
</ul>
<p>E pra resolver esse problema, escrevi uma classe chamada GoogleAuth, que recebe os dados necessários, se autentica no Google Accounts, e passa a fornecer o ACSID como <a href="http://docs.python.org/library/stdtypes.html#sequence-types-str-unicode-list-tuple-buffer-xrange">string</a>. Em caso de falha, tipo usuário ou senha errada, a classe gera um <a href="http://docs.python.org/library/exceptions.html">ValueError</a>.</p>
<pre class="brush: python;">
#!/usr/bin/env python
# coding: utf-8

import sys, urllib, urllib2

class GoogleAuth:
    cookie = ''

    # save the ACSID cookie before redirecting
    class RedirectHandler(urllib2.HTTPRedirectHandler):
        def __init__(self, klass): self.klass = klass
        def http_error_302(self, req, fp, code, msg, headers):
            try: self.klass.cookie = headers.get('Set-Cookie').split(';')[0]
            except: pass
            return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)

    # authenticate
    def __init__(self, appurl, appname, username, password):
        googauth = 'https://www.google.com/accounts/ClientLogin'

        # prepare the request data
        request_data = dict(
            Email=username,
            Passwd=password,
            source=appname,
            service='ah',
            accountType='HOSTED_OR_GOOGLE',
            )

        # get the token from google auth
        fd = urllib2.urlopen(googauth, urllib.urlencode(request_data))
        auth_dict = dict(x.split('=') for x in fd.read().split('\n') if x)
        fd.close()

        token = auth_dict.get('Auth')
        if auth_dict.get('Error') or not token:
            raise ValueError('authentication failed.')

        # get the ACSID cookie for further athenticated requests
        opener = urllib2.build_opener(self.RedirectHandler(self))
        fd = opener.open(appurl+'_ah/login?'+urllib.urlencode({'continue':appurl, 'auth':token}))
        fd.close()

    # return the cookie
    def __str__(self):
        return self.cookie

if __name__ == '__main__':
    appurl = 'http://myapp.appspot.com/'
    appname  = 'My App'
    username = 'foo'
    password = 'bar'

    # authenticate
    try: acsid = GoogleAuth(appurl, appname, username, password)
    except Exception, e:
        print str(e)
        sys.exit(1)

    # now access resources that require authentication...
    print 'authentication cookie:', acsid
    request = urllib2.Request(appurl, headers={'Cookie':acsid})
    chunk = urllib2.urlopen(request).read()
</pre>
Posted in programação, python, rede Tagged: appengine, autenticação, authentication, cookie, google, google accounts, python, redirecionamento, redirect, token, urllib, urllib2 <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/350/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=350&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/08/20/autenticacao-no-google-pro-appengine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/03/google_appengine-779483.png?w=150" medium="image">
			<media:title type="html">Google AppEngine</media:title>
		</media:content>
	</item>
		<item>
		<title>twisted crawler, alvo: mercadolivre</title>
		<link>http://fiorix.wordpress.com/2009/08/19/twisted-crawler-alvo-mercadolivre/</link>
		<comments>http://fiorix.wordpress.com/2009/08/19/twisted-crawler-alvo-mercadolivre/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 05:52:50 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rede]]></category>
		<category><![CDATA[crawler]]></category>
		<category><![CDATA[mercado livre]]></category>
		<category><![CDATA[twisted]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=340</guid>
		<description><![CDATA[Já pensou em fazer um programa que acessa o Mercado Livre, identifica o link de cada categoria, e extrai todos os produtos da primeira página de cada uma dessas categorias?
Pode até parecer complexo, mas não é. Esse programa existe, é simples, e está aqui, neste artigo, pronto pra você testar e modificar. :)
A algumas semanas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=340&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft size-full wp-image-345" title="logo_mercadolivre" src="http://fiorix.files.wordpress.com/2009/08/logo_mercadolivre.jpg?w=130&#038;h=130" alt="logo_mercadolivre" width="130" height="130" />Já pensou em fazer um programa que acessa o <a href="http://mercadolivre.com.br/">Mercado Livre</a>, identifica o link de cada categoria, e extrai todos os produtos da primeira página de <a href="http://www.mercadolivre.com.br/jm/ml.allcategs.AllCategsServlet">cada uma dessas categorias</a>?</p>
<p>Pode até parecer complexo, mas não é. Esse programa existe, é simples, e está aqui, neste artigo, pronto pra você testar e modificar. :)</p>
<p>A algumas semanas tenho feito alguns <a href="http://en.wikipedia.org/wiki/Web_crawler">crawlers</a> pra esses sites que vendem produtos, como o <a href="http://www.webmotors.com.br/">Web Motors</a>, <a href="http://www.submarino.com.br/">Submarino</a>, e até mesmo o <a href="http://www.ebay.com/">eBay</a>. A idéia é simplesmente extrair todos os produtos da primeira página de cada categoria, e montar uma base de dados com essas informações. O objetivo? <a href="http://en.wikipedia.org/wiki/Classified_information">Segredo de Estado</a>.</p>
<p>Um dos problemas que encontrei ao fazer esse tipo de crawler, é controlar a <a href="http://en.wikipedia.org/wiki/Concurrent_computing">concorrência de acesso</a>. Se o programa acessa uma categoria por vez, demora uma eternidade pra baixar e processar cada página. Por outro lado, se ele acessa todas as categorias descontroladamente, o processo acaba criando muitos <a href="http://en.wikipedia.org/wiki/File_descriptor">File Descriptors</a> e isso causa diversos outros problemas pro sistema operacional &#8211; e não adianta falar em aumentar o limite usando <a href="http://ss64.com/bash/ulimit.html">ulimit -n</a>, porque esses crawlers têm baixado <em>milhões</em> de links por dia.</p>
<p>A melhor maneira que encontrei pra solucionar esse problema, foi criando uma classe chamada &#8220;Controller&#8221;, que coloca as requisições em uma fila, baixa N páginas por vez, e ao invés de processá-las, simplesmente salva em um arquivo no disco.</p>
<p>Todos esses arquivos, com nomes únicos, são gerados usando um <a href="http://en.wikipedia.org/wiki/SHA_hash_functions">hash SHA1</a>, e colocados em uma lista para serem processados offline, após o processo de download terminar.</p>
<p>O <a href="http://twistedmatrix.com/">twisted</a> tem um <a href="http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#gatherResults">recurso muito interessante</a>, que permite agrupar diversos <a href="http://twistedmatrix.com/projects/core/documentation/howto/defer.html">deferreds</a> em um único, e quando todos eles terminam, executa um <a href="http://twistedmatrix.com/projects/core/documentation/howto/defer.html#auto0">callback</a>. Nesse caso, quando todos os processos de baixar a página da subcategoria terminam, executa a função &#8220;offline&#8221;, que começa a processar cada uma, e extrair os produtos de lá.</p>
<p>Esta segunda etapa também <em>poderia</em> ser feita em paralelo, usando o <a href="http://code.google.com/p/twisted-parallels/">twisted-parallels</a>, mas decidi não colocar porque o código ficaria muito maior e você não teria tanta paciência pra entendê-lo. Usar um <a href="http://en.wikipedia.org/wiki/Thread_pool_pattern">thread pool</a> pra isso não valeria a pena, pois vale lembrar que o python usa o <a href="http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock">GIL</a>, e I/O em thread só consome recurso e não aumenta em nada o desempenho.</p>
<p>A classe &#8220;MercadoLivre&#8221; tem 3 funções:</p>
<ul>
<li>__str__: retorna o link com todas as categorias do Mercado Livre</li>
<li>parse_categories: um <a href="http://en.wikipedia.org/wiki/Parsing">parser</a> que retorna uma lista composta por <a href="http://en.wikipedia.org/wiki/Tuple">tuples</a> de (url, nome)</li>
<li>parse_subcategory: um parser pro conteúdo de cada categoria, que retorna uma lista com o título dos produtos anunciados lá</li>
</ul>
<p>Todos esses parsers são baseados no <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup 3.1</a>. É necessário tê-lo instalado pra usar o programa.</p>
<p>Por fim, para usar este programa em outros sites, basta substituir a classe &#8220;MercadoLivre&#8221; pela sua própria, tipo &#8220;Submarino&#8221;.</p>
<p>Detalhe: essa porcaria de WordPress mostra a identação do código errada no artigo, mas se você clicar em &#8220;view plain&#8221;, poderá copiar e colar o código correto. Chame o suporte!</p>
<p>Aqui o código (muito belo, por sinal&#8230;):</p>
<pre class="brush: python;">
#!/usr/bin/env python
# coding: utf-8

import os, re, sys
import shutil, hashlib
from Queue import Queue
from BeautifulSoup import BeautifulSoup

# twisted
from twisted.web import client
from twisted.internet import defer, threads, reactor

class MercadoLivre:
    noscript = re.compile(r&quot;(?is)&lt;script[^&gt;]*&gt;(.*?)&lt;/script&gt;&quot;)

    def __str__(self):
	return 'http://www.mercadolivre.com.br/jm/ml.allcategs.AllCategsServlet'

    def parse_categories(self, content):
	catlist = {}
	cleanup = lambda s: s.replace('\n', '').strip()

	# parse the document
	soup = BeautifulSoup(content)

	# find all categories and their items
	current = ''
	for item in soup.findAll('a', {'class':['categ','seglnk']}):
	    text = cleanup(item.contents[0])
	    attrs = dict(item.attrs)
	    if attrs.get(u'class') == u'categ':
		current = text
		catlist[current] = []
	    else:
		catlist[current].append((attrs.get(u'href', ''), text))

	# return the list of categories and their items
	return catlist

    def parse_subcategory(self, content):
	result = []
	soup = BeautifulSoup(self.noscript.sub('', content),
	    convertEntities=BeautifulSoup.HTML_ENTITIES)

	for item in soup.findAll('div', {'class':'col_titulo'}):
	    result.append(item.find('a').contents[0].strip())

	return result

class Controller:
    def __init__(self, fetch):
	self.count = 0
	self.limit = fetch
	self.queue = Queue()
	self.tmpdir = '/tmp/mercadolivre.%d' % os.getpid()
	self.dispatch()

    def encode(self, text):
	return unicode(text).encode('utf-8', 'replace')

    def getPage(self, url, *args, **kwargs):
	d = defer.Deferred()
	self.queue.put((d, url, args, kwargs))
	return d

    def dispatch(self):
	while True:
	    try:
		assert self.count &lt; self.limit
		d, url, args, kwargs = self.queue.get_nowait()
	    except: break
	    self.count += 1
	    deferred = client.getPage(url, *args, **kwargs)
	    deferred.addBoth(self.decrease_count)
	    deferred.chainDeferred(d)
	reactor.callLater(1, self.dispatch)

    def decrease_count(self, result):
	self.count -= 1
	return result

class main(Controller):
    def __init__(self, fetch, parser):
	# set the concurrent download limit for the crawler
	Controller.__init__(self, fetch)

	# fetch the main categories page
	self.total = 0
	self.files = []
	self.parser = parser
	d = self.getPage(str(parser), timeout=60)
	d.addCallback(self.fetch_categories)
	d.addErrback(self.error_categories)

    def error_categories(self, error):
	# hmmm... fatal error, cannot continue
	print 'cannot fetch categories from %s: %s' % (str(self.parser), str(error))
	reactor.stop()

    def error_subcategory(self, error, href, category, subcategory):
	# problem fetching subcategory contents...
	print 'error &quot;%s / %s&quot;: [%s] %s' % (category, subcategory, href, error.value)

    def fetch_categories(self, content):
	# parse the contents in a thread
	reactor.callInThread(self.parse_categories, content)

    def parse_categories(self, content):
	try: categories = self.parser.parse_categories(content)
	except Exception, e:
	    print 'error parsing categories: %s' % str(e)
	    reactor.stop()
	    return

	print 'going to fetch %d categories...' % len(categories)
	tasks = []
	for category, contents in categories.items():
	    category = self.encode(category)
	    for href, subcategory in contents:
		href, subcategory = self.encode(href), self.encode(subcategory)
		d = self.getPage(href, timeout=60)
		d.addCallback(self.save_subcategory, href, category, subcategory)
		d.addErrback(self.error_subcategory, href, category, subcategory)
		tasks.append(d)

	# call the offline subcategory parser after downloading everything...
	d = defer.gatherResults(tasks)
	d.addCallback(self.offline)

    def save_subcategory(self, contents, href, category, subcategory):
	# create the tmpdir if it doesn't exist
	if not os.path.exists(self.tmpdir): os.mkdir(self.tmpdir)

	# create a unique hash for each category
	hash = hashlib.new('sha1', category+subcategory).hexdigest()
	filename = os.path.join(self.tmpdir, hash+'.dump')
	try:
	    fd = open(filename, 'w')
	    fd.write(contents)
	    fd.close()
	except: return
	self.files.append((href, category, subcategory, filename))
	print 'saving &quot;%s / %s&quot;: %s' % (category, subcategory, hash)

    def offline(self, null):
	# start processing each subcategory...
	reactor.stop()
	for item in self.files:
	    href, category, subcategory, filename = item
	    sys.stdout.write('parsing &quot;%s / %s&quot;: ' % (category, subcategory))
	    sys.stdout.flush()
	    fd = open(filename)
	    try: results = self.parser.parse_subcategory(fd.read())
	    except Exception, e:
		print 'error! %s' % str(e)
		continue

	    lr = len(results)
	    self.total += lr
	    print '%d items' % lr
	    for result in results:
		print '  ' + self.encode(result)

	print '\n%d items processed. cleaning up!' % self.total
	shutil.rmtree(self.tmpdir)

if __name__ == '__main__':
    reactor.callWhenRunning(main, 10, MercadoLivre())
    reactor.run()
</pre>
<p>Agora, é só você se dedicar e fazer isso pros sites que te interessam.</p>
<p>Notas?</p>
Posted in programação, python, rede Tagged: crawler, mercado livre, python, twisted, web <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/340/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=340&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/08/19/twisted-crawler-alvo-mercadolivre/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/08/logo_mercadolivre.jpg" medium="image">
			<media:title type="html">logo_mercadolivre</media:title>
		</media:content>
	</item>
		<item>
		<title>skype no iphone 3g</title>
		<link>http://fiorix.wordpress.com/2009/08/17/skype-no-iphone-3g/</link>
		<comments>http://fiorix.wordpress.com/2009/08/17/skype-no-iphone-3g/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 06:13:21 +0000</pubDate>
		<dc:creator>alef</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[rede]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[telecom]]></category>
		<category><![CDATA[3g]]></category>
		<category><![CDATA[chamada de voz]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[jailbreak]]></category>
		<category><![CDATA[skype]]></category>
		<category><![CDATA[voice call]]></category>

		<guid isPermaLink="false">http://fiorix.wordpress.com/?p=333</guid>
		<description><![CDATA[Depois de tanto tempo sem escrever nada, volto logo com uma boa: fazer chamadas de voz por SIP ou Skype, no iPhone, usando a rede 3G !
Aproveitando o assunto (iPhone), vale lembrar que tem apenas duas coisas que me irritam profundamente (até agora) com este telefone:

Não permitir SIP/VoIP/Skype pela rede 3G (olho gordo das operadoras)
Não [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=333&subd=fiorix&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img class="alignleft size-thumbnail wp-image-334" title="skype-logo" src="http://fiorix.files.wordpress.com/2009/08/skype-logo.jpg?w=83&#038;h=83" alt="skype-logo" width="83" height="83" />Depois de tanto tempo sem escrever nada, volto logo com uma boa: fazer chamadas de voz por SIP ou <a href="http://www.skype.com">Skype</a>, no <a href="http://www.apple.com/iphone/">iPhone</a>, usando a rede 3G !</p>
<p>Aproveitando o assunto (iPhone), vale lembrar que tem apenas duas coisas que me irritam profundamente (até agora) com este telefone:</p>
<ol>
<li>Não permitir SIP/VoIP/Skype pela rede 3G (olho gordo das operadoras)</li>
<li>Não ter suporte a Flash (idiotice da Apple por causa dos jogos)</li>
</ol>
<p>De resto, pra quem curte Interweb, é o melhor aparelho que existe.</p>
<p>Voltando ao assunto&#8230; a primeira coisa necessária pra ignorar as restrições de SIP/VoIP/Skype apenas pela conexão <a href="http://en.wikipedia.org/wiki/Wi-Fi">WiFi</a> é fazer o <a href="http://blog.iphone-dev.org/">jailbreak</a> do telefone. O melhor programa que encontrei pra fazer isso, à partir do <a href="http://www.apple.com/macosx/">Mac OS X</a>, é o <a href="http://blog.iphone-dev.org/post/126465561/trois-drei-h-rom">PwnageTool</a> &#8211; não sei o que tem pra Linux nem Windows, não me xinguem.</p>
<p>O jailbreak irá instalar o <a href="http://cydia.saurik.com/">Cydia</a> automaticamente, que é um front-end pro <a href="http://en.wikipedia.org/wiki/Advanced_Packaging_Tool">APT</a>, exatamente igual ao do <a href="http://www.debian.org/">Debian</a>.</p>
<p>Depois disso é necessário conectar o iPhone a uma rede WiFi, saber o endereço IP dele, e pelo Cydia, instalar os pacotes <a href="http://cydia.saurik.com/openssh.html">OpenSSH</a>, APT7 (Strict) e Bigboss Recommended Tools (este irá prover tudo que interessa: ps, vim, etc&#8230;).</p>
<p>Com isso feito, você precisa conectar via SSH no iPhone, usando o seu programa preferido: ssh no console, ou <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a> pros usuários de Windows. Pra conectar no iPhone, o usuário é <em>root</em> e a senha padrão é <em>alpine</em>.</p>
<p>No console, é necessário instalar dois pacotes:</p>
<ul>
<li><a href="http://cydia.saurik.com/info/mobilesubstrate/">mobilesubstrate</a> : resumindo, insere código em um app durante sua execução</li>
<li><a href="http://moreinfo.thebigboss.org/moreinfo/voipover3gDp.php">voipoverip3g</a>: biblioteca do mobilesubstrate pra enganar o iPhone, assim os programar não sabem que estão usando 3G, e pensam que é WiFi (duh!)</li>
</ul>
<p>Para instalar, o procedimento é padrão de debian/ubuntu, mas no console do iPhone:</p>
<pre>apt-get install mobilesubstrate voipoverip3g</pre>
<p>Com isso feito, reinicie o iPhone, re-instale o Skype, e seja feliz. Quando abrir o Skype pela primeira vez, ele vai reclamar que &#8220;não foi feito pra rodar em iPhoneOS modificado&#8221;, mas é &#8220;apenas uma mensagem&#8221;.</p>
<p>Pros mais interessados: o pacote <em>voipoverip3g</em> instala esse &#8220;plugin&#8221; pro mobilesubtrate, e sua configuração fica em</p>
<pre>/Library/MobileSubstrate/DynamicLibraries/VoIPover3G.plist</pre>
<p>Você pode adicionar suporte a qualquer programa que seja restrito ao uso de SIP/VoIP pela rede WiFi, basta editar com vim e adicionar a chave do programa, seguindo o formato do arquivo. O padrão é adicionar suporte ao Fring e Skype.</p>
<p>Este é o conteúdo original do arquivo:</p>
<pre>Bozo:~ root# cat /Library/MobileSubstrate/DynamicLibraries/VoIPover3G.plist
Filter = {Bundles = ("com.Fringland.Fring", "com.skype.skype");};</pre>
<p>Boa?</p>
Posted in mobile, rede, sistema, telecom Tagged: 3g, chamada de voz, iphone, jailbreak, skype, voice call <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fiorix.wordpress.com/333/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fiorix.wordpress.com/333/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fiorix.wordpress.com/333/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fiorix.wordpress.com/333/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fiorix.wordpress.com/333/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fiorix.wordpress.com/333/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fiorix.wordpress.com/333/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fiorix.wordpress.com/333/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fiorix.wordpress.com/333/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fiorix.wordpress.com/333/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fiorix.wordpress.com&blog=3184614&post=333&subd=fiorix&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fiorix.wordpress.com/2009/08/17/skype-no-iphone-3g/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">alef</media:title>
		</media:content>

		<media:content url="http://fiorix.files.wordpress.com/2009/08/skype-logo.jpg?w=150" medium="image">
			<media:title type="html">skype-logo</media:title>
		</media:content>
	</item>
	</channel>
</rss>