Cómo: Rootear (rooting) Android Acer Liquid Mini E310. HowTo

Quizá una de las tareas más útiles y al mismo tiempo más sencillas sobre un dispositivo android. Primero expliquemos un poco sobre lo que estamos hablando.

Rootear (obtener root o rooting) un teléfono es el proceso de modificar el sistema operativo que viene con tu dispositivo para obtener completo control sobre él. Esto implica que podrás superar las limitaciones que las operadoras y los fabricantes ponen en el teléfono, extender la funcionalidad del sistema, e incluso podrás actualizar a una versión personalizada de Android.

El nombre de root viene del mundo del sistema operativo Linux, donde el usuario con más privilegios en el sistema se llama root. Por razones principalmente de seguridad, por defecto el sistema trabaja bajo un usuario sin privilegios, pero luego del rooteo, el sistema podrá obtener o elevarse a privilegios de root cuando así se requiera. Mayormente por esto, con el rooteo se suele también incluir un programa que permite justamente esto, que se le otorguen a los permisos de root a cualquier servicio o aplicación que lo requiera. Uno de los más usados se llama superuser.

Una vez que sabemos lo que es el rooteo de un teléfono, indiquemos algunas de las razones por las cuales quisieras rootearlo:

  • Control total sobre Android
    Podrás tener acceso a modificar los archivos del sistema, temas de usuario, cambiar las imágenes de arranque, borrar aplicaciones de fábrica molestas, tales como AcerNidus, AcerMediaServer, RoadSync (para mi Acer Liquid Mini) y muchos otros similares que las operadoras y fabricantes te imponen en el teléfono para todas las marcas y modelos.
    Hay un montón de información en la web sobre cómo lograr esto , pero quizá la favorita es mediante Titanium Backup que permite la congelación / eliminación de las aplicaciones (el rooteo es necesario, por supuesto) aunque estas estén marcadas como de sistema.
  • Respaldar y Restaurar el sistema completo
    En la mayoría de sistemas Android podrás realizar un respaldo y restauración del sistema completo en una memoria SD. Para las marcas de dispositivos más populares, el método más sencillo es ROM Manager pues permite hacerlo todo con tan solo unos pocos clics en el propio teléfono. Pero no dispone de los paquetes necesarios para mi teléfono, además de que la versión gratuita del mismo tiene limitaciones que, entre otras cosas impiden el manejo de paquetes que no sean descargados con la propia aplicación.
    Para mi Acer Liquid Mini E310 (funciona también para otros de la misma serie Liquid, como el Liquid E y por cierto para casi cualquier otro teléfono), hay que ensuciarse un poco más las manos, pero tampoco es un proceso demasiado complejo. Se trata de reemplazar la imagen de “recovery” del teléfono, por una que te permitirá entre otras cosas, respaldar y restaurar el sistema completo. El procedimiento lo describo detalladamente en otro artículo.
  • Ahorrar espacio en el teléfono
    Aunque Google ya introdujo Apps2SD (mover partes de las aplicaciones a un almacenamiento externo) oficialmente en la actualización de Froyo, sigue estando en manos de los desarrolladores agregar manualmente el soporte para ello en sus aplicaciones. Debido a eso, todavía es bastante fácil quedarse cortos de espacio de almacenamiento en la memoria interna.
    La forma más sencilla de solucionar este problema y permitir que la mayoría de las aplicaciones se puedan mover a SD sería poner un ROM (muchos le dicen también Firmware) personalizado (a este proceso se le conoce como flash o flasheo del ROM o Firmaware) que permite precisamente eso. Por ejemplo, CyanogenMod, el más popular ROM personalizado de Android, permite al usuario forzar a la mayoría de las aplicaciones hacia la SD, incluso si los desarrolladores de esas aplicaciones no habilitaron esta característica. Hay que tener en cuenta que esto no funciona en todas las aplicaciones, en particular, los teclados y con aplicaciones de widgets.
  • Ejecutar aplicaciones especiales
    Existe una enorme variedad de aplicaciones que extraen mucho más de tu teléfono al estar rooteado. La lista a continuación es sólo un extracto que nos puede dar una idea de lo que podemos obtener (todas se consiguen en el propio market/play):
  • Titanium Backup. Hablamos de esta más arriba.
  • ROM Manager. Hablamos de esta más arriba.
  • Shoot Me. Para sacar capturas de pantalla (screenshots) de tu android.
  • Juice Defender. Para configurar perfiles de ahorro de energía y mejorar la duración de la batería.
  • Root Explorer. Permite que navegues a través del sistema de archios de tu Android. Tiene opciones de visualización y edición de archivos también.
  • Quick Boot. Podrás apagar, reiniciar (en modo normal, bootloader, recovery) y resetear tu teléfono (hard reboot).
  • Shark for root. Si sabes lo que es y hace el WireShark, este es lo mismo pero para tu android. Si no lo sabes, seguramente no lo necesitas.
  • adbWireless. En la misma línea que el anterior: si sabes lo que es adb y para lo que sirve, este te permitirá lo mismo pero sin necesidad del cable USB. Si no lo sabes, seguramente no lo necesitas.
  • Link2SD. Permite que muevas ciertas aplicaciones hacia la memoria SD del teléfono, así ahorras memoria interna de almacenamiento.
  • avast! Mobile Security. Entre otras características interesantes, podrás rastrear tu teléfono si te lo roban, e incluso espiar al perpetrador ó enviar comandos de borrado de información.
  • DroidWall. Un firewall bastante completo para tu dispositivo.
  • System Tuner. Un sistema de optimización bien completo para tu android. Maneja, memoria, CPU y otros aspectos importantes.

Cabe aclarar que personalmente no uso todas las listadas, sólo algunas de ellas, las que me resultan útiles y atractivas por cualquier razón/necesidad. Como ellas y similares existen muchísimas más que podrían resultar pás apropiadas para tí.

Bien, ahora manos a la obra. Para rootear tu teléfono (funciona para la gran mayoría de dispositivos de diferentes marcas y modelos) necesitarás de un programa llamado SuperOneClick. A la fecha la versión más actual es la 2.3.3 y la puedes conseguir en segundos con una sencilla búsqueda en Google.

Lo primero que debes hacer es:

  • Poner tu teléfono en modo “USB Debugging”. Settings -> Applications -> Devolpment -> USB debugging.
  • Descargar e instalar en el Windows los drivers USB de tu teléfono.
  • Por supuesto que tu teléfono esté rooteado.

Esta parte me costó un poco pues no uso Windows como sistema operativo sino Linux (Fedora) pero luego de obtener una máquina con Windows, copié el archivo SuperOneClickv2.3.3-ShortFuse.zip (en mi caso) y lo descomprimí en el escritorio (o donde tú prefieras), no es un istalable así que se puede correr desde cualquier ubicación.

Con ello obtienes una pantalla parecida a la siguiente:

SuperOneClick

SuperOneClick

Sólo debes darle click al botón “Root” y esperar unos momentos (podría tradar minutos según dicen en ciertos casos). Al final te indicará que el proceso se ejecutó exitosamente y listo! ya tienes tu teléfono rooteado. Adicionalmente verás entre las aplicaciones del dispositivo una llamada “superuser” que será la encargada de otorgar los permisos de root a toda aplicación o servicio que lo requiera.

Ahora que tienes rooteado tu teléfono podrás realizar cualquiera de las operaciones antes explicadas. Algunas de ellas están (estarán) documentadas aquí mismo en entradas separadas.

