<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Herberth Amaral &#187; tutorial</title> <atom:link href="http://herberthamaral.com/tag/tutorial/feed/" rel="self" type="application/rss+xml" /><link>http://herberthamaral.com</link> <description>Software development adventures</description> <lastBuildDate>Thu, 26 Aug 2010 13:59:42 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.1</generator> <item><title>Criando Web crawlers em Python – Parte II</title><link>http://herberthamaral.com/2010/03/criando-web-crawlers-em-python-parte-ii/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=criando-web-crawlers-em-python-parte-ii</link> <comments>http://herberthamaral.com/2010/03/criando-web-crawlers-em-python-parte-ii/#comments</comments> <pubDate>Sun, 07 Mar 2010 13:08:50 +0000</pubDate> <dc:creator>Herberth Amaral</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[crawler]]></category> <category><![CDATA[tutorial]]></category> <category><![CDATA[web]]></category><guid isPermaLink="false">http://herberthamaral.com/?p=257</guid> <description><![CDATA[Ir para  Criando Web crawlers em Python &#8211; Parte I Ir para Criando Web crawlers em Python &#8211; Parte III No post anterior, eu mostrei como recuperar informações básicas de uma página da Web usando urllib, urllib2 e BeautifulSoup. Neste post eu mostrarei como enviar dados via GET e POST. Há um excelente guia sobre [...]]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F03%2Fcriando-web-crawlers-em-python-parte-ii%2F"> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F03%2Fcriando-web-crawlers-em-python-parte-ii%2F&amp;source=HerberthAmaral&amp;style=normal" height="61" width="50" /> </a></div><p>Ir para  <a href="http://herberthamaral.com/2010/02/criando-web-crawlers-em-python-parte-i" target="_blank">Criando Web crawlers em Python &#8211; Parte I</a></p><p>Ir para <a href="http://herberthamaral.com/2010/03/criando-web-crawlers-em-python-parte-iii/" target="_blank">Criando Web crawlers em Python &#8211; Parte III</a></p><p>No <a href="http://herberthamaral.com/2010/02/criando-web-crawlers-em-python-parte-i/" target="_blank">post anterior</a>, eu mostrei como recuperar informações básicas de uma página da Web usando urllib, urllib2 e <a href="http://www.crummy.com/software/BeautifulSoup/" target="_blank">BeautifulSoup</a>. Neste post eu mostrarei como enviar dados via GET e POST.</p><p>Há um excelente guia sobre urllib2: o <a href="http://www.voidspace.org.uk/python/articles/urllib2.shtml" target="_blank">urllib2 &#8211; The Missing Manual</a> que foi de grande valia nos meus estudos. Nele, pode-se encontrar as informações sobre envio de informações do tipo GET e POST para o servidor. Isso será útil, pois é assim que a busca do <a href="http://sf.net">SourceForge</a> (e da maioria dos outros portais) funcionam.</p><p>Vamos dar uma olhada na URL do na pesquisa por &#8220;Python&#8221; no SF:</p><pre>http://sourceforge.net/search/?type_of_search=soft&amp;words=python</pre><p>Bem, isso indica que temos que enviar duas variáveis para o SF.net: <em>type_of_search</em> (sempre igual à soft) e <em>words</em> (que é a nossa busca). Um exemplo de código que faria essa busca poderia ser esse:</p><div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>,<span style="color: #dc143c;">urllib2</span><br /> <br /> base_url = <span style="color: #483d8b;">'http://sourceforge.net'</span><br /> busca = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Pesquisar por: '</span><span style="color: black;">&#41;</span><br /> <br /> variaveis_get = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'type_of_search'</span>:<span style="color: #483d8b;">'soft'</span>,<span style="color: #483d8b;">'words'</span>:busca<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br /> req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>base_url+<span style="color: #483d8b;">'/search/'</span>,variaveis_get<span style="color: black;">&#41;</span><br /> response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br /> <span style="color: #ff7700;font-weight:bold;">print</span> response</div></div><p>Se der tudo certo, você  deveráver  o código fonte da página do SF que contém os resultados da pesquisa.</p><p>Feito isso, vamos analisar como a marcação do SF é organizada na busca:</p><p style="text-align: center;"><a href="http://herberthamaral.com/wp-content/uploads/2010/03/Screenshot-SourceForge.net-Software-Search-Mozilla-Firefox.png"><img class="aligncenter size-full wp-image-265" title="Resultados da busca no SF.net por Python" src="http://herberthamaral.com/wp-content/uploads/2010/03/Screenshot-SourceForge.net-Software-Search-Mozilla-Firefox.png" alt="" width="994" height="607" /></a></p><p style="text-align: left;">O <a href="http://getfirebug.com/">Firebug</a> nos ajuda a não perder tanto tempo assim analisando código. De acordo com o que pudemos obter, podemos dividir as informações que queremos dessa forma:</p><ul><li>O resultado da busca está dentro de uma tabela com o id=&#8221;searchtable&#8221;.</li><li>Um resultado da busca está sempre dentro de um td com classe description.</li><li>O nome do projeto está dentro de um link dentro de um h2 dentro desse td &#8220;description&#8221;.</li><li>O link de download se encontra na próxima td da mesma linha da tabela.</li></ul><p><strong>Exibindo as informações dos projetos</strong></p><p>Agora nós temos como buscar nossa informação e como filtra-la. Como disse no<a href="http://herberthamaral.com/2010/02/criando-web-crawlers-em-python-parte-i/"> post anterior</a>, eu iria mostrar alguns usos mais avançados do BeautifulSoup, principalmente no que diz respeito à percorrer o documento. O próximo passo será mostrar as informações dos projetos que aparecem no resultado da nossa busca. Podemos fazer isso da seguinte forma:</p><div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> BeautifulSoup <span style="color: #ff7700;font-weight:bold;">import</span> BeautifulSoup<br /> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>,<span style="color: #dc143c;">urllib2</span><br /> <br /> base_url = <span style="color: #483d8b;">'http://sourceforge.net'</span><br /> busca = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Pesquisar por: '</span><span style="color: black;">&#41;</span><br /> <br /> variaveis_get = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'type_of_search'</span>:<span style="color: #483d8b;">'soft'</span>,<span style="color: #483d8b;">'words'</span>:busca<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br /> req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>base_url+<span style="color: #483d8b;">'/search/'</span>,variaveis_get<span style="color: black;">&#41;</span><br /> response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br /> <br /> soup = BeautifulSoup<span style="color: black;">&#40;</span>response<span style="color: black;">&#41;</span><br /> <span style="color: #808080; font-style: italic;"># procura pela tabela com id=searchtable</span><br /> tabela = soup.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'table'</span>,<span style="color: black;">&#123;</span><span style="color: #483d8b;">'id'</span>:<span style="color: #483d8b;">'searchtable'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span> <br /> <span style="color: #808080; font-style: italic;">#retorna uma lista com todas as linhas (&amp;lt;tr&amp;gt;) da tabela</span><br /> linhas_tabela = tabela.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'tr'</span><span style="color: black;">&#41;</span> <br /> <br /> i=<span style="color: #ff4500;">0</span><br /> <br /> <span style="color: #ff7700;font-weight:bold;">for</span> linha <span style="color: #ff7700;font-weight:bold;">in</span> linhas_tabela:<br /> &nbsp; &nbsp; i+=<span style="color: #ff4500;">1</span><br /> &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#encontra a primeira coluna (descricao) da linha</span><br /> &nbsp; &nbsp; coluna_descricao = linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span><span style="color: black;">&#41;</span> <br /> <br /> &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#o atributo contents contem uma lista com o conteudo da tag</span><br /> &nbsp; &nbsp; nome_projeto = coluna_descricao.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: black;">contents</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <br /> <br /> &nbsp; &nbsp; descricao_projeto = coluna_descricao.<span style="color: black;">contents</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Projeto '</span>+<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">': '</span>+nome_projeto<br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> descricao_projeto<br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'--------------------------------'</span></div></div><p>Legal, não?  Isso é uma demonstração básica do poder que o BeautifulSoup tem para percorrer e extrair informações em (X)HTML. O mais interessante de tudo é que quase todos os métodos da classe BeutifulSoup.Tag retornam a própria referência, o que quer dizer que podemos fazer <em>chains</em> (cadeias) de comando como essas:</p><pre class="brush:python">nome_do_primeiro_projeto_da_pesquisa = soup.find('table',{'id':'searchtable'}).findAll('tr')[0].find('td').find('a').contents[0]</pre><p>Isso é realmente muito útil quando se quer economizar código. E o mais interessante de tudo: é bem legível (mas não necessariamente fácil de interpretar&#8230; quem ler seu código assim terá que ter uma boa noção do BeautifulSoup).</p><p><strong>Baixando os arquivos do projeto</strong></p><p>Essa parte é relativamente fácil. O SF é um serviço muito bom, até para o nosso pequeno experimento <img src='http://herberthamaral.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>A URL que o link &#8220;Download Now&#8221; aponta sofre 3 redirects até o arquivo final. Tudo isso serve para o SF determinar a sua localização e apontar o mirror mais próximo de você. Então a única coisa que precisamos fazer é passar esse link para o <strong>wget </strong>(um programa bem útil para download de arquivos na Web presente na maioria das distribuições Linux. Um clone para Windows pode ser encontrado <a href="http://gnuwin32.sourceforge.net/packages/wget.htm" target="_blank">aqui</a>) e ele irá baixar o projeto para nós. Simples, não?</p><p>Então vamos ao código:</p><div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> BeautifulSoup <span style="color: #ff7700;font-weight:bold;">import</span> BeautifulSoup<br /> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>,<span style="color: #dc143c;">urllib2</span><br /> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">subprocess</span> <span style="color: #ff7700;font-weight:bold;">import</span> call<br /> <br /> base_url = <span style="color: #483d8b;">'http://sourceforge.net'</span><br /> busca = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Pesquisar por: '</span><span style="color: black;">&#41;</span><br /> <br /> variaveis_get = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'type_of_search'</span>:<span style="color: #483d8b;">'soft'</span>,<span style="color: #483d8b;">'words'</span>:busca<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br /> req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>base_url+<span style="color: #483d8b;">'/search/'</span>,variaveis_get<span style="color: black;">&#41;</span><br /> response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br /> <br /> soup = BeautifulSoup<span style="color: black;">&#40;</span>response<span style="color: black;">&#41;</span><br /> <br /> <span style="color: #808080; font-style: italic;"># procura pela tabela com id=searchtable</span><br /> tabela = soup.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'table'</span>,<span style="color: black;">&#123;</span><span style="color: #483d8b;">'id'</span>:<span style="color: #483d8b;">'searchtable'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span> <br /> <br /> &nbsp;<span style="color: #808080; font-style: italic;">#retorna uma lista com todas as linhas da tabela</span><br /> linhas_tabela = tabela.<span style="color: black;">findAll</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'tr'</span><span style="color: black;">&#41;</span><br /> <br /> i=<span style="color: #ff4500;">0</span><br /> links_download = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br /> <br /> <span style="color: #ff7700;font-weight:bold;">for</span> linha <span style="color: #ff7700;font-weight:bold;">in</span> linhas_tabela:<br /> &nbsp; &nbsp; i+=<span style="color: #ff4500;">1</span><br /> &nbsp; &nbsp; coluna_descricao = linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'td'</span><span style="color: black;">&#41;</span><br /> &nbsp; &nbsp; nome_projeto = coluna_descricao.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>.<span style="color: black;">contents</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br /> &nbsp; &nbsp; link_download = linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span>,<span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'downloadnow'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'href'</span><span style="color: black;">&#93;</span><br /> &nbsp; &nbsp; links_download.<span style="color: black;">append</span><span style="color: black;">&#40;</span>link_download<span style="color: black;">&#41;</span><br /> &nbsp; &nbsp; descricao_projeto = coluna_descricao.<span style="color: black;">contents</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Projeto '</span>+<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">': '</span>+nome_projeto<br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> descricao_projeto<br /> &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'--------------------------------'</span><br /> <br /> opcao = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Qual projeto gostaria de baixar? '</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br /> opcao_url = base_url+links_download<span style="color: black;">&#91;</span>opcao-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br /> call<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'wget'</span>,opcao_url<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#chama o wget com o link para download</span></div></div><p>A única coisa que eu fiz de novo foi adicionar o link de download em uma lista e perguntar ao usuário qual projeto ele deseja baixar. Então, eu passei o link de download para o wget que fez o serviço de baixar o arquivo pra mim. Pronto! Nosso crawler de exemplo do SF.net está pronto <img src='http://herberthamaral.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>No proximo post eu mostrarei como guardar valores de sessão para percorrermos páginas protegidas por senha. See ya!</p><p><h4>Posts relacionados:</h4><ol><li><a href='http://herberthamaral.com/2010/02/criando-web-crawlers-em-python-parte-i/' rel='bookmark' title='Permanent Link: Criando Web crawlers em Python &#8211; Parte I'>Criando Web crawlers em Python &#8211; Parte I</a></li><li><a href='http://herberthamaral.com/2010/03/criando-web-crawlers-em-python-parte-iii/' rel='bookmark' title='Permanent Link: Criando Web crawlers em Python &#8211; Parte III'>Criando Web crawlers em Python &#8211; Parte III</a></li><li><a href='http://herberthamaral.com/2010/05/criando-web-crawlers-distribuidos-em-python-parte-iv/' rel='bookmark' title='Permanent Link: Criando Web crawlers (distribuidos) em Python &#8211; Parte IV'>Criando Web crawlers (distribuidos) em Python &#8211; Parte IV</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://herberthamaral.com/2010/03/criando-web-crawlers-em-python-parte-ii/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Criando screencasts no Linux</title><link>http://herberthamaral.com/2010/02/criando-screencasts-no-linux/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=criando-screencasts-no-linux</link> <comments>http://herberthamaral.com/2010/02/criando-screencasts-no-linux/#comments</comments> <pubDate>Sun, 21 Feb 2010 02:14:34 +0000</pubDate> <dc:creator>Herberth Amaral</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[dica]]></category> <category><![CDATA[screencast]]></category> <category><![CDATA[tutorial]]></category><guid isPermaLink="false">http://herberthamaral.com/?p=233</guid> <description><![CDATA[Eu vi algumas pessoas reclamando sobre a dificuldade de criar screencasts usando Linux. É, eu também tive algumas dificuldades. Nenhuma das ferramentas que eu consegui encontrar com minhas buscas não resolviam meu problema: Istanbul &#8211; Bonitinho, parece leve, grava legal, mas simplesmente dá um erro de IO (não entendi direito qual era o erro ) [...]]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F02%2Fcriando-screencasts-no-linux%2F"> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F02%2Fcriando-screencasts-no-linux%2F&amp;source=HerberthAmaral&amp;style=normal" height="61" width="50" /> </a></div><p>Eu vi algumas pessoas <a href="http://linux-sucks.blogspot.com/2006/12/desktop-recording-crusade.html" target="_blank">reclamando</a> sobre a dificuldade de criar screencasts usando Linux. É, eu também tive algumas dificuldades. Nenhuma das ferramentas que eu consegui encontrar com minhas buscas não resolviam meu problema:</p><ol><li><a href="http://live.gnome.org/Istanbul" target="_blank"><strong>Istanbul</strong></a> &#8211; Bonitinho, parece leve, grava legal, mas simplesmente dá um erro de IO (não entendi direito qual era o erro ) e não salva.</li><li><strong><a href="http://xvidcap.sourceforge.net/" target="_self">xvidcap</a> </strong>- Levíssimo, completo, mas tem problema com o PulseAudio e não grava o áudio do microfone. Tentei inicializa-lo com o comando <em>padsp xvidcap</em>, mas também não resolveu: mesmo chiado no som.</li><li><strong><a href="http://recordmydesktop.sourceforge.net/about.php" target="_self">recordMyDesktop</a> </strong>- Grava áudio normal, mas as imagens tinham uma qualidade horrível. Parecia que ele atualizava uma parte da tela e esquecia da outra. Resultado: eu gravava um teste no VIM na linha de comando (preta) e quando eu passava pro GMail (verde) a tela ainda continuava preta&#8230;</li></ol><p>Não sei o por quê, mas nem todos os programas que vem no Linux vêm com as configurações mais comuns já de cara. O problema é que eu não percebi que o recordMyDesktop encaixaria perfeitamente pra mim se ele já viesse com uma opção já marcada desde o início:</p><p><a href="http://herberthamaral.com/wp-content/uploads/2010/02/Screenshot-1.png"><img class="aligncenter size-full wp-image-234" title="Screenshot-1" src="http://herberthamaral.com/wp-content/uploads/2010/02/Screenshot-1.png" alt="screenshot das configurações do recordMyDesktop" width="335" height="558" /></a>Estranho, não? Eu pensava que marcar &#8220;Full shots at every frame&#8221; resolveria meu problema, mas, inexplicavelmente, o &#8220;Encode On the Fly&#8221; resolveu. Apesar da tooltip dizer que essa opção consome mais poder de processamento, eu não notei tanto. A qualidade do vídeo ficou impecável e eu estou com os efeitos no máximo <img src='http://herberthamaral.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Se após gravado o screencast você desejar edita-lo ou converte-lo, há uma gama de softwares para Linux mesmo que fazem isso. Para conversão eu uso muito o <a href="http://www.ffmpeg.org/" target="_blank">ffmpeg</a> (não conheço nenhum outro melhor e mais completo) e me recomendaram o <a href="http://fixounet.free.fr/avidemux/" target="_blank">Avidemux</a> para edição de vídeo. A única coisa que eu sinto falta agora é algo que coloque os caracteres digitados na tela e que destaque o clique do mouse.</p><p>See ya!</p><p>Sem posts relacionados.</p>]]></content:encoded> <wfw:commentRss>http://herberthamaral.com/2010/02/criando-screencasts-no-linux/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Testes unitarios no Flex usando o FlexUnit 4</title><link>http://herberthamaral.com/2010/01/testes-unitarios-no-flex-usando-o-flexunit-4/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=testes-unitarios-no-flex-usando-o-flexunit-4</link> <comments>http://herberthamaral.com/2010/01/testes-unitarios-no-flex-usando-o-flexunit-4/#comments</comments> <pubDate>Thu, 28 Jan 2010 14:12:08 +0000</pubDate> <dc:creator>Herberth Amaral</dc:creator> <category><![CDATA[Flex & Actionscript]]></category> <category><![CDATA[agile]]></category> <category><![CDATA[tdd]]></category> <category><![CDATA[flex]]></category> <category><![CDATA[flex builder]]></category> <category><![CDATA[flexunit 4]]></category> <category><![CDATA[integração contínua]]></category> <category><![CDATA[tutorial]]></category><guid isPermaLink="false">http://herberthamaral.com/?p=179</guid> <description><![CDATA[O FlexUnit 4 é a mais nova versão (não tem a oficial, só a RC, por enquanto) e apresenta uma série de vantagens sobre o seu antecessor, o FlexUnit 0.9, como os metadados de teste ([Test], [After] e [Before], para citar as mais populares), Theories, DataPoints e Assumptions que são úteis para testar grandes quantidades [...]]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F01%2Ftestes-unitarios-no-flex-usando-o-flexunit-4%2F"> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fherberthamaral.com%2F2010%2F01%2Ftestes-unitarios-no-flex-usando-o-flexunit-4%2F&amp;source=HerberthAmaral&amp;style=normal" height="61" width="50" /> </a></div><p>O FlexUnit 4 é a mais nova versão (não tem a oficial, só a RC, por enquanto) e apresenta uma série de vantagens sobre o seu antecessor, o FlexUnit 0.9, como os metadados de teste ([Test], [After] e [Before], para citar as mais populares), Theories, DataPoints e Assumptions que são úteis para testar grandes quantidades (talvez até infinita) de dados e ver como a aplicação se comporta e a possibilidade de executar os testes com diferentes Runners.</p><p>Este tutorial tem como objetivo mostrar o básico de testes unitários no Flex, sem se aprofundar muito nos recursos avançados do framework de testes.  Eu pretendo ir postando mais tutoriais à medida que eu for me aprofundando na tecnologia.</p><p><strong>O setup</strong></p><p>Para usar o FlexUnit4, você precisa baixa-lo <a href="http://opensource.adobe.com/wiki/display/flexunit/Downloads" target="_blank">aqui</a>. Após isso, crie um projeto no Flex Builder e adicione todas as libs que vieram no pacote no seu diretório libs:<br /> <a href="http://herberthamaral.com/wp-content/uploads/2010/01/flex_new_project.png"><img class="aligncenter size-full wp-image-180" title="flex_new_project" src="http://herberthamaral.com/wp-content/uploads/2010/01/flex_new_project.png" alt="" width="680" height="591" /></a></p><div id="attachment_182" class="wp-caption aligncenter" style="width: 275px"><a href="http://herberthamaral.com/wp-content/uploads/2010/01/flex_navigator1.png"><img class="size-full wp-image-182" title="flex_navigator" src="http://herberthamaral.com/wp-content/uploads/2010/01/flex_navigator1.png" alt="" width="265" height="308" /></a><p class="wp-caption-text">Verifique se todas as libs estão lá</p></div><p>Como o bom e velho TDD manda, vamos primeiro escrever a classe de teste de exemplo antes de escrever nosso código de produção.</p><p><strong>A classe de teste</strong></p><p>Uma classe de testes é uma classe comum que usa a classe Assert para fazer asserções. No exemplo que irei mostrar, usarei dois tipos básicos de asserção, mas se você observar, o FlexUnit possui vários tipos diferentes de asserções:</p><pre class="brush:java">package tests
{
	import org.flexunit.Assert;
	import org.flexunit.runner.manipulation.filters.IncludeAllFilter;

	import production.BasicClass;

	public class BasicTests
	{
		public function BasicTests(){}
		private var basicClass:BasicClass;

		[Before]
		public function before():void
		{
			basicClass = new BasicClass();
		}

		[Test]
		public function Verifica_Se_As_Duas_Strings_Sao_Iguais():void
		{
			var str:String = "MinhaString";
			Assert.assertTrue(basicClass.areStringsEqual(str,"MinhaString"));
		}

		[Test]
		public function Verifica_Se_A_Soma_Retorna_Resultado_Correto():void
		{
			var soma:int = 10;
			Assert.assertEquals(soma,basicClass.somar(2,8));
		}

		[After]
		public function after():void
		{
			//codigo de after
		}

	}
}</pre><p><strong>A suíte de teste</strong></p><p>A suíte de testes inclui nosso caso de teste descrito acima e será útil para o Flex executar nossos testes. Sendo assim, nossa suíte de testes ficaria mais ou menos desse jeito:</p><pre class="brush:java">package tests
{
	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class MyTestSuite
	{
		public var baseTest:BasicTests;
		public function MyTestSuite(){}

	}
}</pre><p><strong>UITestRunner e o FlexUnitCore</strong></p><p>O UITestRunner é um componente do FlexUnit que mostra os testes numa interface gráfica. Ele ficará na nossa aplicação e mostrará os resultados dos testes.</p><p>O FlexUnitCore será o responsável por carregar as suítes de teste e por passar os dados de saída de testes para o UITestRunner. No nosso caso, nossa aplicação principal ficaria assim:</p><pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="run()" layout="absolute" xmlns:flexUnitUIRunner="http://www.adobe.com/2009/flexUnitUIRunner"&gt;
    &lt;mx:Script&gt;
    &lt;![CDATA[
       import tests.MyTestSuite;
       import org.flexunit.listeners.UIListener;
       import org.flexunit.runner.FlexUnitCore;

       public var core:FlexUnitCore;
       public function run():void
       {
           core = new FlexUnitCore();
           core.addListener(new UIListener(uiRunner));
           core.run(MyTestSuite);
      }
    ]]&gt;
   &lt;/mx:Script&gt;
   &lt;flexUnitUIRunner:TestRunnerBase id="uiRunner"  width="100%" height="100%"/&gt;
