<?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>El Futirifoken &#187; General</title>
	<atom:link href="http://www.gazer.com.ar/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gazer.com.ar</link>
	<description>El arte de no decir nada ;-)</description>
	<lastBuildDate>Mon, 26 Dec 2011 19:56:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Oregano tiene nuevo lider</title>
		<link>http://www.gazer.com.ar/2011/12/26/oregano-tiene-nuevo-lider/</link>
		<comments>http://www.gazer.com.ar/2011/12/26/oregano-tiene-nuevo-lider/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 19:56:05 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Oregano]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1361</guid>
		<description><![CDATA[Luego ya de muchisimos años (parece eterno) alguien con pilas apareció Marc Lorber, quien va a ser el nuevo lider y main developer de Oregano, proyecto que salio de este grupo alguna vez. Marc estaba completando el port a Gtk3 y al nuevo canvas además de tener pilas para arreglar los bugs históricos que arrastramos [...]]]></description>
			<content:encoded><![CDATA[<p>Luego ya de muchisimos años (parece eterno) alguien con pilas apareció Marc Lorber, quien va a ser el nuevo lider y main developer de Oregano, proyecto que salio de este grupo alguna vez. Marc estaba completando el port a Gtk3 y al nuevo canvas además de tener pilas para arreglar los bugs históricos que arrastramos hace tiempo <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>El main git fue movido a <a href="https://github.com/marc-lorber/oregano" target="_blank">https://github.com/marc-<wbr>lorber/oregano</wbr></a> por lo que es la nueva fuente oficial.</p>
<p>Saludos y Feliz 2012 para todos!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2011/12/26/oregano-tiene-nuevo-lider/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git branch &amp; Subversion detection en el prompt de Bash</title>
		<link>http://www.gazer.com.ar/2011/09/06/git-branch-subversion-detection-en-el-prompt-de-bash/</link>
		<comments>http://www.gazer.com.ar/2011/09/06/git-branch-subversion-detection-en-el-prompt-de-bash/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 23:30:34 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[GNU+Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1355</guid>
		<description><![CDATA[Simple, agregar en el .bashrc lo siguiente : function parse_git_branch &#123; git branch --no-color 2&#62; /dev/null &#124; sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/' &#125; &#160; function detect_svn &#123; test -d .svn &#38;&#38; echo &#34;(svn)&#34; &#125; &#160; function proml &#123; local RED=&#34;\[\033[0;31m\]&#34; local LIGHT_RED=&#34;\[\033[1;31m\]&#34; local YELLOW=&#34;\[\033[0;33m\]&#34; local LIGHT_GREEN=&#34;\[\033[1;32m\]&#34; local WHITE=&#34;\[\033[1;37m\]&#34; local LIGHT_GRAY=&#34;\[\033[0;37m\]&#34; local LIGHT_PURPLE=&#34;\[\033[1;34m\]&#34; case $TERM [...]]]></description>
			<content:encoded><![CDATA[<p>Simple, agregar en el .bashrc lo siguiente :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> parse_git_branch <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #c20cb9; font-weight: bold;">git</span> branch <span style="color: #660033;">--no-color</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'/^[^*]/d'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/* \(.*\)/(\1)/'</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> detect_svn <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #660033;">-d</span> .svn <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;(svn)&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> proml <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span>         <span style="color: #007800;">RED</span>=<span style="color: #ff0000;">&quot;\[\033[0;31m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span>   <span style="color: #007800;">LIGHT_RED</span>=<span style="color: #ff0000;">&quot;\[\033[1;31m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span>      <span style="color: #007800;">YELLOW</span>=<span style="color: #ff0000;">&quot;\[\033[0;33m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">LIGHT_GREEN</span>=<span style="color: #ff0000;">&quot;\[\033[1;32m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span>       <span style="color: #007800;">WHITE</span>=<span style="color: #ff0000;">&quot;\[\033[1;37m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span>  <span style="color: #007800;">LIGHT_GRAY</span>=<span style="color: #ff0000;">&quot;\[\033[0;37m\]&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">LIGHT_PURPLE</span>=<span style="color: #ff0000;">&quot;\[\033[1;34m\]&quot;</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$TERM</span> <span style="color: #000000; font-weight: bold;">in</span>
    xterm<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #007800;">TITLEBAR</span>=<span style="color: #ff0000;">'\[\033]0;\u@\h:\w\007\]'</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #007800;">TITLEBAR</span>=<span style="color: #ff0000;">&quot;&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
<span style="color: #007800;">PS1</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">${TITLEBAR}</span><span style="color: #000099; font-weight: bold;">\
</span><span style="color: #007800;">$LIGHT_PURPLE</span>\w<span style="color: #007800;">$YELLOW</span><span style="color: #000099; font-weight: bold;">\$</span>(parse_git_branch)<span style="color: #000099; font-weight: bold;">\$</span>(detect_svn)<span style="color: #000099; font-weight: bold;">\
</span><span style="color: #007800;">$LIGHT_GRAY</span><span style="color: #000099; font-weight: bold;">\$</span> &quot;</span>
<span style="color: #007800;">PS2</span>=<span style="color: #ff0000;">'&gt; '</span>
<span style="color: #007800;">PS4</span>=<span style="color: #ff0000;">'+ '</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
proml</pre></div></div>

<p>Y se ve algo como (sin colores, sorry <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  :</p>
<pre>
~/src/some_git_project(master)$
~/src/some_svn_project(svn)$
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2011/09/06/git-branch-subversion-detection-en-el-prompt-de-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtro de Contenido para T!</title>
		<link>http://www.gazer.com.ar/2011/05/11/filtro-de-contenido-para-t/</link>
		<comments>http://www.gazer.com.ar/2011/05/11/filtro-de-contenido-para-t/#comments</comments>
		<pubDate>Wed, 11 May 2011 17:18:35 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1347</guid>
		<description><![CDATA[Hoy estuve leyendo este post donde los dueños de Taringa declara que &#8220;no podemos investigar el destino final de cada uno de los 20.000 post diarios&#8221;. Lejos de ser algo &#8220;colectivamente inteligente&#8221; como declaración, es una terrible boludez . Con aplicar algunos filtros automáticos, permitir que cualquiera de forma rápida y fácil reporte los contenidos [...]]]></description>
			<content:encoded><![CDATA[<p>Hoy estuve leyendo <a href="http://www.taringa.net/posts/taringa/10557222/La-situacion-de-Taringa_-explicada-por-nosotros.html">este</a> post donde los dueños de Taringa declara que &#8220;no podemos investigar el destino final de cada uno de los 20.000 post diarios&#8221;. Lejos de ser algo &#8220;colectivamente inteligente&#8221; como declaración, es una terrible boludez <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Con aplicar algunos filtros automáticos, permitir que cualquiera de forma rápida y fácil reporte los contenidos ilegales y actuando más o menos rápido en su eliminación uno se cubre el 90% del orto. El otro 10% hay que pelearlo por carta documento porque hay gente muy al pedo ahí afuera, pero ni en pedo llegamos a un juicio oral teniendo un poco de criterio <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>El problema es que filtrar a mano es caro, y además filtrar hace que nuestros usuarios bajen pues no tiene ya toda la piratería al alcance de la mano <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Pero veamos como hacer un filtro para determinar por heurística los posts que posiblemente sean ilegales, de manera de poder revisar a mano solo los que tal ve son malos, y así bajar el trabajo necesario y por ahí bajar el costo y aumentar el profit <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>No lo voy a explicar muy en detalle, pero básicamente el programa siguiente hace un scraping de la home de T! y agarra los &#8216;Ultimos posts&#8217;. Para cada uno de ellos, lee el contenido y aplica una heurística muy básica para ver si es potencialmente ilegal :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'hpricot'</span>
&nbsp;
AGENT = <span style="color:#996600;">&quot;Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10&quot;</span>
&nbsp;
url = <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://www.taringa.net/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
http = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;www.taringa.net&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
html = http.<span style="color:#9900CC;">request_get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/'</span>, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'User-Agent'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> AGENT<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
doc = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span>html.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#40;</span>doc<span style="color:#006600; font-weight:bold;">/</span><span style="color:#996600;">&quot;html/body/div[2]/div[4]/div[4]/div/div[2]/ul/li/a&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>link<span style="color:#006600; font-weight:bold;">|</span>
  text = http.<span style="color:#9900CC;">request_get</span><span style="color:#006600; font-weight:bold;">&#40;</span>link.<span style="color:#9900CC;">attributes</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'href'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'User-Agent'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> AGENT<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  doc1 = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span>text.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  content = <span style="color:#006600; font-weight:bold;">&#40;</span>doc1<span style="color:#006600; font-weight:bold;">/</span><span style="color:#996600;">&quot;html/body/div[2]/div[4]/div[4]/div/div[2]/div[2]&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">to_s</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>content =~ <span style="color:#006600; font-weight:bold;">/</span>megaupload<span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#40;</span>content =~ <span style="color:#006600; font-weight:bold;">/</span>free<span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#40;</span>content =~ <span style="color:#006600; font-weight:bold;">/</span>mediafire<span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#40;</span>content =~ <span style="color:#006600; font-weight:bold;">/</span>fileserve<span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{link.inner_html.strip} posible post ilegal&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>content =~ <span style="color:#006600; font-weight:bold;">/</span>Este post es privado<span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{link.inner_html.strip} es privado. Al menos si es ilegal no lo ve todo el mundo :)&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{link.inner_html.strip} parece legal.&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Con esto podemos saber :</p>
<ul>
<li>Cuantos posts parecen legales</li>
<li>Cuantos parecen ilegales</li>
<li>Cuantos no son públicos, por lo que podemos revisarlos o no, no es tan terrible</li>
</ul>
<p>Con un poco de bash sacamos las stats :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">gazer<span style="color: #000000; font-weight: bold;">@</span>Max:~$ ruby tfilter.rb <span style="color: #000000; font-weight: bold;">&gt;</span> post.txt
<span style="color: #000000;">54</span> post.txt
gazer<span style="color: #000000; font-weight: bold;">@</span>Max:~$ <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'posible post ilegal'</span> post.txt <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> <span style="color: #660033;">-l</span>
<span style="color: #000000;">2</span></pre></div></div>

<p>Solo el <strong>3.7%</strong> de los posts analizados parecería ser ilegales, por lo que en lugar de tener que revisar 20.000 posts por día solo deberia revisar 740, el número es otro. Si de esos ademas sumás el report del user, seguro no te quedan mucho más y hasta por ahí lo podés moderar mientras desayunas <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Obviamente mi filtro se basa solamente en linksharing (que es el 90% del problema de T! y del uso que sus usuarios le dan al site). Seguramente haya servicios de upload que no puse, pero para demostrar que filtrar el contenido es una terrible pelotudez y que Taringa! no lo hace porque no le conviene, alcanza y sobra <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a href='http://www.gazer.com.ar/wp-content/uploads/2011/05/post.txt'>Posts analizados</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2011/05/11/filtro-de-contenido-para-t/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Procesando archivos en background con Rails</title>
		<link>http://www.gazer.com.ar/2010/09/08/procesando-archivos-en-background-con-rails/</link>
		<comments>http://www.gazer.com.ar/2010/09/08/procesando-archivos-en-background-con-rails/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 16:42:29 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1297</guid>
		<description><![CDATA[Procesar archivos en paneles de administración es un bajón, sobre todo cuando son cada vez más grande y cada vez más. En uno de nuestros proyectos tenemos ya unos cinco archivos CSV diferentes a procesar donde cada uno cumple alguna función específica. Algunos de estos archivos superan los 5 Mb por upload, por lo que [...]]]></description>
			<content:encoded><![CDATA[<p>Procesar archivos en paneles de administración es un bajón, sobre todo cuando son cada vez más grande y cada vez más. En uno de nuestros proyectos tenemos ya unos cinco archivos CSV diferentes a procesar donde cada uno cumple alguna función específica. Algunos de estos archivos superan los 5 Mb por upload, por lo que se hizo necesario desacoplar el procesamiento del archivo del request que realiza el upload.</p>
<p>Para manejar procesos en background en rails hay muchas opciones buenas, algunas más complejas con colas de trabajo, workers distribuidos y otras cosas que nosotros no necesitamos. Lo importante para nosotros era encontrar alguno que permita :</p>
<ul>
<li>Procesar en background (obvio <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</li>
<li>Poder saber en que estado está el trabajo (% completado)</li>
<li>Al menos un proceso en background a la vez (si hay más que espere su turno, los uploads son semanales o mensuales por lo que no hay tanto solapamiento entre tareas como para justificar múltiples workers)</li>
</ul>
<p>Y nada más. Buscando y buscando caí con <a href="http://github.com/ncr/background-fu">BackgroundFu</a> que cumplía con lo necesario.</p>
<h3>Procesando los archivos</h3>
<p>Como todos los archivos son de texto con algún separador (algunos &#8216;;&#8217;, otros tabs o comas) empezamos por lo básico y crear una clase base que maneje algunos parámetros comunes.</p>
<p>En <a href="http://github.com/ncr/background-fu">BackgroundFu</a> uno puede encolar cualquier clase, por lo que nuestro worker es simplemente una clase con un método <code>process</code> (que también es arbitrario el nombre, podría ser cualquier otro).</p>
<p>Como el archivo que sube el usuario está en un directorio temporal, antes de mandar al proceso en background en necesario guardarlo en algún lugar seguro, para poder saber que al momento de procesarlo va a seguir estando, para ello encapsulamos este comportamiento en un método especial para encolar.</p>
<p>Nuestra completa termina siendo algo como (más adelante veremos en detalle algunas cosas) :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FileWorker
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">BackgroundFu::WorkerMonitoring</span>
&nbsp;
  attr_reader <span style="color:#ff3333; font-weight:bold;">:total_lines</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">enqueue</span><span style="color:#006600; font-weight:bold;">&#40;</span>file, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
    filename = <span style="color:#996600;">&quot;#{RAILS_ROOT}/tmp/#{self.name}-#{Time.now.to_i}&quot;</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#996600;">&quot;wb&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>file.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    Job.<span style="color:#9900CC;">enqueue</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">name</span>, :<span style="color:#996600;">'process'</span>, filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> process<span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@lines</span> = <span style="color:#006666;">0</span>
    <span style="color:#0066ff; font-weight:bold;">@total_lines</span> = <span style="color:#996600;">`wc -l #{filename}`</span>.<span style="color:#9900CC;">to_i</span>
    record_progress<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    result = real_process<span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    record_progress<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">unlink</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    result
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  protected
  <span style="color:#9966CC; font-weight:bold;">def</span> line_processed!
    <span style="color:#0066ff; font-weight:bold;">@lines</span> <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006666;">1</span>
&nbsp;
    update<span style="color:#006600; font-weight:bold;">&#40;</span>@lines<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> update<span style="color:#006600; font-weight:bold;">&#40;</span>lines<span style="color:#006600; font-weight:bold;">&#41;</span>
    record_progress<span style="color:#006600; font-weight:bold;">&#40;</span>lines, <span style="color:#0066ff; font-weight:bold;">@total_lines</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Veamos un poco más en detalle algunas partes.</p>
<h3>Encolado</h3>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">enqueue</span><span style="color:#006600; font-weight:bold;">&#40;</span>file, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
    filename = <span style="color:#996600;">&quot;#{RAILS_ROOT}/tmp/#{self.name}-#{Time.now.to_i}&quot;</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#996600;">&quot;wb&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>file.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    Job.<span style="color:#9900CC;">enqueue</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">name</span>, :<span style="color:#996600;">'process'</span>, filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Este método es quien guarda en un lugar seguro el archivo. Utilizando el nombre de la clase actual (recuerden que este método está en una clase base, de donde luego vamos a heredar) y un timestamp por las dudas que se lleguen a hacer 2 uploads (cosa que en la práctica no pasa, pero por las dudas está).</p>
<p>Luego de guardar el archivo se encola el trabajo pasándole el archivo (el path completo) y cualquier otro argumento que se quiera.</p>
<p>Esto hará que luego el daemon de background instancia la clase &#8216;self.name&#8217; y llame al método process pasandole nuestros parámetros.</p>
<h3>Procesamiento</h3>
<p>El método genérico de procesamiento hace uso de un método que la clase base no tiene &#8216;real_process&#8217; que es el método que las clases hijas definarán para realizar el trabajo final :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> process<span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@lines</span> = <span style="color:#006666;">0</span>
    <span style="color:#0066ff; font-weight:bold;">@total_lines</span> = <span style="color:#996600;">`wc -l #{filename}`</span>.<span style="color:#9900CC;">to_i</span>
    record_progress<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    result = real_process<span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    record_progress<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">unlink</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    result
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En este caso el método se encarga de saber cual es el total de lineas (de una manera tal vez no muy linda, pero que anda <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) y borrar el archivo al terminar el proceso.</p>
<h3>Un worker real</h3>
<p>Para que esto tenga sentido, debemos crear un worker que haga realmente algo, entonces por ejemplo podríamos tener un worker que sume puntos a los usuarios desde un archivo :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> UserPointProcessor <span style="color:#006600; font-weight:bold;">&lt;</span> FileWorker
  private
  <span style="color:#9966CC; font-weight:bold;">def</span> real_process<span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">transaction</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      FasterCSV.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#ff3333; font-weight:bold;">:col_sep</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\t</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>row<span style="color:#006600; font-weight:bold;">|</span>
         <span style="color:#008000; font-style:italic;"># Hacer algo con row</span>
&nbsp;
         line_processed!
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#996600;">&quot;Podemos retornar algun valor o status de exito&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>De esta forma podemos ahora en algún controller hacer el encolado del trabajo :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> add_points
    <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">post</span>?
      redirect_to admin_job_path<span style="color:#006600; font-weight:bold;">&#40;</span>UserPointProcessor.<span style="color:#9900CC;">enqueue</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:file</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    render <span style="color:#996600;">'file_upload'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En este caso el template <code>file_upload</code> es un form con un <em>file field</em> para hacer el upload, sin ningún otro campo. La ruta <code>admin_job_path</code> nos la provee directamente <a href="http://github.com/ncr/background-fu">BackgroundFu</a>, generándonos también las vistas con AJAX para actualizar el estado, una linda barra de progreso que nos muestra el tiempo estimado para terminar entre otros datos útiles (o no tanto <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/09/08/procesando-archivos-en-background-con-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtrando datos con jQuery</title>
		<link>http://www.gazer.com.ar/2010/06/25/filtrando-datos-con-jquery/</link>
		<comments>http://www.gazer.com.ar/2010/06/25/filtrando-datos-con-jquery/#comments</comments>
		<pubDate>Fri, 25 Jun 2010 03:19:21 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1289</guid>
		<description><![CDATA[Filtrar elementos dentro de una lista o una tabla para realizar una búsqueda inline con jQuery es bastante simple, solo basta entender un poco donde va cada cosa. La función en cuestión que nos permite hacer esto es filter() que junto con un poco de trabajo para hacer un deep-search dentro del DOM nos da [...]]]></description>
			<content:encoded><![CDATA[<p>Filtrar elementos dentro de una lista o una tabla para realizar una búsqueda inline con jQuery es bastante simple, solo basta entender un poco donde va cada cosa. La función en cuestión que nos permite hacer esto es <a href="http://api.jquery.com/filter/">filter()</a> que junto con un poco de trabajo para hacer un deep-search dentro del DOM nos da esta funcionalidad.</p>
<p>Por ejemplo si queremos mostrar los elementos de una lista que coinciden con una búsqueda deberíamos hacer algo como :</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  v <span style="color: #339933;">=</span> <span style="color: #3366CC;">'some word'</span><span style="color: #339933;">;</span>
  <span style="color: #009966; font-style: italic;">/* Ocultamos todos los LI */</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#list ul li'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009966; font-style: italic;">/* Filtramos y mostramos los que coinciden */</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#list ul'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">contents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> innerSearch<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>La función innerSearch la pueden ver en el ejemplo, y básicamente hace un recorrido por el DOM y devolviendo true en aquellos tags donde su contenido de texto contiene el patrón buscado.</p>
<p>Eso nos da muchas posibilidades, ya que por ejemplo en lugar de un simple show se podría aplicar alguna clase CSS para resaltar, modificar el color o lo que se les pueda ocurrir.</p>
<p>Por razones de <em>performance</em> no es muy útil para un DOM muy complejo, pero para el <a href="http://club.speedy.com.ar/concursos/llevate-dos-entradas-para-el-avant-premiere-de-brigada-a/ganadores">caso</a> donde yo lo necesité funciona aceptablemente bien.</p>
<p>Dejo <a href='http://www.gazer.com.ar/wp-content/uploads/2010/06/jquery_filter.html' target="_blank">un ejemplo</a> completo con filtrado en listas y tablas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/06/25/filtrando-datos-con-jquery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HTML5 : Guardar el contenido de &lt;canvas&gt; en el servidor</title>
		<link>http://www.gazer.com.ar/2010/04/13/html5-guardar-el-contenido-de-canvas-en-el-servidor/</link>
		<comments>http://www.gazer.com.ar/2010/04/13/html5-guardar-el-contenido-de-canvas-en-el-servidor/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 03:57:34 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Sinatra]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1267</guid>
		<description><![CDATA[Hoy tenía ganas de hacer algo distinto (vamos, no quería trabajar ) así que me puse a jugar con HTML5, entre otras cosas con el tag &#60;canvas&#62; para poder dibujar. Luego de bajar varios ejemplos y tener un &#8216;paint&#8217; andando lo que quería era guardar la imagen, y llegué a este post donde el autor [...]]]></description>
			<content:encoded><![CDATA[<p>Hoy tenía ganas de hacer algo distinto (vamos, no quería trabajar <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) así que me puse a jugar con HTML5, entre otras cosas con el tag &lt;canvas&gt; para poder dibujar. Luego de bajar varios ejemplos y tener un &#8216;paint&#8217; andando lo que quería era guardar la imagen, y llegué a este <a href="http://www.nihilogic.dk/labs/canvas2image/">post</a> donde el autor deja guardar en PNG, JPG hasta incluso en BMP el contenido del canvas.</p>
<p>Pero que el usuario se pueda guardar la imagen no era mi idea, era más bien guardarle en el servidor. Por ejemplo para hacer una firma digital y usarla después en el sitio para firmar los posts como si fueran documentos <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> .</p>
<p>Al principio pensé que iba a ser <em>super</em> complicado, pero me encontré que todo fue mucho más fácil de lo que imaginé. Así que vamos por partes.</p>
<p>Vamos a empezar por el server. Como era muy poco código para este ejemplo, hice una aplicación en <a href="http://www.sinatrarb.com/">Sinatra</a> que me permite mostrar un canvas y luego hacer un POST con los datos. Es ideal en este caso, ya que el server queda de tan solo unas 20 líneas de código :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'sinatra'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'RMagick'</span>
&nbsp;
get <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
   erb <span style="color:#ff3333; font-weight:bold;">:index</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
post <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># Ya completaremos ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Como se puede ver tenemos una vista en el root y el POST lo manejamos también en la raiz. Para procesar la imagen decidí usar la única gema que conozco, RMagick, que buscando en la documentación de ImageMagick me <a href="http://www.imagemagick.org/script/formats.php">encontré</a> con grata sorpresa que sale leer &#8216;Base64-encoded inline image&#8217; , que resulta que es justo el formato en que se obtienen los datos desde el canvas <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . La única diferencia es que hay que preceder el string con &#8216;inline:&#8217; y ya estamos, nuestro método POST queda así :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">post <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  data = <span style="color:#996600;">'inline:'</span> <span style="color:#006600; font-weight:bold;">+</span> request.<span style="color:#9900CC;">body</span>.<span style="color:#9900CC;">read</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">begin</span>
    image = <span style="color:#6666ff; font-weight:bold;">Magick::Image</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>
&nbsp;
    image.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'image.png'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#996600;">&quot;alert('Image saved successfully')&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    <span style="color:#996600;">&quot;alert('Image format not recognized')&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Habría que revisar la documentación y bugs de ImageMagick para ver que tipos de implicancia puede llegar a tener en la seguridad del sitio o del sistema, pero son cosas que no vienen al caso <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>La vista (reducida para el ejemplo) puede resumirse en el siguiente HTML :</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;canvas id=&quot;example&quot; width=&quot;200&quot; height=&quot;200&quot;&gt;
    This text is displayed if your browser does not support HTML5 Canvas.
  &lt;/canvas&gt;
&nbsp;
  &lt;input type=&quot;button&quot; id=&quot;submit&quot; value=&quot;Submit&quot; /&gt;</pre></div></div>

<p>Y un poco de javascript :</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// jQuery todavía no habla bien con HTML5, hack para</span>
      <span style="color: #006600; font-style: italic;">// no usar un plugin.</span>
      <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#example&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> c.<span style="color: #660066;">toDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Un dibujito estático para probar</span>
    <span style="color: #003366; font-weight: bold;">var</span> example <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'example'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> context <span style="color: #339933;">=</span> example.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2d'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">fillStyle</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;rgb(255,0,0)&quot;</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">fillRect</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">30</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">30</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Y ya estamos, al presionar el botón se envían los datos de la imagen dibujada, si está todo bien ImageMagick creará el archivo en el filesystem y por último devolverá algo de javascript para informar al usuario como salió todo. Obviamente si tuviéramos un sistema de usuarios en el server podríamos guardar la imagen para cada uno, pero de nuevo, no viene al caso.</p>
<p>El resultado final :</p>
<p><img src="http://www.gazer.com.ar/wp-content/uploads/2010/04/image.png" alt="" title="image" width="200" height="200" class="aligncenter size-full wp-image-1268" /></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ identify <span style="color: #660033;">-verbose</span> image.png 
Image: image.png
  Format: PNG <span style="color: #7a0874; font-weight: bold;">&#40;</span>Portable Network Graphics<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  Class: DirectClass
  Geometry: 200x200+<span style="color: #000000;">0</span>+<span style="color: #000000;">0</span>
  Resolution: 72x72
  Print <span style="color: #c20cb9; font-weight: bold;">size</span>: 2.77778x2.77778
  Colorspace: RGB
  Depth: <span style="color: #000000;">8</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1</span>-bit
  Histogram:
     <span style="color: #000000;">37500</span>: <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0</span>,  <span style="color: #000000;">0</span>,  <span style="color: #000000;">0</span>,  <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">#00000000 none</span>
      <span style="color: #000000;">2500</span>: <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">255</span>,  <span style="color: #000000;">0</span>,  <span style="color: #000000;">0</span>,<span style="color: #000000;">255</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">#FF0000 red</span>
  Page geometry: 200x200+<span style="color: #000000;">0</span>+<span style="color: #000000;">0</span>
  Compression: Zip
  Properties:
    create-date: <span style="color: #000000;">2010</span>-04-13T00:<span style="color: #000000;">20</span>:<span style="color: #000000;">15</span>-03:00
    modify-date: <span style="color: #000000;">2010</span>-04-13T00:<span style="color: #000000;">20</span>:<span style="color: #000000;">15</span>-03:00
    signature: 0a42f3c85d6364e38f14dac554d26c62a90b84b06ac7f22264c9d964657ba8d6
  Tainted: False
  Filesize: 503b
  Number pixels: 39.1kb
  Version: ImageMagick 6.5.1-<span style="color: #000000;">0</span> <span style="color: #000000;">2009</span>-08-<span style="color: #000000;">27</span> Q16 OpenMP http:<span style="color: #000000; font-weight: bold;">//</span>www.imagemagick.org</pre></div></div>

<p>Probado en :</p>
<ul>
<li>Chromium 5.0.372.0 (44042) Ubuntu</li>
<li>Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9</li>
</ul>
<p>Código completo : <a href='http://www.gazer.com.ar/wp-content/uploads/2010/04/html5_canvas_submit.zip'>html5_canvas_submit</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/04/13/html5-guardar-el-contenido-de-canvas-en-el-servidor/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Casa y Casamiento</title>
		<link>http://www.gazer.com.ar/2010/04/09/casa-y-casamiento/</link>
		<comments>http://www.gazer.com.ar/2010/04/09/casa-y-casamiento/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 04:59:41 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Yo Estuve Ahí]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1239</guid>
		<description><![CDATA[Y si, volví para seguir molestando con cosas que a nadie le interesa . En los últimos meses han pasado tantas cosas que ya ni encuentro un rato para sentarme a escribir . Para empezar me volví a mudar, si, si, 4 mudanzas en 4 meses, espero que esta vez sea la definitiva. Ahora, y [...]]]></description>
			<content:encoded><![CDATA[<p>Y si, volví para seguir molestando con cosas que a nadie le interesa <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . En los últimos meses han pasado tantas cosas que ya ni encuentro un rato para sentarme a escribir <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p>Para empezar me <a href="http://www.gazer.com.ar/2010/01/13/ano-nuevo-vida-nueva/">volví</a> a mudar, si, si, 4 mudanzas en 4 meses, espero que esta vez sea la definitiva. Ahora, y después de 12 años, volví a mi Cipolletti &#8220;<em>natal</em>&#8220;, el que me vio hacer tantas cagadas de chico. Y más aún, volví al barrio donde viví toda mi secundaria (a menos de 100 mts de la casa donde vivíamos con mis viejos por esa época), toda una regresión <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Pero la cosa siguió y finalmente llegamos vivos al casamiento con mi (ex) novia y me tuve que disfrazar de &#8220;empresario&#8221; para aparentar un poco frente a la familia. Siempre es bueno dar una buena impresión, pero a mi me suele alcanzar con que sea buena o mala <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p style="text-align: center;"><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c1.jpg"><img class="size-full wp-image-1241 alignnone" title="Empresariado" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c1.jpg" alt="" width="102" height="154" /> </a><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c2.jpg"><img class="alignnone size-full wp-image-1242" title="c2" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c2.jpg" alt="" width="231" height="154" /> </a><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c3.jpg"><img class="alignnone size-full wp-image-1243" title="c3" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c3.jpg" alt="" width="102" height="154" /></a></p>
<p>La fiesta fue, bueno, una fiesta, si me conocen saben como soy cuando hay joda, así que el resto se lo pueden imaginar. No faltó ni comida y mucho menos para tomar, barra libre, etc, etc &#8230; más de uno se fue gateando (yo volví manejando, para variar, en piloto automático). Cuando arrancó la joda, luego de que Nacho Morán (imitador/cantante de Choele Choel) hiciera su gracia, se armó alto bailongo, donde nadie se quedó sentado.</p>
<p style="text-align: center;"><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c4.jpg"><img class="alignnone size-full wp-image-1244" title="Nacho Moran" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c4.jpg" alt="" width="231" height="154" /></a> <a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c5.jpg"><img class="alignnone size-full wp-image-1245" title="Plena Joda" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c5.jpg" alt="" width="231" height="154" /></a></p>
<p>Más entrada la noche una mesa dulce para cortar un poco el alcohol y si te agarra el control de alcoholemia poder mentir que fue por metabolizar los dulces <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> , aunque hay que se realista, en Cipollettia las 8AM no hay controles <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> .</p>
<p style="text-align: center;"><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c6.jpg"><img class="alignnone size-full wp-image-1246" title="c6" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c6.jpg" alt="" width="217" height="144" /></a> <a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c7.jpg"><img class="alignnone size-full wp-image-1247" title="c7" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c7.jpg" alt="" width="217" height="144" /></a></p>
<p>Ya cuando los gallos empiezan a cantar empezamos a cerrar la joda con un foto de los valientes que duraron hasta el final.</p>
<p style="text-align: center;"><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c8.jpg"><img class="alignnone size-full wp-image-1248" title="c8" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c8.jpg" alt="" width="217" height="144" /> </a><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c9.jpg"><img class="alignnone size-full wp-image-1249" title="c9" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c9.jpg" alt="" width="217" height="144" /></a></p>
<p>Por último falta la luna de miel, que se da sobre fin de mes (nada de salir corriendo al otro día, hay que aprovechar las vacaciones <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ).</p>
<p>Ah, y por si todo fue muy sutil y no se notó en las fotos anteriores, pegue &#8220;<em>altas llantas</em>&#8221; esa noche <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.gazer.com.ar/wp-content/uploads/2010/04/c10.jpg"><img class="aligncenter size-full wp-image-1251" title="Altas llantas" src="http://www.gazer.com.ar/wp-content/uploads/2010/04/c10.jpg" alt="" width="266" height="400" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/04/09/casa-y-casamiento/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Apple iPad</title>
		<link>http://www.gazer.com.ar/2010/01/28/apple-ipad/</link>
		<comments>http://www.gazer.com.ar/2010/01/28/apple-ipad/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 22:11:10 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[ipod]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1233</guid>
		<description><![CDATA[Bueno, no voy a decir lo que ya todo el mundo ya debe haber leído (no multitask, es un iPod Touch grandote, solo con AT&#38;T bla bla bla) . http://www.youtube.com/watch?v=lQnT0zp8Ya4 Creo que eso resume más que bien lo que la mayoría de los no-fan de Apple piensan cuando leen la ficha técnica .]]></description>
			<content:encoded><![CDATA[<p>Bueno, no voy a decir lo que ya todo el mundo ya debe haber leído (no multitask, es un iPod Touch grandote, solo con AT&amp;T bla bla bla) <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p style="text-align: center;">
<p><a href="http://www.youtube.com/watch?v=lQnT0zp8Ya4">http://www.youtube.com/watch?v=lQnT0zp8Ya4</a></p>
</p>
<p>Creo que eso resume más que bien lo que la mayoría de los no-fan de Apple piensan cuando leen la ficha técnica <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/01/28/apple-ipad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrando datos desde PHP a Rails</title>
		<link>http://www.gazer.com.ar/2010/01/22/migrando-datos-desde-php-a-rails/</link>
		<comments>http://www.gazer.com.ar/2010/01/22/migrando-datos-desde-php-a-rails/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 20:02:41 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[active record]]></category>
		<category><![CDATA[migracion]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1227</guid>
		<description><![CDATA[Por esas cosas de la vida me encontré todo el día de hoy migrando datos viejos de un sistema hecho en PHP a uno hecho en Rails. Las cosas venían bastante simples definiendo modelos de ActiveRecord para las tablas de la base de datos vieja y reinsertando con modelos apuntando a las tablas nuevas. Pero [...]]]></description>
			<content:encoded><![CDATA[<p>Por esas cosas de la vida me encontré todo el día de hoy migrando datos viejos de un sistema hecho en PHP a uno hecho en Rails. Las cosas venían bastante simples definiendo modelos de ActiveRecord para las tablas de la base de datos vieja y reinsertando con modelos apuntando a las tablas nuevas. Pero &#8230; siempre hay un pero.</p>
<p>Resulta que el hermoso sistema anterior para evitar tener muchas tablas (o vaya a saber por qué) tenía en una parte un tabla donde cada field era un gran TEXT que contenía un array de PHP <a href="http://php.net/manual/en/function.serialize.php" target="_blank">serializado</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> UserTextField <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  set_table_name <span style="color:#996600;">&quot;usertextfield&quot;</span>
  set_primary_key <span style="color:#996600;">&quot;userid&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> folders
    field3
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
$<span style="color:#006600; font-weight:bold;">&gt;</span> user = UserTextField.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
$<span style="color:#006600; font-weight:bold;">&gt;</span> user.<span style="color:#9900CC;">folders</span> <span style="color:#008000; font-style:italic;"># =&gt; 'a:2:{i:0;s:4:&quot;bkps&quot;;i:1;s:6:&quot;listas&quot;;'</span></pre></div></div>

<p>Justo cuando estaba por ponerme a parsear texto me encontré con <a href="http://github.com/jqr/php-serialize">php-serialize</a> que permite serializar y deserializar estos string en cómodos tipos nativos de Ruby.</p>
<p>El código final queda entonces algo como :</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> UserTextField <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  set_table_name <span style="color:#996600;">&quot;usertextfield&quot;</span>
  set_primary_key <span style="color:#996600;">&quot;userid&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> folders
    PHP.<span style="color:#9900CC;">unserialize</span><span style="color:#006600; font-weight:bold;">&#40;</span>field3<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
$<span style="color:#006600; font-weight:bold;">&gt;</span> user = UserTextField.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
$<span style="color:#006600; font-weight:bold;">&gt;</span> user.<span style="color:#9900CC;">folders</span> <span style="color:#008000; font-style:italic;"># =&gt; [&quot;bkps&quot;, &quot;listas&quot;]</span></pre></div></div>

<p>Y la migración de datos pudo continuar sin problemas <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/01/22/migrando-datos-desde-php-a-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Audacity en Paranormal Activity</title>
		<link>http://www.gazer.com.ar/2010/01/14/audacity-en-paranormal-activity/</link>
		<comments>http://www.gazer.com.ar/2010/01/14/audacity-en-paranormal-activity/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 18:46:10 +0000</pubDate>
		<dc:creator>Gazer</dc:creator>
				<category><![CDATA[Cine]]></category>
		<category><![CDATA[GNU+Linux]]></category>

		<guid isPermaLink="false">http://www.gazer.com.ar/?p=1220</guid>
		<description><![CDATA[La película es muy mala (no puedo creer que tenga casi 7 puntos en IMDB), pero mientras iba adelantandola a ver si pasaba algo me encontré que el protagonista usa Audacity para filtrar los ruidos de los &#8220;espíritus&#8221; : Ahora por lo menos se que con software libre puedo investigar los ruidos misteriosos de una [...]]]></description>
			<content:encoded><![CDATA[<p>La <a href="http://www.paranormalactivity-movie.com/">película</a> es muy mala (no puedo creer que tenga <a href="http://www.imdb.com/title/tt1179904/">casi 7 puntos en IMDB</a>), pero mientras iba adelantandola a ver si pasaba algo me encontré que el protagonista usa <a href="http://audacity.sourceforge.net/?lang=es">Audacity</a> para filtrar los ruidos de los &#8220;espíritus&#8221; :</p>
<p><a href="http://www.gazer.com.ar/wp-content/uploads/2010/01/Screenshot-PA.png"><img class="aligncenter size-full wp-image-1221" title="Screenshot-PA" src="http://www.gazer.com.ar/wp-content/uploads/2010/01/Screenshot-PA.png" alt="" width="491" height="267" /></a></p>
<p>Ahora por lo menos se que con software libre puedo investigar los ruidos misteriosos de una casa <img src='http://www.gazer.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gazer.com.ar/2010/01/14/audacity-en-paranormal-activity/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