2 Comentarios

Fedora 16: Novedades con Gnome3 y la nueva serie del Kernel 3.x

Hoy he pasado las últimas horas haciendo un “upgrade” de mi Fedora 15 hacia la beta de Fedora 16. Esta vez he demorado un poco el cambio pues normalmente yo paso de versión de Fedora justo al salir la primera Beta porque a estas alturas (a 4 días del lanzamiento oficial) ya incluso los repositorios extras (uso RPMfusion) están medio maduros como para tener los drivers del wireless especialmente, sin mencionar el VirtualBox-OSE…

Lo bueno de migrar hacia el beta, según yo, son dos cosas: 1. Obtengo la última versión (soy medio impaciente para esperar el release de la oficial) y 2. Desde el F13 al “upgradear” al beta de la siguiente versión, te pone ya en el path del release oficial, lo cual quiere decir que a la larga con simples “yum update” llego y me mantengo transparentemente en la versión oficial.

Bueno, hace unos 15 minutos ha terminado y he reiniciado … la imagen de arranque ahora es gris y no celeste como hasta F15, cambio meramente cosmético hasta ahora… Trae el nuevo Grub2. Como deja intacto el MBR del anterior Grub, se debe re-instalar bajo demanda para reemplazarlo, por lo cual no lo ví hasta luego de hacer lo indicado aquí.

La pantalla del Grub2 de hecho es más fea que antes, o mejor dicho: es mucho más simple, no tiene imagen de fondo y aparece directo el menú en texto blanco sobre un fondo negro, me recordó el cambio (visualmente idéntico) entre CentOS 5 a CentOS 6…

Al entrar ya el GUI del Gnome3, la ventana de escoger el usuario para hacer login, es más acorde al estilo del Gnome3 y menos parecida al de Gnome2. Ya una vez logueado, lo primero que noté fue que al tener conectado mi disco externo, en la barra de abajo apareción un “applet?” tipo el de Windows que dice “dispositivos extraíbles” y te lista todos los conectados con un claro ícono de expulsar… Bastante cómoda desde mi punto de vista. También noté que al conectar un dispositivo extraíble, aparece abajo un diálogo que te da 2 opciones: abrir con el nautilus o expulsarla… una desmejora práctica según yo, pues me gustaba más que simplemnete se abra en una ventana de Nautilus.

Puras mejoras visuales hasta ahora … al entrar en la esquina superior derecha (sobre mi nombre) ví una opción que dice “cuentas en línea” y que te permite enlazar el Gnome con tu cuenta de Google. Puedes escoger entre enlazar: Mail, Calendario, Contactos, Chat y Documentos independientemente… Puede manejar tu chat y demás directo desde tu escritorio Gnome…

Por último, al entrar en “Actividades” por cualquiera de los métodos conocidos y escribir unas pocas letras para buscar una aplicación, encontré que al estar enlazado a Google, ahora gnome no busca y lista sólo aplicaciones, sino también en mi lista de contactos… algo también apreciable pues se me hace parecido al buscador del Android!

Mejoras más técnicas? al menos no las he sentido, sólo puedo decir que voy un par de horas usando el nuevo F16_Beta y funciona al menos tan perfecto como el F15… lo cual ya es bastante bueno luego de un upgrade… No he notado diferencias prácticas en el rendimiento con el nuevo kernel 3.1 pero como sé que esta nueva versión trae muchas mejoras en relación a la serie 2.x, me siento más confiado en que soportará mejor los eventuales embates de trabajo que se le confíen!

En resumen, estoy bastante contento y por ahora es todo, de notar nuevas mejoras (o demejoras) relevantes las iré actualizando …

No hay Comentarios

Cómo: Encriptar y desencriptar archivos en Linux

Para encriptar y desencriptar archivos con una clave, se puede utilizar el comando gpg. Es una herramienta de encriptado y firmado para sistemas operativos Linux/UNIX así como para FreeBSD/Solaris.

GnuPG significa GNU Privacy Guard y es una herramienta GNU para asegurar comunicaciones y almacenamiento de datos. Se puede usar para encriptar datos y para crear firmas digitales. Incluye una facilidad avanzada para el manejo de llaves.

Encriptando un archivo en linux

Para encriptar un archivo sencillo, usar el siguiente comando gpg:

$ gpg -c nombreDelArchivo

Por ejemplo, para encriptar el archivo infoFinanciera.txt, escribir el comando:

$ gpg -c infoFinanciera.txt

la salida esperada será:

Enter passphrase: TuClaveAquí
Repeat passphrase: TuClaveAquí

Esto creará un archivo llamado infoFinanciera.txt.gpg.

Opciones:

-c : Encripta con un cifrador simétrico.

Precaución: Si te olvidas de la clave (alias passphrase), no podrás recobrar la información pues se usa una encriptación muy fuerte.

Desencriptar el archivo

Para desencriptar el archivo usar el siguiente comando gpg:

$ gpg infoFinanciera.txt.gpg

La salida esperada será:

gpg infoFinanciera.txt.gpg
gpg: CAST5 encrypted data
Enter passphrase: TuClaveAquí

Para desencriptar el archivo pero escribir la salida en otro archivo llamado respaldoFinanciero.txt ejecuta el siguiente comando:

$ gpg infoFinanciera.txt.gpg –o respaldoFinanciero.txt

Es bueno apuntar también que si la extensión del archivo es .asc, se trata de un archivo encriptado ASCII y si l extensión es .gpg, es un archivo encriptado binario.

No hay Comentarios

Cómo: Usar Eclipse IDE con Subversion para desarrollo PHP con control de versiones

He usado Zend Develpment Environment desde hace unos 5 años para el desarrollo de software, las nuevas versiones se volvieron cada vez más (demasiado?) sofisticadas para mi gusto y empezaron a volverse muy restrictivas en cuanto al licenciamiento de uso, así como a implementar/requerir diferentes plataformas/versiones de algo que debería ser simple y sencillo y que ellos lo empezaron a complicar con servers, debuggers, plattforms y más y más cosas.

Por otro lado los costos son cada vez menos accesibles, pues ya no puedes tomar sólo el IDE, ahora necesitas todo un pack que trae un pequeño arsenal de “esas cosas” que describí y que honestamente no necesito.

Con dos minutos de investigación en Internet cualquiera puede determinar que, al menos para mis necesidades, el indicado debería ser Eclipse. Analicé también NetBeans, pero honestamente Eclipse está mejor parado en cuanto a desarrollo PHP. Sí, NetBeans puede ser un poco más intuitivo de usar, pero luego de “tontearle” un poco, Eclipse se vuelve bastante versátil. Adicionalmente, el crecimiento de uso de Eclipse en plataformas Linux ha sido algunas veces más grande que el de NetBeans.

Entrando ya en materia, en mi Fedora 14 he instalado Eclipse IDE de la manera habitual:

yum -y install eclipse eclipse-phpeclipse eclipse-subclipse

Nótese que he agregado el plugin de soporte para desarrollo PHP (phpeclipse) así como el de Subversion (subclipse) para control de versiones pues el sistema que Eclipse trae por defecto es CVS. Al momento la versión más nueva estable y la que instalé es la 3.6 (Helios).

Una vez instalado sólo hay que abrirlo:

Creamos un nuevo proyecto con: Archivo -> Nuevo -> PHP Project. Asegúrate de seleccionar PHP Project dentro de el ítem PHP:

