Spiga

Lima Agile Day 2010

April 20, 10 by Pedro Hernández

El sábado pasado (17 de abril) se celebró por segundo año consecutivo el “Lima Agile Day” en su edición 2010.

Ha sido toda una experiencia tanto organizarla como exponer en él, con el tema de “Visual Management”. Una de las técnicas que he estado usando en diferentes trabajos después del Cerfied ScrumMaster y que me ha ayudado muchísimo al momento de transmitir y poner en práctica Scrum.

El programa del evento fue el siguiente:

En esta ocasión compartimos experiencias con Heitor y Marco de Scrum Amazonia. Ambas exposiciones fueron enriquecedoras por las experiencias que compartieron.

Debo de destacar la presentación Abner, la cual me sorprendió por el gran uso de storytelling en su tema técnico.

Este evento fue todo un reto, no pudo ser posible sin el apoyo de Gustavo Quiroz, Gustavo Veliz y Jersson Dongo. Grandes amigos que me dieron la oportunidad de participar y estar en todo momento. Muchas gracias. Gracias también a los Auspiciadores, a todos los chicos y chicas que se ofrecieron para el apoyo ya que sin ellos no hubiese sido posible el desarrollo del evento y sobre todo a los asistentes.

Esto ha sido una pequeña muestra de lo que podemos lograr, nos volveremos a ver en Ágiles 2010 que este año se realiza en Lima, Perú.

PD: Les dejo mi presentación.

Dailymotion creado con Symfony framework

February 24, 09 by Pedro Hernández

Así es y se me había pasado publicar esta gran noticia, el sitio http://www.dailymotion.com/ ha sido desarrollado con el framework Symfony. Pueden ver el resto de las notas en el sitio oficial: Dailymotion, powered by symfony, y en español aqui: Dailymotion también utiliza Symfony.

Instalando mod_top en Centos 5.x

February 16, 09 by Pedro Hernández

En casa y en la agencia donde trabajo usamos como sistema operativo para los servidores Centos y como desde hace un tiempo vengo viendo el tema de monitorizar para mejorar la performance de las aplicaciones que desarrollo me decidí a probar mod_top. Esta herramienta corriendo en centos es gracias al soporte de Red Hat Enterprise Linux (RHEL) 4 o 5.

De momento mod_top solo da soporte a las siguiente versiones de PHP: 4.4x, 5.1.x, 5.2.x. Aunque piensan hacerlo además para: Perl, Ruby, Python, mySQL, Postgres, Apache1+2.

Pues bien ¿y qué se pude hacer con esta herramienta?, como ellos lo definen:

  • Localizar cuellos de botella en las aplicaciones.
  • Solucionar problemas gran consumo de memoria.
  • Comprender el uso de la CPU con carga.
  • Diagnosticar las causas de lentitud o la utilización de los recursos.
  • Descubrir las dependencias de la base de datos.
  • Impresionar a sus amigos con su eficiente código escalable.

Instalando mod_top

Para comenzar necesitamos descargar la versión compatible con nuestro PHP.  En mi caso descargué la versión 0.5 (la última a la fecha 2008/02/14) con soporte para PHP  v5.2.x y arquitectura i686. Yo suelo descargar las librerías aquí:

# cd /usr/local/src

Descomprimimos y guardamos su contenido en /opt/mod_top:

# mkdir /opt/mod_top

En este caso el archivo es mod-top-0.5-php52-i686.tar.gz:

# tar -xvzf mod-top-0.5-php52-i686.tar.gz -C /opt/mod_top

Terminado esto toca instalar las librerías Lamp1701 como muestra la documentación…

lib/liblamp1701read.so      - lamp1701 libraries
    liblamp1701utils.so
    liblamp1701write.so
    liblamp1701read.so.0    - shared object name links
    liblamp1701utils.so.0
    liblamp1701write.so.0

… en la carpeta /usr/lib o /usr/lib64 si fuese el caso:

# ln -s /opt/mod_top/mod-top-0.5-php52-i686/lib/liblamp1701*.0 /usr/lib

Instalando la extensión en PHP

Se crea un enlace simbólico del archivo php/lamp1701.so (que en este caso está en /opt/mod_top/mod-top-0.5-php52-i686/) en la carpeta de módulos de PHP (en este caso /usr/lib/php/modules):