&lt;/mx:Application&gt;</pre><p><strong>O código de produção</strong></p><p>Ufa! Depois de escrever a classe de teste, a suíte de teste e o runner, podemos nos focar em fazer nosso código de produção <img src='http://herberthamaral.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Dêem uma olhada em como ficaria o dito:</p><pre class="brush:java">package production
{
	public class BasicClass
	{
		public function BasicClass(){}

		public function areStringsEqual(string1:String,string2:String):Boolean
		{
			return (string1==string2);
		}

		public function somar(valor1:int,valor2:int):int
		{
			return valor1+valor2;
		}

	}
}</pre><p><strong>E Voilà!</strong></p><p>Depois de tudo pronto, a cara da criança ficaria mais ou menos assim:</p><p><a href="http://herberthamaral.com/wp-content/uploads/2010/01/ui_runner.png"><img class="aligncenter size-medium wp-image-190" title="ui_runner" src="http://herberthamaral.com/wp-content/uploads/2010/01/ui_runner-300x177.png" alt="" width="300" height="177" /></a></p><p>Legal, não? E ainda dá pra fazer com que o FlexUnit4 exporte o resultado dos testes para um arquivo XML, permitindo que seus testes no Flex sejam importados pelo seu sistema de Integração Contínua, mas isso é assunto para outro post <img src='http://herberthamaral.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Você pode baixar o código fonte <a href="http://herberthamaral.com/wp-content/tutoriais/flexunit4/UsandoFlexUnit4.zip" target="_blank">aqui</a> e ver os exemplos rodando online <a href="http://herberthamaral.com/wp-content/tutoriais/flexunit4/" target="_blank">aqui</a>.</p><p>Good testing!</p><p>Sem posts relacionados.</p>]]></content:encoded> <wfw:commentRss>http://herberthamaral.com/2010/01/testes-unitarios-no-flex-usando-o-flexunit-4/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>