En el siguiente paso debes indicar el nombre para tu proyecto y si deseas le cambias la ubicación predeterminada (yo la dejé tal cual):

Listo, ya tienes un proyecto nuevo y en blanco para empezar tu trabajo. A partir de aquí podrías simplemente agregar archivos al proyecto con un clic derecho sobre el nombre del mismo a la izquierda y poner el código necesario dentro!

Pero si quieres hacerlo un poco más serio y deseas agregarle control de versiones, hay que realizar unos pocos pasos más.

Nota: Se asume que para el control de versiones tú ya has creado un repositorio de archivos SVN para el proyecto. Antes ya escribí un post sobre el uso de Subversion para el control de versiones donde describo cómo hacerlo.

En Eclipse existen las denomidas perspectivas. Para ponerlo de una manera sencilla, el concepto de “perspectivas” en Eclipse no es más que una organización de las diferentes ventanas en el espacio de trabajo. Entonces comencemos con agregar la perspectiva de Subversion en nuestro espacio de trabajo haciendo clic sobre el ícono de Abrir perspectiva arriba a la derecha del espacio de trabajo:

Y seleccionamos SVN Repository Exploring de la lista y clic en Aceptar:

Con lo cual obtenemos ya la perspectiva de exploración de repositorio SVN, donde haremos clic sobre el botón de Add SVN Repository resaltado en la imagen, para añadir nuestro repositorio SVN:

Ingresamos la URL del repositorio:

Si el repositorio tiene contraseña te la solicitará para desplegar el contenido del mismo en la ventana de árbol de la izquierda. Una vez enganchado al repositorio podrás explorarlo normalmente:

Ahora hay que enlazar el repositorio con el proyecto, para lo cual hacemos clic derecho sobre el repositorio y seleccionamos Checkout... con lo cual obtendremos el formulario de opciones:

Observa que yo seleccioné la opción Check out as a project in the workspace con lo cual haré la importación de los archivos hacia el proyecto que creé anteriormente (lo sobre escribiré en realidad). Para ello coloqué además el mismo nombre de proyecto y luego clic en Siguiente.

Sólo queda la ventana de confirmación de que haremos checkout sobre el espacio de trabajo por defecto. Clic en Finalizar:

Me advierte que estoy haciendo checkout sobre el raíz del repositorio, lo cual es correcto en mi caso pues así es como organicé mi repositorio:

Nos solicita confirmación para sobre escribir el proyecto que habíamos creado originalmente, lo cual como dije antes es OK. Sin embargo pudieron obviar la parte de crear el directorio e ir directo a generarlo desde la opción de checkout de SVN, pero preferí indicar también cómo crear un proyecto por si no se deseara seguir con SVN quizá por ser un proyecto muy simple o por cualquier otra razón.

Dependiendo del tamaño y cantidad de archivos dentro del repositorio, el proceso de checkout tomará más o menos tiempo:

Una vez terminado el proceso de checkout podremos regresar a la perspectiva PHP y veremos que el proyecto ha sido cargado con todos los archivos descargados desde el repositorio:

Nótese que los archivos tienen un pequeñísimo cilindro color naranja en la esquina inferior derecha del ícono, lo cual indica que están siendo “versionados”, con SVN en nuestro caso. El cilindro naranja cambia por un + si el archivo es nuevo, un * si tiene modificaciones, etc. Todos ellos indican que hay variaciones locales respecto a la última revisión descargada del repositorio. La tarea más común en este caso será la de Commit los cambios hacia el repositorio, para lo cual hacemos clic derecho sobre el proyecto para aplicar todos los cambios sobre el repositorio (nueva revisión) o sobre un archivo o carpeta para aplicar los cambios particulares de ese archivo o carpeta, que igualmente genera una nueva revisión en el repositorio; luego seleccionamos Trabajo en equipo y Commit... a lo que nos abre una ventana donde deberemos agregar un comentario que será incluido en el log de la nueva revisión y adicionalmente (abajo) me permite revisar los archivos que serán aplicados al repositorio en esta nueva revisión:

En el mismo menú de Trabajo en equipo están disponibles las demás opciones de trabajo con control de versiones, como Update, Diff, Patch, Merge, Log, etc., muchas de ellas quizá con nombres diferentes pero que hacen lo mismo que las descritas. Sólo es cuestión de poner manos a la obra e ir moneando y aprendiendo… Aún tengo pegadas algunas de las mañas adquiridas de tanto usar ZDE pero he encontrado al menos 3 o 4 características muy interesantes en Eclipse que ZDE no tenía y que aprecio mucho.

4 Comentarios

Corregir errores `ereg is deprecated` en PHP 5.3

Desde principios de noviembre del año pasado (2010/11/10) tenemos ya disponible RedHat 6 (seguimos esperando por CentOS 6) que trae PHP 5.3.2, serie (5.3.x) con la cual ya hemos estado trabajando en nuestras plataformas de desarrollo (Fedora) desde hace poco más de un año, justamente para buscar estar preparados para los casos que ya hemos empezado a experimentar:

He actualizado mi servidor Linux (de RedHat/CentOS 5 a RedHat/CentOS 6) y al menos una de mis aplicaciones web (basada en PHP) ha dejado de funcionar mostrándome errores del tipo `Function ereg() is deprecated`.

La explicación es simple, como fue anunciado con anticipación (los logs de versiones previas de PHP ya mostraban un mensaje indicando la futura depreciación de las funciones tipo `ereg`) estas funciones fueron retiradas para siempre en PHP 5.3. Una de las razones principales para esta decisión es que eran mucho más lentas y su sitanxis menos familiar que las alternativas Funciones PCRE.

Afortunadamente la solución es también simple, aunque puede resultar demorada y tediosa, dependiendo de qué tan extensivamente se usaron las Funciones (que han sido depreciadas) de expresiones regulares POSIX dentro de la aplicación. Veamos entonces la solución, revisando independientemente cada una de las funciones depreciadas de uso más común:

Migrando ereg():

ereg('\.([^\.]*$)', $this->filename, $extension);

reemplazarla por:

preg_match('/\.([^\.]*$)/', $this->filename, $extension);

Nótese que he encerrado el patrón de coincidencia \.([^\.]*$) entre / / (slashes), mismos que son delimitadores de patrón. Si el patrón contuviera slashes (una URL por ejemplo) entonces quizás quieras usar el delimitador # (sharp) en lugar del slash.

Migrando eregi():

Siguiendo la lógica seguramente buscaríamos la función pregi_match(), que debería ser la versión no sensible a mayúsculas/minúsculas de preg_match(). Sin embargo no existe nada parecido, pues en su lugar se trabaja con los modificadores de expresión regular. Básicamente para volver a preg_match insensible a mayúsculas/minúsculas deberemos anexar la i luego del delimitador de patrón. Entonces, para cambiar:

eregi('\.([^\.]*$)', $this->filename, $extension);

reemplazarla por:

preg_match('/\.([^\.]*$)/i', $this->filename, $extension);

Migrando ereg_replace():

$this->filename = ereg_replace('[^A-Za-z0-9_]', '', $this->filename);

Reemplazarla por:

$this->filename = preg_replace('/[^A-Za-z0-9_]/', '', $this->filename);

Nuevamente, sólo agregué los slashes como delimitadores al patrón.

Migrando eregi_replace():