# ln -s /opt/mod_top/mod-top-0.5-php52-i686/php/lamp1701.so /usr/lib/php/modules

Ahora a activar la extensión en el php.ini:

# cd /etc/php.d/
# vim mod_top.ini

Dentro del archivo agregamos:

; Enable lamp1701 extension module
extension=lamp1701.so

Ejecutando mod_top

Lo primero es iniciar lamp1701d que se encuentra en sbin/lamp1701d:

# cd /opt/mod_top/mod-top-0.5-php52-i686/sbin
# ./lamp1701d

Ahora ejecutar mod_top:

# cd /opt/mod_top/mod-top-0.5-php52-i686/bin
# ./mod_top -s 127.0.0.1

Una vez ejecutandose este proceso no podremos usar más esta terminal, si no únicamente para monitorizar.

En otra terminal

Verificamos que el proceso mod_top se esté ejecutando:

# ps aux | grep -i mod_top
root      6956  0.2  0.3   4044  2924 tty1     S+   10:43   0:00 ./mod_top -s 127.0.0.1
root      6970  0.0  0.0   3976   744 pts/0    R+   10:44   0:00 grep -i mod_top

Finalmente toca iniciar o reiniciar apache:

# apachectl start

Ahora ejecuta algún proyecto que tengas en php y comenzaras a ver los resultados como se muestra aquí, sobre todo resulta interesante cuando lo usas con symfony.

Saludos.

BarCamp Lima 2008

October 29, 08 by Pedro Hernández

Pués sí, todo comenzó en uno de los post de la Asociación Nacional de Webmasters Perú y luego César Soplín completó la idea de armar el BarCamp Lima 2008, un evento donde todos están invitados, y sobre todo “no hay turistas”.

El primer encuentro es el sábado 8 de noviembre, y pronto en el wiki del evento estará listo el lugar.

La expectativa es grande y espero conocer a todos los asistentes :)

Usando AMFPHP v1.9b2 con symfony 1.0.x

October 22, 08 by Pedro Hernández

Hace poco se me dió la oportunidad de comenzar un proyecto que requeria comunicación desde la parte de frontend el usar Flash v9.

Como se esta usando symfony comencé a buscar en el repositorio oficial de symfony si habia ya un plugin que integrara AMF, y efectivamente encontré uno: sfAmfPlugin, el problema es que usa SabreAMF que funciona a partir de la versión 5.1 de php y el cliente de este proyecto solo nos proporciona php v5.0 y el mas cercano compatible con esta versión es AMFPHP.

Luego buscando entre el repositorio antiguo de symfony descubrí que alguien ya habia implementado amfphp con symfony, este plugin es: sfAmfphpPlugin; pero la version que usa de AMFPHP es la 1.2, que fue liberada en el 2006.

Partiendo de su proyecto es que he realizado mejoras, usando la ultima version de AMFPHP: v1.9 beta 2 liberada el 2008-01-20. Entre estas mejoras se encuntran:

  • Usa la versión más actual de AMFPHP (1.9 beta2).
  • Este plugin trae un modulo que permite habilitarce desde cualquier aplicación para poder acceder al gateway o el browser.
  • Se puede acceder al browser de clases que trae hecho en flex.
  • Por seguridad no se puede acceder al browser desde un site en producción, pero el gateway se puede acceder libremente.

Para poder usar el plugin debes de hacer lo siguiente:

  1. Crea un proyecto nuevo en symfony, en este caso la ultima version de symfony de la rama 1.0.x es la 1.0.18.
    .
  2. Descarga el plugin que dejo más abajo. De momento no esta en el site oficial de symfony debido a que su creador recién se entera de él :P .
    .
  3. Instala el plugin via PEAR como se menciona en el listado 17-16 del libro oficial. Durante ese paso se copiará la carpeta web del plugin a la carpeta web de tu proyecto, solo dejalo así por que alli se encuentra el browser del AMFPHP.
    .

    >> plugin    installing web data for plugin
    >> dir+      D:\www\sf10-dev\web\sfAmfphpPlugin\swf
    >> dir+      D:\www\sf10-dev\web\sfAmfphpPlugin\swf\browser
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlugin\swf\browser\AC_OETags.js
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlugin\swf\browser\history.js
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlugin\swf\browser\history.swf
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlugin\swf\browser\index.html
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlu...rowser\playerProductInstall.swf
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlu...swf\browser\servicebrowser.mxml
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlu...\swf\browser\servicebrowser.swf
    >> file+     D:\www\sf10-dev\web\sfAmfphpPlu...swf\browser\services-config.xml

    .

  4. Ahora habilita los modulos del plugin en la aplicacion que gustes desde su settings.yml:
    .

    all:
      .settings:
        # Activated modules from plugins or from the symfony core
        enabled_modules:        [default, sfAmfphpModule]

    .

  5. Ahora agrega las nuevas rutas a tu aplicación desde el routing.yml:
    .

    sf_amfphp_gateway:
      url:   /amfphp/gateway
      param: { module: sfAmfphpModule, action: gateway }
    
    sf_amfphp_browser:
      url:   /amfphp/browser
      param: { module: sfAmfphpModule, action: browser }

    .

