<?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>alejandro corpeño &#187; programación</title>
	<atom:link href="http://alejandro.corpeno.com/tag/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://alejandro.corpeno.com</link>
	<description>web - programación - arte - negocios</description>
	<lastBuildDate>Thu, 26 Aug 2010 07:33:23 +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>miCajita.com &#8211; Hace casi 10 años</title>
		<link>http://alejandro.corpeno.com/2009/11/18/micajita-com-hace-10-anos/</link>
		<comments>http://alejandro.corpeno.com/2009/11/18/micajita-com-hace-10-anos/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 01:15:01 +0000</pubDate>
		<dc:creator>corp</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://alejandro.corpeno.com/?p=108</guid>
		<description><![CDATA[Hace unas semanas estaba buscando un archivo antiguo en un disco duro de backup y encontré el folder de mi proyecto de graduación de la Universidad. En el año 2000 registré el dominio miCajita.com y hospedé allí mi proyecto para la presentación a la terna de graduación, pero despues de unos meses no continué el proyecto ni volví a renovar dominio... hoy es un proyecto muerto.]]></description>
			<content:encoded><![CDATA[<p><a href="http://alejandro.corpeno.com/wp-content/uploads/2009/11/micajita-home.gif"><img class="aligncenter size-full wp-image-114" title="MiCajita.com (2000)" src="http://alejandro.corpeno.com/wp-content/uploads/2009/11/micajita-home-thumb.gif" alt="MiCajita.com (2000)" width="450" height="225" /></a></p>
<p>Hace unas semanas estaba buscando un archivo antiguo en un disco duro de backup y encontré el folder de mi proyecto de graduación de la Universidad. En el año 2000 registré el dominio miCajita.com y hospedé allí mi proyecto para la presentación a la terna de graduación, pero despues de unos meses no continué el proyecto ni volví a renovar dominio&#8230; hoy es un proyecto muerto.</p>
<p>Fue mi segunda aplicación web en PHP/MySQL, unos meses antes había desarrollado junto a <a href="http://www.twitter.com/rbreve">@rbreve</a> un portal multiservicios llamado SiliconAlien, proyecto que hoy tampoco existe (<a href="http://web.archive.org/web/20010418151651/http://www.siliconalien.com/">siliconalien en archive.org</a>)</p>
<h2><strong>En que consistía?</strong></h2>
<p>La idea de miCajita era simple y apta para aquellos días en que no existía Gmail y las cuentas de correo gratuitas (e incluso las pagadas) tenían límites de espacio demasiado bajas.</p>
<p>En esos días era muy común que uno no podía enviar correos con attachments de más de 1MB porque posiblemente la casilla de el receptor estaba llena. miCajita era una solución en que cada usuario podía crear su cuenta de 10 a 100MB de espacio para subir archivos que quisiera tener disponibles para compartir con otros.</p>
<p>El sistema incluía opciones como:</p>
<ul>
<li>File Manager web con folders públicos y privados</li>
<li>Control de accesos para lectura y escritura a nivel de archivo y folder para usuarios individuales y grupos</li>
<li>Envío de archivos desde miCajita hacia direcciones de email</li>
</ul>
<h2><strong>Por qué murió?</strong></h2>
<p>Era un proyecto que inicié por razones académicas (para graduarme) y en esos días estaba más metido en la onda de iniciar mi  empresa de consultoría, desarrollando websites para clientes.</p>
<p>Me pasó por la mente lanzarlo públicamente pero le tuve miedo a varios aspectos como:</p>
<ul>
<li><strong>Competencia existente: </strong>servicios como <a href="http://www.xdrive.com/">Xdrive</a>, el cual hasta tenía un software instalable para integrase al File Explorer de Windows, creando un disco virtual al podías drag and drop archivos para subirlos.</li>
</ul>
<ul>
<li><strong>Falta de dinero: </strong>me preocupaba el costo de hosting, ya que el plan era regalar unos 100MB por usuario si lanzaba el servicio al público. En ese entonces el hosting era más caro que ahora y no tenía fondos propios para soportar el costo.</li>
</ul>
<ul>
<li><strong>Falta de interés: </strong>los dos factores anteriores hicieron que mi interés por lanzar el proyecto públicamente muriera. Si volviera al pasado, posiblemente hubiera seguido con el proyecto buscando apoyo financiero externo&#8230;</li>
</ul>
<h2><strong>Lo positivo&#8230;</strong></h2>
<p>Creo que todo proyecto y experiencia en la vida deja algo positivo.<br />
De este proyecto puedo mencionar unas cuantas consecuencias positivas:</p>
<ul>
<li><strong>Aprendizaje: </strong>siendo uno de mis primeros proyectos de desarrollo web aprendí mucho en un tiempo bastante corto. Esto me sirvió en mi objetivo de desarrollo profesional como consultor y empresario.</li>
</ul>
<ul>
<li><strong>Dinero: </strong>Fue la base de un sistema privado de folders compartidos que vendimos a varios clientes para sus intranets. Logré monetizar el tiempo invertido en la programación vendiendolo al menos 10 veces y creando un buen nombre para mi empresa.</li>
</ul>
<ul>
<li><strong>Quedar con ganas de hacer más: </strong>el haber realizado el proyecto y seguirle los pasos a los servicios similares que existían en ese momento me hizo ver (a la larga) que las buenas ideas surgen y evolucionan rápidamente&#8230; me dejó <a href="http://www.tubabel.com/definicion/28093-picado" target="_self">picado</a> por intentar nuevamente con proyectos propios.</li>
</ul>
<h2><strong>Documentación</strong></h2>
<p>En el folder del backup que mencioné al inicio encontré dos documentos relevantes:</p>
<ul>
<li><a href="http://alejandro.corpeno.com/wp-content/uploads/2009/11/ManualdeUsuario-micajita.pdf">Manual de Usuario</a> &#8211; <span style="color: #888888;">350 KB</span></li>
<li><a href="http://alejandro.corpeno.com/wp-content/uploads/2009/11/ManualdeTecnico-micajita.pdf">Manual de Técnico</a> &#8211; <span style="color: #888888;">569 KB</span></li>
</ul>
<p>Son suvenirs de hace 10 años&#8230; mucho ha cambiado desde ese momento y si volviera a programar el sistema lo haría completamente de otra forma, pero allí les dejo para quienes tengan curiosidad de leer más acerca de lo que fue miCajita en su momento.</p>
]]></content:encoded>
			<wfw:commentRss>http://alejandro.corpeno.com/2009/11/18/micajita-com-hace-10-anos/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Leyendo APIs desde Rails</title>
		<link>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/</link>
		<comments>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 23:12:01 +0000</pubDate>
		<dc:creator>corp</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[apis]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://alejandro.corpeno.com/?p=117</guid>
		<description><![CDATA[Esta semana tuve que integrar un sitio hecho en Rails con el API de wine.com. Mientras esta aplicación está en desarrollo se hospeda en un grid container pequeño de media temple.

Todo estaba funcionando bien en mi computadora cuando hice la integración usando el gem "hpricot", pero al subirlo al grid container tuve problemas. El log de Rails indicaba que el archivo hpricot_scan.so no era accesible.]]></description>
			<content:encoded><![CDATA[<p>Esta semana tuve que integrar un sitio hecho en Rails con el <a href="http://api.wine.com/wiki/api-object-dictionary">API de wine.com</a>. Mientras esta aplicación está en desarrollo se hospeda en un <a href="http://mediatemple.net/webhosting/gs/features/containers.php#ror" target="_blank">grid container</a> pequeño de media temple.</p>
<p><strong>El problema&#8230;</strong></p>
<p>Todo estaba funcionando bien en mi computadora cuando hice la integración usando el gem &#8220;hpricot&#8221;, pero al subirlo al grid container tuve problemas. El log de Rails indicaba que el archivo hpricot_scan.so no era accesible.</p>
<p>Encontré la solución <a href="http://www.cherpec.com/2009/06/hpricot-081-on-ruby-185/" target="_blank">en un blog</a>, el problema era que la versión de Ruby bajo la que operan los grid containers es la 1.8.5 y para esta versión hay unos problemas que requiren que se modifique el código fuente del gem.</p>
<p>OK, procedí a hacer los cambios en el código fuente tal como dice el artículo, pero me surgió otro problema&#8230;</p>
<pre><span style="color: #ff0000;">/usr/lib/ruby/1.8/fileutils.rb:754: command not found: ragel -v</span></pre>
<p>El  &#8220;rake&#8221; para regenerar el gem con los cambios requería &#8220;ragel&#8221; en el servidor&#8230;</p>
<p>Ya que los containers son pedazos virtuales de una maquina, no tengo acceso root para instalar nuevos paquetes, esto me impidió solucionar el problema:</p>
<ul>
<li>Instalando una versión más nueva de Ruby, por ejemplo 1.8.6 o 1.8.7</li>
<li>Instalando Ragel y completar el proceso de regenerar la gem hpricot</li>
</ul>
<p>Otra opción era pasar todo a un servidor dedicado y volver a preparar el ambiente de desarrollo, pasar la base de datos, etc&#8230; esto es factible pero no cuando necesito que mi cliente vea el update mañana.</p>
<p>La otra opción era hacer la integración nuevamente con algo diferente a  hpricot&#8230; opte por esta.</p>
<p><strong>La Solución</strong></p>
<p>Encontré <a href="http://railstips.org/2008/8/12/parsing-xml-with-ruby">un blog post</a> que compara tres formas de leer XML desde Rails&#8230; este me salvó ya que pude hacer la integración utilizando un método que no requiere librerías externas.</p>
<p>El artículo compara <a href="http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html">REXML</a>, <a href="http://wiki.github.com/hpricot/hpricot">Hpricot</a> y <a href="http://libxml.rubyforge.org/">libxml-ruby</a> &#8230; de todas la más lenta es REXML, pero es la que no depende de librerías externas y por lo tanto la que termine utilizando (probé con libxml pero tuve un problema similar).</p>
<p>Claro que esta es una solución temporal, solo para que mi contraparte en el proyecto pueda ver el avance.</p>
<p><strong>Ejemplo de Uso de REXML<br />
</strong></p>
<p>La solución con REXML es fácil de implementar y quiero compartirla en caso que alguien necesite leer XMLs desde una aplicación de Rails sin necesidad de usar librerías separadas.</p>
<p>Para el ejemplo usaremos el API de Twitter&#8230; este es el XML de mi timeline: <a href="http://twitter.com/statuses/user_timeline/corp.xml">http://twitter.com/statuses/user_timeline/corp.xml</a></p>
<p>Primero crearemos una función que recibe como parametro el usuario de twitter que queremos consultar, luego lee el XML correspondiente, lo almacena en un arreglo llamado <strong>twitts </strong>y lo devuelve con <strong>return twitts</strong>:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> get_twitts<span class="br0">&#40;</span>user<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;apiurl = <span class="st0">&quot;http://twitter.com/statuses/user_timeline/#{user}.xml&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;url = <span class="kw4">URI</span>.<span class="me1">parse</span><span class="br0">&#40;</span>apiurl<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;request = <span class="re2">Net::HTTP::Get</span>.<span class="me1">new</span><span class="br0">&#40;</span>apiurl<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;response,body = <span class="re2">Net::HTTP</span>.<span class="me1">new</span><span class="br0">&#40;</span>url.<span class="me1">host</span>, url.<span class="me1">port</span><span class="br0">&#41;</span>.<span class="me1">start</span> <span class="br0">&#123;</span>|http| http.<span class="me1">request</span><span class="br0">&#40;</span>request<span class="br0">&#41;</span> <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;twitts=<span class="br0">&#91;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;doc = <span class="re2">REXML::Document</span>.<span class="me1">new</span><span class="br0">&#40;</span>body<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;doc.<span class="me1">elements</span>.<span class="me1">each</span><span class="br0">&#40;</span><span class="st0">&#8216;statuses/status&#8217;</span><span class="br0">&#41;</span> <span class="kw1">do</span> |s|</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;h = <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;%w<span class="br0">&#91;</span>created_at text source<span class="br0">&#93;</span>.<span class="me1">each</span> <span class="kw1">do</span> |a|</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;h<span class="br0">&#91;</span>a.<span class="me1">intern</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span>a<span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;h<span class="br0">&#91;</span><span class="re3">:screen_name</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;user&#8217;</span><span class="br0">&#93;</span>.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;screen_name&#8217;</span><span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;h<span class="br0">&#91;</span><span class="re3">:profile_image_url</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;user&#8217;</span><span class="br0">&#93;</span>.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;profile_image_url&#8217;</span><span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;twitts &lt;&lt; h</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">return</span> twitts</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>Ahora ya podríamos usar esta función en nuestro controller, enviandole el usuario como parámetro.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> show_mytwitts</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re1">@twitts</span> = get_twitts<span class="br0">&#40;</span><span class="st0">&quot;corp&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>Para mostrar los twitts que almacenamos en el controller, la vista sería algo así:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&lt;%<span class="kw1">for</span> twitt <span class="kw1">in</span> <span class="re1">@twitts</span> do%&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;img src=<span class="st0">&quot;&lt;%=twitt[:profile_image_url]%&gt;&quot;</span> width=<span class="st0">&quot;25&quot;</span> /&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;strong&gt;&lt;%=twitt<span class="br0">&#91;</span><span class="re3">:screen_name</span><span class="br0">&#93;</span>%&gt;:&lt;/strong&gt; &lt;%=twitt<span class="br0">&#91;</span><span class="re3">:text</span><span class="br0">&#93;</span>%&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; Enviado desde &lt;%=twitt<span class="br0">&#91;</span><span class="re3">:source</span><span class="br0">&#93;</span>%&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;hr /&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;%end%&gt;</div>
</li>
</ol>
</div>
<p><strong>Conclusión</strong></p>
<p>Hay muchas formas de leer XML desde Rails, de hecho las mejores y más elegantes facilitan mucho más el acceso a los datos por medio de integración con los modelos.</p>
<p>Lo que pude implementar con REXML es una solución rápida y simple que sirve para la etapa en que estas en desarrollo y para que tu cliente (socio o contraparte) pueda ver los resultados de la integración al API deseado.</p>
<p>Para producción conviene utilizar soluciones más eficientes. Mientras investigaba encontré esta presentación que describe muchas formas elegantes y más eficientes de leer XML con Rails:</p>
<div id="__ss_955192" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Ruby Xml Mapping" href="http://www.slideshare.net/marc.seeger/ruby-xml-mapping-presentation">Ruby Xml Mapping</a><object style="margin:0px" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ruby-xml-mapping-1233006534538089-1&amp;stripped_title=ruby-xml-mapping-presentation" /><param name="allowfullscreen" value="true" /><embed style="margin:0px" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ruby-xml-mapping-1233006534538089-1&amp;stripped_title=ruby-xml-mapping-presentation" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/marc.seeger">Marc Seeger</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