Nuevamente aplicamos la i como modificador de expresión regular, al igual que en el caso de eregi() explicado anteriormente:

$this->filename = eregi_replace('[^A-Za-z0-9_]', '', $this->filename);

Reemplazarla por:

$this->filename = preg_replace('/[^A-Za-z0-9_]/i', '', $this->filename);

Con lo cual se han cubierto los cambios necesarios en las Funciones de Expresiones Regulares POSIX de uso más frecuente. La filosofía se mantiene intacta para el resto de funciones no detalladas aquí pero que pertenecen a la misma librería como split() y spliti().

Finalmente, aprovecho para hacer notar que éste es sólo uno de los cambios/mejoras que pueden provocarte problemas al actualizar la versión del SO y/o de PHP. Sin embargo como ya te imaginarás, no es el único, y otro de los que se presentarán con regular frecuencia es que por defecto en PHP 5.3 ya no se soportan los short open tags para iniciar código PHP, es decir si al inicio (o en cualquier parte) de uno de tus scripts PHP estaba algo como esto:

// Código de ejemplo de short Open Tag
< ?
  $pi = 3.1416;
  // Más código aquí
  // y más aún acá

Deberás reemplazar < ? por el tag completo que es < ?php así:

// Código de ejemplo del Open Tag completo
< ?php
  $pi = 3.1416;
  // Más código aquí
  // y más aún acá

Si experimentas problemas adicionales a los indicados, sería excelente que los comentes aquí para completar el artículo con sus respectivas soluciones!

Suerte!

6 Comentarios

Ya está disponible Joomla 1.6 Stable !!!

Como estuvo anunciado con anteriorida, hoy salió al aire la nueva, última y según dicen, mejor versión de Joomla! hasta el momento. Yo la he estado probando desde la RC1 (Release Candidate 1) y la ví muy buena.

Joomla 1.6 mayormente implementa una característica solicitada por muchos (quizá me atrevería a decir, la gran mayoría) de nosotros durante años: El manejo extendido de usuarios y la posibilidad de manipularlos más allá del esquema pre-establecido de grupos fijos que se manejaron siempre en Joomla! hasta la versión 1.5.x. Con esta característica tendremos una grandísima ventaja al poder manejar diferentes grupos y asignar a los usuarios a estos grupos y según ello definir a dónde y qué podrá hacer cada uno.

Adicionalmente, una característica interesante añadida en esta versión es el concepto de “estilo” (style) en las plantillas, tanto del sitio (fronEnd) como del administrador (backEnd). Mediante este concepto (quizá funcionalidad) podemos personalizar diferentes “caras” de la misma plantilla y además podremos asignar estos estilos a elementos individuales del menú. Es decir podemos hacer que al dar clic sobre “Inicio” se presente la plantilla “Beez” con el estilo por defecto, pero al hacer clic en “Acerca de” se muestre la misma plantilla pero con un estilo diferente y definido por nosotros.

No he revisado extensivamente ninguna de las 2 características, pero con el paso de los días y según vaya obteniendo resultados les iré comentando sobre ellos !!!

Mientras, recomiendo esperar!. Yo al menos no pienso poner esta versión en ningún sitio en producción hasta estar un poco más seguro de su estabilidad y robustez. Realmente no desconfío demasiado pues mayormente sigue siendo un Joomla! 1.5 que ya ha sido probado bastante en ambientes de producción!. Adicionalmente, los grandes proveedores de plantillas profesionales para Joomla! aún no liberan las versiones de su repertorio en versión 1.6, sin mencionar que la gente de joomlaspanish aún o sacó la traducción al español de esta última versión.

Por último, yo uso bastante Joomla! como FrameWork de aplicaciones de todo tipo, así que tengo un poco de trabajo técnico ahí, al investigar y descubrir las nuevas classes y modificaciones a las ya existentes, para así poder sacar siempre lo máximo de lo que nos ofrece este famosísimo y excelente CMS.

Este es un punto bastante especial en la línea te tiempo de vida de un sistema, donde se acercan más que nunca (y cada cierto tiempo) los niveles de conocimiento de los expertos y los novatos, pues es como un comienzo nuevo y fresco con cada nueva versión… Es bueno que colaboremos lo máximo, aún cuando pienses que eres un novato y tienes nada que ofrecer. Siempre hay algo que hacer y esto es especialmente cierto con sistemas recién nacidos o recién evolucionados como en este caso!

A trabajar!

Salu2
don pool

No hay Comentarios

Cómo: Implementar un servidor para Control de versiones con Subversion en CentOS 5.

Desde hace tiempo he tenido la intención de aprender a usar algún sistema de control de versiones para los proyectos y por fin decidí hacerlo. Escogí Subversion por ser el más actual y de más amplia utilización. Pero antes de poner manos a la obra veamos algo de teoría:

Introducción.

SubVersion es un sistema de control de versiones, cuyo cometido es administrar el acceso a un conjunto de ficheros, y mantener un historial de cambios realizados. El control de versiones es útil para guardar cualquier documento que cambie con frecuencia, como el código fuente de un programa.
Normalmente consiste en una copia maestra en un repositorio central, y un programa cliente con el que cada usuario sincroniza su copia local. Esto permite compartir los cambios sobre un mismo conjunto de ficheros. Además, el repositorio guarda registro de los cambios realizados por cada usuario, y permite volver a un estado anterior en caso de necesidad. Pero, ¿que hacer cuando dos usuarios intentan modificar el mismo fichero?. Existen dos estrategias:
  • Bloqueos: el usuario bloquea el fichero durante su edición, evitando el acceso concurrente de otros usuarios. Existen varios problemas: el usuario que acapara ficheros, el interbloqueo entre usuarios que necesitan varios ficheros, y la falta de concurrencia.
  • Merge (fusión de cambios): los ficheros se acceden concurrentemente. Los cambios realizados sobre un mismo fichero son fusionados inteligentemente por el sistema. El único problema es el intento de fusión de cambios incompatibles, que ha de solucionarse manualmente.