Si ahora intentas ingresar a por ejemplo: http://www.myproj.com/frontend_dev.php/amfphp/gateway. Te deberia salir la pagina clasica de AMFPHP diciendo que se instaló correctamente.

Ahora si ingresas a: http://www.sf10-dev.com/frontend_dev.php/amfphp/browser, (recuerda que el browser solo se puede ver desde un entorno de desarrollo) este fallará al cargar debido a que no encuentra la carpeta services.

Para esto entra a la carpeta lib del plugin y copia la carpeta services, finalmente pegala en el lib de tu proyecto. Ahora si vuelve a cargar el browser de AMFPHP y veras los resultados ;) .

Dejo en descarga el plugin aquí y un proyecto con los ejemplo que vienen para la ultima versión de AMFPHP.

Saludos.

Unknown channel “pear.symfony-project.com” al tratar de contruir plugins en symfony

October 20, 08 by Pedro Hernández

Sucede que desde hace un tiempo tengo symfony instalado via SVN (Subversion, pronto haré un tutorial sobre ello), y tratando de empaquetar un plugin me doy con la grata sorpresa de este error:

> pear package
Error: Unknown channel "pear.symfony-project.com"
Parsing of package.xml from file "package.xml" failed
Cannot package, errors in package file

La solución fue simple, era nada más de agregar el canal pear de symfony al channel-discover como si de instalar symfony via PEAR se tratase (pero solo esto, recordar que ya lo tengo instalado via SVN):

> pear channel-discover pear.symfony-project.com
Adding Channel "pear.symfony-project.com" succeeded
Discovery of channel "pear.symfony-project.com" succeeded

Ahora si intentas empaquetar el plugin todo será perfecto :D :

> pear package
Package sfTestPlugin-1.0.1.tgz done

Por cierto, a la hora de construir un plugin te vendria bien usar el plugin sfPluginManagerPlugin, puedes ver en el repositorio del plugin como lo usan.

Saludos :)

pyExcelerator y sus errores con el “test del ñandú”

September 12, 08 by Pedro Hernández

En estos momentos me encuentro terminando la parte de exportación a excel de unos reportes y como se eligió la libreria pyExcelerator para hacerlo, me tocó encontrar un detallito al momento de hacerle un test del ñandú.

Si probamos algo simple como:

from pyExcelerator import *

wb = Workbook()
ws0 = wb.add_sheet('0')

ws0.write(1, 1, "test del ñandú")

wb.save('output.xls')

Esto falla dandome como error lo siguiente:

SyntaxError: Non-ASCII character '\xc3' in file excel.py on line 6, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

Ahora si probamos (notese que solo agregé la u de unicode):

from pyExcelerator import *

wb = Workbook()
ws0 = wb.add_sheet('0')

ws0.write(1, 1, u"test del ñandú")

wb.save('output.xls')

El mismo error que el de la primera prueba, para solucionarlo le agregamos la siguiente cabecera: # -*- coding: utf-8 -*-

# -*- coding: utf-8 -*-
from pyExcelerator import *

wb = Workbook()
ws0 = wb.add_sheet('0')

ws0.write(1, 1, u"test del ñandú")

wb.save('output.xls')

Por cierto, esta libreria no tiene documentación, pero pueden guiarce de este post y de algunas cosas de mi delicious.

Y listo, salu2.

Recuperando registros separados por coma en MySQL

August 24, 08 by Pedro Hernández

Hace un tiempo un compañero de trabajo encontró un funcion en MySQL que ha resultado bastante util, la función se llama GROUP_CONCAT() y se encuentra disponible desde la version 4.1, la cual nos permite recuperar registros separados por algún simbolo, en este caso separado por comas.