Características.

  • Actualiza ficheros modificados. El cliente recorre el código del servidor y sincroniza la copia local con el repositorio.
  • Copias de seguridad centralizadas. Solo el administrador debe preocuparse de realizar copias de seguridad en el repositorio.
  • Historial de cambios. El repositorio guarda registro de todos los cambios realizados. Es posible recuperar cualquiera de las versiones anteriores de cualquier fichero. Si alguien borra todos los ficheros, podemos volver atrás y recuperar su contenido.
  • SubVersion contiene dos métodos de acceso por red. Uno es una variante del protocolo HTTP llamado WedDAV/DeltaV, que proporciona mecanismos de autentificación, compresión y navegación a un repositorio. El otro método es un demonio que usa su propio protocolo el cual puede fácilmente ser encapsulado sobre ssh.
  • Seguridad. Es posible otorgar diferentes permisos sobre diferentes ramas del proyecto. Por ejemplo, estableciendo permiso universal de lectura, y permiso de escritura solo a ciertos usuarios.
  • Registra cambios en la estructura de directorios (permite mover y renombrar sin perder el historial). SubVersion usa un sistema virtual de ficheros versionado sobre una base de datos.
  • El uso de la base de datos Berkeley permite aislamiento, atomicidad, recuperación de datos, integridad, backups en caliente, y concurrencia sin necesidad de usar ficheros de lock. Con Berkeley DB no se pueden editar los ficheros a mano , pero eso tampoco es necesario porque el repositorio no se corrompe.
  • Commits atómicos, se realizan todos o ninguno. Las transacciones atómicas permiten identificar conjuntos de cambios. Cuando un desarrollador sube un conjunto de ficheros lo hace en una transacción atómica, de modo que todos los ficheros se etiquetan con un número de revisión en el repositorio. La atomicidad también impide que el repositorio quede en estado no compilable porque la red cae durante la subida de cambios.
  • Servidor y cliente intercambian diferencias entre versiones. Al enviar una nueva versión nunca es necesario transmitir ficheros enteros.
  • Permite operar directamente sobre el repositorio, sin copia local.
  • Posibilidad de trabajar con Apache versión 2 (se conecta al servidor como un modulo de extensión), esto hace que nos podamos aprovechar de toda la tecnología de este servidor Web. Es posible utilizar SSL (encriptación), trabajar remotamente utilizando el puerto estándar de los servidores Web (puerto 80).
  • Usa la biblioteca Apache Portable Runtime, que permite portar la capa de red a varios sistemas operativos.
  • Versiona todos los ficheros guardando comprimidas sus diferencias.
  • No es necesario duplicar el código en el repositorio para crear ramas. SubVersion usa copia perezosa, solo se crea un nuevo fichero cuando es modificado. Mientras tanto, el fichero de la nueva rama, esta implementado como un enlace al fichero original.
  • No es necesario conexión a red para ciertas operaciones: status, diff, revert. Esto se debe a que la copia local contiene una copia del fichero original presente en el repositorio. Este comportamiento ahorra ancho de banda a costa de mayor espacio en disco.
  • Los números de versiones son globales para todo el repositorio. No hay un número de versión por fichero (mirar apartado revisiones).

Ahora sí, ya que hemos conocido a breves rasgos el subversion, implementémoslo en un equipo con CentOS 5.

Implementación.

Lo primero será instalar los paquetes necesarios:

[root@dv4-1413 ~]# yum install mod_dav_svn subversion

mod_dav_svn es el móduo de apache para permitirle trabajar con SVN, subversion es el paquete que instalará el SVN. Si no se tuviera el Apache (httpd) ya instalado, el comando yum indicado lo agregará a la lista de paquetes a descargar/instalar, así como a cualquier otra dependencia necesaria.

Bien, el siguiente paso será verificar que el servidor Apache arranque. Normalmente no es necesario hacer modificaciones a la configuración de apache, así que procederemos con:

[root@dv4-1413 ~]# service httpd start
[root@dv4-1413 ~]# chkconfig httpd on

Si se desea personalizar cualquier cosa en el Apache, se podrá hacer con toda libertad y luego reiniciar el servidor Apache.

Ahora configuremos el módulo de apache para trabajar con subversion, de tal forma que puedan trabajar juntos adecuadamente. Editaremos entonces el archivo de configuración de ejemplo que viene con el módulo:

[root@dv4-1413 ~]# cd /etc/httpd/conf.d/
[root@dv4-1413 conf.d]# vi subversion.conf

# Asegúrate de descomentar estas dos líneas para garantizar la carga de los módulos
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

# Agrega una sección similar a ésta para tu repositorio SVN
<Location /svn/repo>
   DAV svn
   SVNPath /var/www/svn/repo

   AuthType Basic
   AuthName "Subversion :: Proyecto Repo"
   AuthUserFile /var/www/.htpasswd
   Require valid-user
</Location>

Como vemos, la configuración incluye un sistema básico de autenticación, así que deberemos crear el archivo de claves así:

[root@dv4-1413 ~]# htpasswd -cm /var/www/.htpasswd pbernal

La clave para el usuario pbernal se solicitará 2 veces en la consola y luego se almacenará en el archivo indicado. El siguiente paso será crear la estructura de directorios necesaria para el repositorio:

[root@dv4-1413 ~]# cd /var/www
[root@dv4-1413 ~]# mkdir svn
[root@dv4-1413 ~]# cd svn
[root@dv4-1413 ~]# svnadmin create repo
[root@dv4-1413 ~]# chown -R apache.apache repo
[root@dv4-1413 ~]# service httpd restart

Ahora probemos que se puede acceder al repositorio a través de un navegador: http://laipdetumaquina/svn/repo. Se debería obtener un popup solicitando el usuario y la clave de acceso al repositorio SVN. De ser así ingresar las credenciales (indicadas en el comnado htpasswd antes) y se debería mostrar una página indicando:

De ser así, eso es todo, ya hemos configurado nuestro primer repositorio SVN. Si se desearan múltiples repositorios, basta con agregar secciones <Location> en la configuración indicando las particularidades de cada una.

A continuación podremos empezar a utilizar el repositorio recién configurado con cualquier cliente, IDE, etc., que soporte SVN para el control de versiones.

Uso de Subversion.

Como referencia veamos un ejemplo de proyecto que agregaremos al repositorio repo.

Empecemos por crear el esquema de directorios de nuestro proyecto. La documentación recomienda que se creen al menos los directorios: branches, tags y trunk en el directorio raíz del esquema, siendo trunk el directorio que contendrá tus archivos.

[pbernal@dv4-1413 ~]$ cd /tmp/
[pbernal@dv4-1413 tmp]$ mkdir proy1
[pbernal@dv4-1413 tmp]$ cd proy1
[pbernal@dv4-1413 proy1]$ mkdir branches
[pbernal@dv4-1413 proy1]$ mkdir tags
[pbernal@dv4-1413 proy1]$ mkdir trunk
[pbernal@dv4-1413 trunk]$ vi config.php
[pbernal@dv4-1413 trunk]$ vi trunk/index.php

Hay que notar que si el proyecto no se tratara de una aplicación, sino quizá un simple método de almacenar/versionar archivos de configuración, este esquema no sería necesario y podríamos colocar los archivos directamente en la raíz del esquema, o en carpetas con un nombre cualquiera. Existe entonces total libertad sobre la disposición y contenido del directorio de trabajo.

El siguiente paso será importar al repositorio los archivos de mi directorio local de trabajo. Para ello usaremos el subcomando import del comando svn:

[pbernal@dv4-1413 ~]$ svn import /tmp/proy1/ http://192.168.7.7/svn/repo/proy1 -m "Esquema inicial de repositorio para proy1"
Reino de autentificación: <http: //192.168.7.7:80> DonPool :: Subversion repos
Clave de 'pbernal':
Añadiendo      /tmp/proy1/trunk
Añadiendo      /tmp/proy1/trunk/index.php
Añadiendo      /tmp/proy1/branches
Añadiendo      /tmp/proy1/config.php
Añadiendo      /tmp/proy1/tags
Commit de la revisión 1.

Así habremos importado hacia el repositorio todo el contenido de mi directorio de trabajao /tmp/proy1. De ahora en adelante podrá ser accesado local ó remotamente con cualquier cliente SVN.

Veamos ahora cómo hacer checkout (obtener) de los archivos desde algún otro equipo:

[pbernal@aspire ~]$ svn co http://192.168.7.7/svn/repo/proy1
A    proy1/trunk
A    proy1/trunk/index.php
A    proy1/branches
A    proy1/config.php
A    proy1/tags
Revisión obtenida: 1

Ahora, dado que ya hemos obtenido la revisión 1, podremos editarla a voluntad y luego de ello, enviar los cambios hacia el repositorio:

[pbernal@aspire ~]$ cd proy1/
[pbernal@aspire proy1]$ svn move config.php trunk/config.php
A         trunk/config.php
D         config.php
[pbernal@aspire proy1]$ svn commit -m "Movido el archivo config.php hacia dentro del trunk y editado para agregar otra variable."
Eliminando     config.php
Añadiendo      trunk/config.php
Transmitiendo contenido de archivos .
Commit de la revisión 2.

Lo bonito de esto es que se puede borrar todos los directorios que acabamos de obtener en tu equipo, sin afectar en lo más mínimo lo almacenado en el repositorio. La única razón por la que se obtuvieron (checked out) fue la de editarlos y luego enviarlos de vuelta en línea. Puedes revisar los cambios aplicados navegando en el repositorio.

Veamos unos ejemplos de cómo agregar o eliminar archivos al repositorio:

[pbernal@aspire proy1]$ cp ~/bin/arreglaPermisos.php trunk/
[pbernal@aspire proy1]$ svn add trunk/arreglaPermisos.php
A         trunk/arreglaPermisos.php
[pbernal@aspire proy1]$ svn commit -m "Agregado al trunk script de corrección de permisos"
Añadiendo      trunk/arreglaPermisos.php
Transmitiendo contenido de archivos .
Commit de la revisión 3.
[pbernal@aspire proy1]$ svn delete trunk/arreglaPermisos.php
D         trunk/arreglaPermisos.php
[pbernal@aspire proy1]$ svn commit -m "Eliminado del trunk el script de corrección de permisos"
Eliminando     trunk/arreglaPermisos.php
Commit de la revisión 4.

En los pasos anteriores hemos agregado el archivo trunk/arreglaPermisos.php (revisión 3) y lo eliminamos (revisión 4). Pensemos que deseáramos regresar a un estado previo del proyecto, por ejemplo si ha pasado un tiempo desde la última vez que revisamos el proyecto, siempre es buena idea echar un vistazo a la bitácora del repositrio:

[pbernal@aspire proy1]$ svn log http://192.168.7.7/svn/repo/proy1
------------------------------------------------------------------------
r4 | pbernal | 2010-07-25 15:27:49 -0500 (dom 25 de jul de 2010) | 1 line

Eliminado del trunk el script de corrección de permisos
------------------------------------------------------------------------
r3 | pbernal | 2010-07-25 14:33:29 -0500 (dom 25 de jul de 2010) | 1 line

Agregado al trunk script de corrección de permisos
------------------------------------------------------------------------
r2 | pbernal | 2010-07-25 14:10:03 -0500 (dom 25 de jul de 2010) | 1 line

Movido el archivo config.php hacia dentro del trunk y editado para agregar otra variable.
------------------------------------------------------------------------
r1 | pbernal | 2010-07-25 13:53:21 -0500 (dom 25 de jul de 2010) | 1 line

Esquema inicial de repositorio para proy1
------------------------------------------------------------------------

Esta es la razón por la que es buena idea agregar un comentario con el modificador -m cada vez que hacemos un commit al repositorio. Adicionalmente, para éste y otros comandos, se puede especificar una revisión con el parámetro -r, por ejemplo, para obtener el log de la revisión 2:

[pbernal@aspire proy1]$ svn log -r2 http://192.168.7.7/svn/repo/proy1
------------------------------------------------------------------------
r2 | pbernal | 2010-07-25 14:10:03 -0500 (dom 25 de jul de 2010) | 1 line

Movido el archivo config.php hacia dentro del trunk y editado para agregar otra variable.
------------------------------------------------------------------------

E incluso un rango de revisiones, por ejemplo el log de las revisiones 2 -> 3:

[pbernal@aspire proy1]$ svn log -r2:3 http://192.168.7.7/svn/repo/proy1
------------------------------------------------------------------------
r2 | pbernal | 2010-07-25 14:10:03 -0500 (dom 25 de jul de 2010) | 1 line

Movido el archivo config.php hacia dentro del trunk y editado para agregar otra variable.
------------------------------------------------------------------------
r3 | pbernal | 2010-07-25 14:33:29 -0500 (dom 25 de jul de 2010) | 1 line

Agregado al trunk script de corrección de permisos
------------------------------------------------------------------------

Bien, ahora que tenemos claras las modificaciones realizadas en cada revisión, podremos revertir los cambios en la copia local hacia el estado anterior que se desee, simplemente obteniendo (checkout) dicha revisión específica:

[pbernal@aspire proy1]$ svn co -r3 http://192.168.7.7/svn/repo/proy1
A    proy1/trunk/arreglaPermisos.php
Revisión obtenida: 3

Por otro lado, una de las características, que yo personalmente como desarrollador veo más útil, es la posibilidad de obtener diffs entre las revisiones, lo cual me permite generar archivos de parche para actualizar fácilmente entre versiones en los sistemas ya en producción. Veamos:

[pbernal@aspire proy1]$ svn diff -r1:2 http://192.168.7.7/svn/repo/proy1
Index: config.php
===================================================================
--- config.php	(revisión: 1)
+++ config.php	(revisión: 2)
@@ -1,2 +0,0 @@
-<?php
-$var = 1
Index: trunk/config.php
===================================================================
--- trunk/config.php	(revisión: 0)
+++ trunk/config.php	(revisión: 2)
@@ -0,0 +1,3 @@
+<?php
+$var = 1;
+$var2 = 2;

La salida del comando se puede almacenar en un archivo (con un redirect “>” por ejemplo) que podrá ser usado directamente con el comando patch para migrar/actualizar cualquier directorio de trabajo que tenga la revisión 1 y transformarla así a la revisión 2.

Por último, veamos cómo controlar o discriminar los accesos hacia el repositorio a través de ACLs. Las ACLs pueden ser habilitadas con la opción AuthzSVNAccessFile que toma un nombre de archivo como parámetro y que se puede agregar a cualquier sección <Location>:

<Location /svn/repo>
   DAV svn
   SVNPath /var/www/svn/repo
   AuthzSVNAccessFile /etc/svn-acl-conf
   AuthType Basic
   AuthName "DonPool :: Subversion repo"
   AuthUserFile /var/www/.htpasswd
   Require valid-user
</Location>

Ahora podemos crear el archivo /etc/svn-acl-conf que consta de secciones de la forma siguiente:

[nombrerepo:rutarepo]
usuario = acceso

Donde acceso puede ser r (lectura), rw (lectura, escritura) ó vacío (ningún acceso). La ACL por defecto es no dar ningún acceso a ningún usuario. Supongamos que necesitamos ofrecer acceso de lectura y escritura a pbernal y de sólo lectura a nawes:

[repo:/]
nawes =  r
pbernal = rw

También es posible crear grupos en una sección groups. De esta manera los grupos pueden ser usados en las ACLs anteponiendo el signo “@” delante del nombre:

[groups]
desarrollo = donpool, epe, david

[repo:/]
nawes =  r
@desarrollo = rw

Si se deseara hacer a todos los repositorios legibles por cualquiera, se puede agregar una sección para el raíz de todo repositorio:

[/]
* =  r

Conclusiones.

Esta es sólo una pequeña guía de la instalación y uso básicos de SVN y sólo cubre los aspectos más relevantes o los más comunmente utilizados, sin embargo no he sino rascado la superficie de esta poderosísima herramienta de control de versiones, es así que siempre será recomendable profundizar revisando la documentación oficial y también a este excelente libro libre, que fueron las principales fuentes de éste artículo; además de este PDF que me proporcionó la parte teórica del mismo.