Por ejemplo, si tuvieramos la tabla cars, un listado simple del mismo podría ser:

Listado simple de la tabla cars

Listado simple de la tabla cars

Separar estos tres por comas para que aparescan en una sola fila seria:

Usando GROUP_CONCAT()

Usando GROUP_CONCAT()

Sus usos son muchos, como por ejemplo el de imprimir los tags de tus favoritos como lo hace delicious.com

Saludos :)

El regreso…

August 16, 08 by Pedro Hernández

No se cuantas veces he puesto en este blog que he regresado … despues de tiempo, pero al menos trataré de poner un post semanal ^^.

Pues bien, desde el 4 de febrero de este año ingresé a trabajar a una empresa de marketing interactivo en la ciudad de Lima y este hecho a consumido gran parte de mi tiempo. Ahora más organizado es cuando decido volver.

He visto que mis posts más vistos son los de instalar pear y symfony cosa que me agrada mucho :D .

En todo este tiempo de ausencia es que he aprendido más sobre php, symfony, python, django y mysql; cosas que postearé en su momento. He cambiado el slogan del blog (si asi se puede decir), colocando: “Desarrollo web, Inteligencia artificial y otras paranoias”; y es que de inteligencia artificial me gustaría ir aprendiendo también :) .

Algo que me gusto en todo este tiempo es que en Julio se lanzó Stones Throw Records. Un site en el colaboré junto con Roberto Carvajal y Jon Bauher. Por cierto este sitio está hecho en Symfony :D .

Antes de terminar agradecer mucho a todas las personas que preguntaron que le pasó al blog y del por que no posteaba, a todos los que me han enviado mails colaborando con los plugins que he desarrollado para Symfony y a Mauro Casuola, quien se integra para ayudarme a desarrollar mi plugin sfCssTabs.

Saludos y gracias.

Redirección 301 en Symfony: filtros vs htaccess

January 27, 08 by Pedro Hernández

Este tema salio de una urgencia que tubo mi buen amigo Joan y como ya antes en la lista de symfony en español se había preguntado, salio la idea de resolverlo a modo de competencia. Por mi parte como Filtro de Symfony y por la parte de Joan con htaccess.

¿Para que sirven estas soluciones?
Pues bien en Symfony por defecto las URI no terminan en slash (por temas SEO), es decir si terminan en algo así: www.site.com/moudulo/, esto te retornará un 404. Para evitar este problema y hacer una redirección 301 de www.site.com/moudulo/ a www.site.com/moudulo aquí las soluciones:

Con un filtro en symfony:
Solo colócalo en la carpeta lib de tu aplicación

<?php
class redirect301Filter extends sfFilter
{
  public function execute($filterChain)
  {
    if ($this->isFirstCall())
    {
      $uri = $this->getContext()->getRequest()->getUri();

      if (preg_match('#/$#', $uri))
      {
        $uri = preg_replace('#/$#', '', $uri);
        $this->getContext()->getController()->redirect($uri, 301);
      }
    }

    // Ejecutar el proximo filtro
    $filterChain->execute();
  }
}

Y activas el filtro así:

sshot-2008-01-27-02-11-27.png

Ahora la versión de Joan con htaccess:

Options +FollowSymLinks +ExecCGI

<IfModule mod_rewrite.c>
  RewriteEngine On

  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  RewriteBase /

  # we skip all files with .something
  RewriteCond %{REQUEST_URI} \..+$
  RewriteCond %{REQUEST_URI} !\.html$
  RewriteRule .* - [L]

  # remove trailing slash
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} ^(.*)/$
  RewriteRule ^(.*)/$ $1 [R=302,L]

  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]
  RewriteCond %{REQUEST_FILENAME} !-f

  # no, so we redirect to our front web controller
  RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

# big crash from our front web controller
ErrorDocument 500 "<h2>Application error</h2>symfony application failed to start properly"

Para este caso (y como lo comenta Joan) el RewriteBase / es obligatorio si te quieres evitar problemas.

En las pruebas de rendimiento obviamente htaccess sale ganando, pero queda de tu parte elegir cual usar :) .

Si no es del todo legible el código colocado mas arriba (comienzo a odiar al iG:Syntax Hiliter) puedes descargarlo de aquí filtro_vs_htaccess.zip.