1 Comentario

Generando logs hacia archivos en Joomla 1.5 con JLog

Joomla provee una clase utilitaria para logear  información hacia archivos llamada JLog. Esta clase provee las funcionalidades para crear archivos en common log format para virtualmente cualquier propósito como:

  • Almacenar información de depuración
  • Logear llamadas AJAX para ayudarnos a encontrar problemas
  • Logear las cosas que un visitante de un sitio web esté haciendo

La clase JLog se encuentra en /libraries/error/log.php y se puede incluir con el siguiente código:

jimport('joomla.error.log');

Si bien logear errores es ciertamente una práctica muy común (de hecho la propia clase se encuentra como un sub-paquete del paquete error), no se limita a logear información de errores solamente.

Usando JLog directamente

Generalmente NO se creará una nueva instancia de JLog. En su lugar se deberá usar el método getInstance para obtener una instancia del log para un archivo y opciones específicas de un log dado.

jimport('joomla.error.log');
$log = &JLog::getInstance();

Por defecto esto creará un archivo de log llamado error.php en el directorio temporal de Joomla (referido en la variable $tmp_path en el archivo configuration.php). El archivo tiene una extensión .php como medida de seguridad para prevenir accesos directos a los contenidos del mismo. Para incrementar la privacidad posteriormente, se podría considerar el cambio del directorio temporal de Joomla a una localización externa al raíz del web.

Cambiando el nombre del archivo de log

En la práctica, es recomendable crear nuestros propios archivos de log incluyendo espacios de nombres (namespaces) como por ejemplo:

jimport('joomla.error.log');
$log = &JLog::getInstance('com_ajax.log.php');

Por defecto esto ofrece un archivo de log básico con las siguientes columnas:

  • date
  • time
  • level
  • c-ip (la dirección IP del usuario)
  • status
  • comment

Las columnas date, time y c-ip son populadas automáticamente si es que no se proveen. Las columnas level, status y comment pueden ser usadas a discreción del programador. La columna level es generalmente orientada a alguna clase de nivel como warning o error. La columna status generalmente indicará algún estado como ok ó fail (probablemente un valor de 0 ó 1 o incluso algo como un código de estado HTTP). Se puede dejar en blanco también. Al nivel más simple se proporcionará únicamente la columna comment y se dejará manejar el resto a los valores por defecto de la clase, como se muestra en el uso del método addEntry:

jimport('joomla.error.log');
$log = &JLog::getInstance('com_ajax.log.php');

// Just adding a comment
$log->addEntry(array('comment' => 'Este es mi mensaje');

// Adding the comment and the status code
$log->addEntry(array('comment' => 'Un extraño error ha ocurrido', 'status' => 500));

Se puede ver que se le pasó un vector asociativo a addEntry, donde cada elemento del array apunta a una columna en el archivo de log. Si no se provee una columna esperada, el log simplemente agrega un guión. Si se proveen más columnas de las que la clase conoce, estas simplemente serán ignoradas.

Cambiando el formato del archivo de log

Se puede fácilmente cambiar el formato del archivo de log (las columnas que están disponibles) para ajustarse a la información que se desea logear. Esto se puede hacer de dos maneras. La primera es pasarle el formato en un vector de opciones.

jimport('joomla.error.log');
$options = array(
  'format' => "{DATE}\t{TIME}\t{USER_ID}\t{COMMENT}";
);

$log = &JLog::getInstance('com_ajax.log.php', $options);
$user = &JFactory::getUser();
$userId = $user->get('id');
$log->addEntry(array('user_id' => $userId, 'comment' => 'Este es mi mensaje'));

Entonces, lo que se hizo aquí es crear un vector asociativo en la variable $options. El vector tiene un elemento “format”.  El formato es simplemente una cadena de los nombres de columna deseados en mayúsculas, cada uno encerrado entre llaves y separados por un caracter de tabulación. Nótese que esta cadena está encerrada entre comillas (no apóstrofes) para que \t sea reconocido como un tabulador (no como un backslash con la letra t).

La segunda forma de personalizar el formato del log es usar el método setOptions así:

jimport('joomla.error.log');
$options = array(
    'format' => "{DATE}\t{TIME}\t{USER_ID}\t{COMMENT}";
);

$log = &JLog::getInstance('com_ajax.log.php');
$log->setOptions($options);
$user = &JFactory::getUser();
$userId = $user->get('id');
$log->addEntry(array('user_id' => $userId, 'comment' => 'Este es mi mensaje'));

Cualquiera de los dos métodos es aceptable. Si se está usando esto en una extensión, sólo se debe asignar el formato una vez por archivo de log. En un componente por ejemplo, se puede inicializar el objeto en el archivo de entrada del componente (dispatcher), pero no usarlo realmente, como se sugiere en el ejemplo anterior. Entonces, luego, dentro de la ejecución del componente, se podrá llamar a una instancia del objeto de logs, así:

// Anywhere, deep inside the component
$log = &JLog::getInstance('com_notes.log.php');
$log->addEntry(array('user_id' => 0, 'comment' => 'Algo que requiere de tu atención'));

Esto funciona siempre que se mantenga constante el nombre del archivo de log. Por tal motivo, se podría preferir la definición del nombre de archivo de log como una constante, así::

// This is the code in the dispatcher file (components/ajax.php)
// Define the file name as a PHP constant
define('AJAX_ERROR_LOG', 'com_ajax.log.php');

// Include the library dependancies
jimport('joomla.error.log');
$options = array(
    'format' => "{DATE}\t{TIME}\t{USER_ID}\t{COMMENT}";
);
// Create the instance of the log file in case we use it later
$log = &JLog::getInstance(AJAX_ERROR_LOG, $options);
....
....
// Then, deep in the heart of the component
$log = &JLog::getInstance(AJAX_ERROR_LOG);
$user = &JFactory::getUser();
$userId = $user->get('id');
$log->addEntry(array('user_id' => $userId, 'comment' => 'Este es mi mensaje'));

Definir el nombre de archivo como una constante significa que no se tendrá que recordar este nombre a través del código y si se necesitara cambiarlo, se puede hacer en un solo lugar.

Se puede, por supuesto, crear múltiples archivos de log para una sola extensión. No existe límite en el número de archivos que se pueden crear y se pueden usar diferentes logs para recolectar diversa información. Alternativamente, se puede logear la misma información pero creando un log por cada día. Para logar esto, sólo deberemos incluir la fecha en el nombre del archivo, así:

// Define the file name as a PHP constant
define('AJAX_ERROR_LOG', 'com_notes.log.'.date('Y_m_d').'.php');

Esta es una buena técnica si se trata de ubicar errores intermitentes y que se reporten en una fecha específica. Nos ahorrará el trabajo de buscar dentro de archivos de log potencialmente muy largos. Se podrá descartar los logs luego de un número de días, de ser el caso.

Cambiar la ubicación de los archivos de log

El método JLog::getInstance toma un argumento más. Se puede opcionalmente indicar la ruta (path) donde queremos almacenar el archivo de log dentro de nuestro servidor. Si se usa este argumento para una extensión que se esté distribuyendo, entonces se debería setear como una opción de configuración de la misma, dado que es posible que la ruta (path) no exista en todos los servidores (sin mencionar las diferencias en las rutas entre sistemas operativos como Windows, Linux, etc).

Para especificar una ruta fija, se instancia el log así:

// Create the instance of the log file in case we use it later
$log = &JLog::getInstance(AJAX_ERROR_LOG, $options, '/tmp/ajax');

Creación de ayudantes (helpers) para JLog

Usar JLog directamente está bien, pero podría resultar algo tedioso. Para hacernos la vida un poco más fácil se puede crear una clase ayudante (helper) que haga todo el trabajo duro, configurando el log, pero ofreciendo una API muy simple para usarse dentro de la extensión. Una clase helper podría verse algo así:

/**
 * Helper class for logging
 * @package    Ajax
 * @subpackage com_ajax
 */
class AjaxHelperLog
{
    /**
     * Simple log
     * @param string $comment  The comment to log
     * @param int $userId      An optional user ID
     */
    function simpleLog($comment, $userId = 0)
    {
        // Include the library dependancies
        jimport('joomla.error.log');
        $options = array(
            'format' => "{DATE}\t{TIME}\t{USER_ID}\t{COMMENT}";
        );
        // Create the instance of the log file in case we use it later
        $log = &JLog::getInstance(AJAX_ERROR_LOG, $options);
        $log->addEntry(array('comment' => $comment, 'user_id' => $userId));
    }
}

Ahora, todo lo que se necesita hacer es cargar el archivo en el dispatcher y dentro de nuestro componente todo lo que deberíamos hacer es ejecutar una llamada estática al método simpleLog, así:

AjaxHelperLog::simpleLog('Esta es mi historia, esta es mi canción');

Adicionalmente se puede agregar el ID de usuario si fuese apropiado. La lección principal aquí es la de que se puede crear un método para servir a múltiples propósitos según lo que el programador requiera.

No hay Comentarios

Instalación de Blue Onyx en CentOS 5.4

Es muy simple la instalación del Blue Onyx, sin embargo me topé con un par de cosas luego de la instalación que me hicieron perder tiempo.

Primero debemos realizar una instalación de CentOS dividido en particiones, principalmente se debe tener en un partición aparte el home ya que ahí aplicaremos quota que es necesario para el funcionamiento de BlueOnyx, una vez instalado, seguimos el siguiente tutorial desde el punto que dice: “yum install quota wget

http://www.blueonyx.it/index.php?page=tar-ball-installer

Luego de instalado el BlueOnyx, existen algunos problemas que en mi caso era necesario resolver, por ejemplo:

No podemos ingresar como usuario root vía ssh al server.

Dentro de las seguridades que aplica el BlueOnyx es bloquear al root, para desbloquear debemos editar el archivo de configuración del demonio sshd así:

# vi /etc/ssh/sshd_config

Editamos el parámetro que dice:

PermitRootLogin no

cambiar a:

PermitRootLogin yes

El primer truco encontrado, es que este parámetro está puestos dos veces, la una por medio del archivo y la otra al final, debes asegurarte que en los dos esté en “PermitRootLogin yes”, yo le borre  el primer parámetro que encontré y le dejé solo el que está casi al final del archivo.

Un segundo problema es que no se puede copiar nada al servidor como usuario root,  justamente porque agrega restricciones a este usuario por seguridad, en ese caso deben utilizar el usuario admin para copiar y luego ingresan como usario root vía ssh para realizar las tareas que necesiten (ya tienen copiado al servidor que es lo importante).

Por cierto si alguna vez se te pierde o no recuerdas la clave de administración del BlueOnyx, loq ue debes hacer es entrar vía ssh al server como root y aplicar un simple comando para cambiar la contraseña:

# passwd admin

No hay Comentarios

Capturar tu escritorio para hacer videos demostrativos con Linux

Primero que todo, deberé indicar que todo lo que escribo lo he ejecutado en mi Fedora 12, pero estoy seguro que casi cualquier Linux actual deberá soportar la tecnología descrita…

Dado que me he dado a la tarea de preparar unos cursos de PHP, decidí introducir unos videos demostrativos de algunas tareas que describan de forma más didáctica y directa ciertas actividades del curso. Con la ayuda del “yum” no tardé mucho tiempo en recordar el nombre del paquete que mi socio Ernesto Pérez me comentó hace tiempo usaba para estos menesteres: recordmydesktop… que es una herramienta en línea de comandos (CLI) justamente para eso y que trae una interface gráfica al mismo llamada gtk-recordmydesktop (Creo que él lo corría sobre CentOS 5 en aquel tiempo). La herramienta es muy buena y sencilla de manejar, graba video y audio (el audio es opcional) y tiene opciones para modificar la calidad de grabación de ambos. Repito, muuuy bueno y simple!!! …

Luego de grabar un par de pruebas me percaté de que genera los archivos en formato de video ogg “.ogv“, lo cual no es un defecto ni nada, de hecho es uno de los códecs más eficientes y de mejor calidad que he visto, pero no es muy popular, lo que quiere decir que para publicarlo en web deberé tomar en cuenta a toda esa gente que usa sistemas del “lado oscuro” y que no incluyen este códec por defecto. Complicarles con descargas/inclusiones de códecs a los usuarios finales no es muy buena idea.

En busca de una solución acudí al “ffmpeg” que he usado profusamente desde hace tiempo para codificación/conversión de audio y video, para probar transformar el video de “ogv” a “flv” encontrándome con la imposibilidad del ffmpeg (o ignorancia mía al correrlo) de leer el ogv como códec de entrada para la transformación. Siguiente paso, como siempre, leer la documentación del ffmpeg para buscar la salida …

En eso que leía y leía, me topé con una pequeña sección titulada “X11 grabbing” (Captura de X11) que me llamó la atención. Pues resulta que el ffmpeg no sólo es capaz de recibir un archivo y/o un flujo como entrada para la codificación/recodificación, sino que también es capáz de tomar como entrada una pantalla del sistema… Wow!!! dije y enseguida a probar… El comando resultante en mi caso fue:

ffmpeg -f x11grab -s svga -r 3 -i :0.0 -vcodec flv -y Videos/PHP_MySQL/primerPHPcli.flv

Parece más complejo de lo que realmente es, paso a describirlo:

  • -f x11grab: indica que se tome la interface gráfica (X11) como entrada
  • -s svga: indica el tamaño de la captura, se puede especificar como 800×600 por ejemplo, o con alguna de las definiciones pre-existentes como svga.
  • -r 3: indica que se capturen 3 cuadros por segundo
  • -i :0.0: indica que se tome la interface gráfica de la pantalla :0.0 que típicamente corresponde con el valor de la variable global DISPLAY
  • -vcodec flv: indica que deseo generar un archivo flv como resultado de la captura
  • -y: que sobre-escriba archivos preexistentes con el mismo nombre
  • Videos/PHP_MySQL/primerPHPcli.flv: es el archivo en el cual quiero que se grabe el video

El comando se queda corriendo en una consola mientras se graba el video… para detener basta presionar la tecla “q” en dicha consola.

Desventajas:

  • No graba el video con audio, así que sólo podemos hacer cine mudo. En mi caso no era inconveniente.
  • El archivo FLV generado, si bien es compatible con el web (es el formato que usa YouTube) los archivos son bastante más grandes que el OGV.

Igual y con todo es lo que estoy usando y me está ayudando a lograr mi cometido, aunque seguiré buscando una salida viable para los OGV que sí contienen audio y que son bastante más pequeños.

No hay Comentarios