Archive for the 'Programación' Category

subversion: Recuperar cambios y eliminaciones hechas

Muchos compañeros de trabajo y amigos en general que recién comienzan con el manejo de sistemas de control de versiones centralizados, en particular subversion, regularmente tienen inquietudes en cuanto al proceso de recuperación de cambios una vez que han sido enviados al repositorio, así como también la recuperación de ficheros y directorios que fueron eliminados en el pasado. Trataré de explicar algunos casos en base a ejemplos para que se tenga una idea más clara del problema y su respectiva solución.

En el primero de los casos se tiene recuperar la revisión previa a la actual, suponga que usted mantiene un repositorio de recetas, una de ellas en particular es la ensalada caprese, por error o descuido añadió el ingrediente Mostaza tipo Dijón a la lista, si usted posee siquiera un lazo con italinos sabe que está cometiendo un error que puede devenir en escarnio público, desprecio e insultos.

~/svn/wc/trunk$ svn diff -r 2:3 ${URL}/trunk/caprese
Index: caprese
===================================================================
--- caprese	(revision 2)
+++ caprese	(revision 3)
@@ -7,3 +7,4 @@
  - Albahaca fresca
  - Aceite de oliva
  - Pimienta
+ - Mostaza tipo Dijon

Note que el comando anterior muestra las diferencias entre las revisiones 2 y 3 del repositorio, en el resumen se puede apreciar que en la revisión 3 ocurrió el error. Un modo rápido de recuperarlo es como sigue.

~/svn/wc/trunk$ svn merge -c -3 ${URL}/trunk/caprese
--- Reverse-merging r3 into 'caprese':
U    caprese

En este caso particular se están aplicando las diferencias entre las revisiones consecutivas a la copia de trabajo. Es hora de verificar que los cambios hechos sean los deseados:

~/svn/wc/trunk$ svn status
M      caprese
~/svn/wc/trunk$ svn diff
Index: caprese
===================================================================
--- caprese	(revision 3)
+++ caprese	(working copy)
@@ -7,4 +7,3 @@
  - Albahaca fresca
  - Aceite de oliva
  - Pimienta
- - Mostaza tipo Dijon

Una vez verificado enviamos los cambios hechos al repositorio a través de comando svn commit.

Seguramente usted se estará preguntando ahora que sucede si las revisiones del ficheros no son consecutivas como en el caso mostrado previamente. En este caso es importante hacer notar que la opción -c 3 es equivalente a -r 2:3 al usar el comando svn merge, en nuestro caso particular -c -3 es equivalente a -r 3:2 (a esto se conoce como una fusión reversa), substituyendo la opción -c (o --changes) en el caso previo obtenemos lo siguiente:

~/svn-tests/wc/trunk$ svn merge -r 3:2 ${URL}/trunk/caprese
--- Reverse-merging r3 into 'caprese':
U    caprese

Referencias: svn help merge, svn help diff, svn help status.

Recuperando ficheros o directorios eliminados

Una manera bastante sencilla de recuperar ficheros o directorios eliminados es haciendo uso de comando svn cp o svn copy, una vez determinada la revisión del fichero o directorio que desea recuperar la tarea es realmente sencilla:

~/svn-tests/wc/trunk$ svn cp ${URL}/trunk/panzanella@6 panzanella
A         panzanella

En este caso se ha duplicado la revisión 6 del fichero panzanella en la copia de trabajo local, se ha programado para su adición incluyendo su historial, esto último puede verificarse en detalle al observar el signo ‘+’ en la cuarta columna del comando svn status.

~/svn-tests/wc/trunk$ svn status
A  +   panzanella

Referencias: svn help copy, svn help status.

Generando contraseñas aleatorias con Perl

El día de hoy se manifestó la necesidad de generar una serie de claves aleatorias para un proyecto en el que me he involucrado recientemente, la idea es que la entrada que tenemos corresponde más o menos al siguiente formato:

username_1
username_2
...
username_n

La salida que se desea obtener debe cumplir con el siguiente formato:

username_1 pass_1
username_2 pass_2
username_3 pass_3
...
username_n pass_n

En este caso debía cumplir un requisito fundamental, las contraseñas deben ser suficientemente seguras.

No pensaba en otra cosa que usar el lenguaje de programación Perl para realizar esta tarea, así fue, hice uso del poderío que brinda Perl+CPAN y en menos de 5 minutos ya tenía la solución al problema planteado, el tiempo restante me sirvió para comerme un pedazo de torta que me dió mi hermana, quien estuvo de cumpleaños el día de ayer.

En primer lugar, debemos instalar el módulo String::MkPasswd, el cual nos permitirá generar contraseñas de manera aleatoria. Si usted disfruta de una distribución decente como Debian1 la instalación del módulo es realmente trivial.

# aptitude install libstring-mkpasswd-perl

Además, si usted se detiene unos segundos y lee la documentación del módulo String::MkPasswd2, se dará cuenta que la función mkpasswd() toma un hash de argumentos opcionales. Si no le pasa ningún argumento a esta función estará generando constraseñas aleatorias con las siguientes características:

  • La longitud de la contraseña será de 9.
  • El número mínimo de dígitos será de 2.
  • El número mínimo de caracteres en minúsculas será de 2.
  • El número mínimo de caracteres en mayúsculas será de 2.
  • El número mínimo de caracteres no alfanuméricos será de 1.
  • Los caracteres no serán distribuidos entre los lados izquierdo y derecho del teclado.

Ahora bien, asumiendo que el fichero de entrada es users.data, la tarea con Perl es resumida en una línea de la siguiente manera.

perl -MString::MkPasswd=mkpasswd -nli -e 'print $_, " ", mkpasswd()' users.data

La línea anterior hace uso de la función mkpasswd del módulo String::MkPasswd para generar las contraseñas aleatorias para cada uno de los usuarios que se encuentran en el fichero de entrada users.data, además, la opción -i3 permite editar el fichero de entrada in situ, ahora bien, quizá para algunos paranoicos (me incluyo) no sea suficiente todo esto, así que vamos a generar contraseñas aleatorias aún más complicadas.


#!/usr/bin/perl -li

use strict;
use warnings;
use String::MkPasswd qw(mkpasswd);

while(<>){
        chomp;
        print $_, " ", mkpasswd(
                -length => 16,
                -minnum => 5,
                -minlower => 5,
                -minupper => 3,
                -minspecial => 3,
                -distribute => 1
        );
}

En esta ocasión el la función mkpasswd() generará claves aún más complejas, dichas claves cumplirán con las siguientes condiciones.

-length

La longitud total de la contraseña, 16 en este caso.
-minnum
El número mínimo de digitos. 5 en este caso.
-minlower
El número mínimo de caracteres en minúsculas, en este caso 5.
-minupper
El número mínimo de caracterés en mayúsculas, en este caso 3.
-minspecial
El número mínimo de caracteres no alfanuméricos, en este caso será de 3.
-distribute

Los caracteres de la contraseña serán distribuidos entre el lado izquierdo y derecho del teclado, esto hace más díficil que un fisgón vea la contraseña que uno está escribiendo. El valor predeterminado es falso, en este caso el valor es verdadero.

El script mostrado anteriormente lo podemos reducir a una línea, aunque preferí guardarlo en un fichero al que denomine genpasswd.pl por cuestiones de legibilidad.

  1. Recuerde, Debian es inexorable[regresar]
  2. Este modulo en particular no solo se encuentra perfectamente integrado con nuestra distribución favorita, sino que además sus dependencias están resueltas. Esto es una simple muestra del poderío que ofrece una distribución como Debian.[regresar]
  3. Para mayor información acerca de las distintas opciones usadas se le sugiere referirse a man perlrun[regresar]

El algoritmo de Dijkstra en Perl

Hace ya algunos días nos fué asignado en la cátedra de Redes de Computadoras encontrar el camino más corto entre dos vértices de un grafo dirigido que no tuviese costos negativos en sus arcos, para ello debíamos utilizar el algoritmo de Dijkstra. Además de ello, debía presentarse el grafo y la ruta más corta en una imagen, para visualizarlo de mejor manera.

Cuando un profesor te dice: No se preocupen por la implementación del algoritmo de Dijkstra, utilice la que usted prefiera, pero les agradezco que la analicen. Además, pueden utilizar el lenguaje de programación de su preferencia. Estas palabras te alegran el día, simplemente eres feliz.

Por algunos problemas que tuve con algunos módulos en Python, no lo hice en dicho lenguaje de programación, no vale la pena explicar en detalle los problemas que se me presentaron.

Lo importante de todo esto, es que asumí el reto de realizar la asignación en un lenguaje de programación practicamente nuevo para mí, aunque debo reconocer que la resolución no me causó dolores de cabezas en lo absoluto, a continuación algunos detalles.

En primer lugar, formularse las preguntas claves, ¿existe algún módulo en Perl que implemente el algoritmo de Dijkstra para encontrar el camino más corto?, ¿existe algún módulo en Perl que implemente GraphViz?

En segundo lugar, buscar en el lugar correcto, y cuando hablamos de Perl el sitio ideal para buscar es search.cpan.org, efectivamente, en cuestión de segundos encontre los dos módulos que me iban a facilitar la vida, Bio::Coordinate::Graph, para encontrar la ruta más corta entre dos vértices en un grafo y GraphViz, para pintar el grafo.

En tercer lugar, verificar en tu distro favorita, Debian, si existe un paquete precompilado listo pasa ser usado, para GraphViz existe uno, libgraphviz-perl, así que para instalarlo es tan fácil como:

# aptitude install libgraphviz-perl

Para instalar el módulo Bio::Coordinate::Graph, primero debía debianizarlo, eso es tan sencillo como hacer.

# dh-make-perl --build --cpan Bio::Coordinate::Graph

Luego debe proceder a instalar el fichero .deb que se generó con dh-make-perl, para lograrlo hago uso del comando dpkg, eso es todo. Por cierto, acerca del comando dh-make-perl ya había hablado en la entrada Perl: Primeras experiencias.

Encontrando el camino más corto

Según dice la documentación del módulo Bio::Coordinate::Graph debemos hacer uso de un hash de hashes anónimos para representar la estructura del grafo, en ese momento recordé algunas palabras que José Luis Rey nos comentó en la primera parte del curso de Perl, vale resalta la siguiente: Si usted no utiliza un hash, no lo está haciendo bien.

my $hash = {
		'6' => undef,
		'1' => {
			'2' => 1
			},
		'2' => {
			'6' => 4,
			'4' => 1,
			'3' => 1
			},
		'3' => {
			'6' => 1
			},
		'4' => {
			'5' => 1
			},
		'5' => undef
	};

Algo que es importante saber es que en Perl las estructuras de datos son planas, lo cual es conveniente. Por lo tanto, vamos a tener que utilizar referencias en este caso, pero luego nos preocuparemos por ello. Ahora solo resta decir que, la estructura hecha a través de un hash de hashes es sencilla de interpretar, las llaves o keys del hash principal representan los vértices del grafo, ahora bien, las llaves de los hashes más internos representan los vértices vecinos de cada vértice descrito en el hash principal, el valor de los hashes más internos representa el peso, distancia o costo que existe entre ambos vértices, para aclarar la situación un poco: El vértice 2, tiene como vecinos a los vértices 3, 4 y 6, con costos de 1, 1 y 4 respectivamente. Puede ver una muestra del grafo resultante.

De manera alternativa puede utilizar un hash de arrays para representar la estructura del grafo, siempre y cuando todos los costos entre los vértices sean igual a 1, este método es menos general que el anterior y además, este tipo de estructura es convertida a un hash de hashes, así que a la final resulta ineficiente.

Una vez definida la estructura del grafo corresponde crear el objeto, esto es realmente sencillo.

my $graph = Bio::Coordinate::Graph->new(-graph => $hash);

Lo que resta es definir el vértice de inicio y el vértice final, yo los he definido en las variables $start y $end, luego de ello, debemos invocar al método shortest_path, de la siguiente manera:

my @path = $graph->shortest_path($start, $end);

En el array @path encontraremos los vértices involucrados en el camino más corto.

Pintando el grafo

Una vez hallado el camino más corto entre dos vértices dados en un grafo dirigido con un costo en los arcos siempre positivos, lo que resta es hacer uso del módulo GraphViz, hacemos uso del constructor del objeto de la siguiente manera:

my $g = GraphViz->new();

Usted puede invocar al constructor con distintos atributos, para saber cuales usar le recomiendo leer la documentación del módulo.

Ahora bien, yo quería distinguir aquellos vértices involucrados en el camino más corto de aquellos que no pertenecían, así que lo más sencillo es generar una lista de atributos que será usada posteriormente. Por ejemplo:

my @shortest_path_attrs = (
				color => 'red',
			);

Una vez definidos los atributos, debemos generar cada uno de sus vértices y además, establecer los arcos entre cada uno de ellos. Para ello haremos uso de los métodos add_node, add_edge.

foreach my $key (keys %$hash){
	$g->add_node($key);
	foreach my $neighbor (keys %{$hash->{$key}}){
		$g->add_edge($key => $neighbor, label => $hash->{$key}->{$neighbor});
	}
}

El bloque de código anterior lo que hace es agregar cada uno de los vértices que se encuentran en el hash que representa la estructura del grafo, para cada uno de estos vértices, se añade cada uno de los arcos que lo conectan con sus vecinos, nótese el manejo del operador flecha (->) para desreferenciar las referencias al hash de hashes anónimos.

Una vez construidos los nodos y sus arcos, ¿cómo reconocer aquellos que pertenecen al camino más corto?, bueno, toda esa información la podemos extraer del array que hemos denominado @path.

for (my $count=0; $count < = $#path; $count++){
	$g->add_node($path[$count], @shortest_path_attrs);
	$g->add_edge($path[$count] => $path[$count+1], @shortest_path_attrs) unless ($count+1 > $#path);
}

Según dice la documentación del módulo GraphViz todos los atributos de un vértice del grafo no tienen que definirse de una sola vez, puede hacerse después, ya que las declaraciones sucesivas tienen efecto acumulativo, eso quiere decir lo siguiente:

$g->add_node('1', color => 'red');

Es equivalente a hacer las siguientes declaraciones sucesivas.

$g->add_node('1');
$g->add_node('1', color => 'red');

Lo que resta por hacer en este instante es exportar el objeto creado, puede crear por ejemplo un PNG, texto sin formato, PostScript, entre otros.

Yo decidí generar un fichero PostScript:

$g->as_ps("dijkstra.ps");

Por supuesto, les dejo una muestra de los resultados. Los vértices cuyo borde es rojo, son aquellos involucrados en el camino más corto desde el vértice inicio al vértice final, los arcos que marcan la ruta más corta también han sido coloreados.

Como siempre, todas las recomendaciones, comentarios, sugerencias son bienvenidas.

Perl y su poderío

Al igual que José, considero que el hilo de discusión Borrar línea X de un archivo es bastante interesante, este hilo fué discutido en la lista de correos técnica 1 del Grupo de Usuarios de Linux de Venezuela (VELUG), el problema planteado 2 consistía en eliminar un registro completo, en donde se pasara como argumento el primer campo (tal vez el identificador) de dicho registro.

Suponga que el fichero tiene la siguiente estructura:

:(123
	... # otros campos
)

:(234
	... # otros campos
)

:(456
	... # otros campos
)

Se dieron soluciones en lenguajes como Bash y C 3 y ciertas en Perl, éstas últimas son las que llaman mi atención, vamos por partes 4.

José propuso lo siguiente:

#!/usr/bin/perl -n
$deadCount = 7 if ($_ =~ /${ARGV[0]}/);
--$deadCount if ($deadCount);
print unless ($deadCount);

El programa debe ejecutarse así:

$ perl script.pl archivo 123

Este programa hace el trabajo, pero al final emitirá un error porque cree que el argumento 123 es otro fichero, y por supuesto, no lo encuenta.

Mi solución fue la siguiente:

perl -ne 'print unless /:\\(123/../\\)/' input.data > output.data

Por supuesto, en este caso solamente estaría eliminando el registro cuyo primer elemento es 123, funciona, pero genera un problema al igual que el hecho por José, se deja una línea de espacio vacía adicional en los registros, cuando el separador de los grupos de datos debe ser una 5 línea en blanco, tal cual como apunto Ernesto Hernández en una de sus respuestas.

Otro apunte realizado por el profesor Ernesto, fué que las soluciones presentadas hasta el momento de su intervención fué el análisis de fondo que estabamos haciendo, el problema no consistía en procesar cada una de las líneas, el trabajo en realidad consistía en analizar un registro multilínea (o párrafo), en términos más sencillos, cada grupo de datos (registros) está separado por una línea en blanco.

El profesor continuaba su excelente explicación diciendo que el problema se reduce al analizarlo de esta manera en lo siguiente:

…si se cuenta con un lenguaje de programación que está preparado para manejar el concepto de “registro” y puede definir el separador de registro como una línea en blanco, simplemente se trata de ignorar aquellos registros que tengan la expresión regular (X, donde X es la secuencia de dígitos que no nos interesa preservar.

La solución presentada por el profesor Ernesto fue:

perl -000 -i -ne 'print unless /\\(XXX/' archivo

En donde se debe sustituir las XXX por los dígitos cuyo bloque no nos interesa conservar.

De este hilo aprendí cosas nuevas de Perl, en realidad estoy comenzando, muchos pensarán que este código es críptico, por ello considero conveniente aclarar algunas cosas.

Lo críptico de un código no es inherente a un lenguaje particular, eso depende más del cómo se programe.

En este caso particular una sola línea de código nos proporciona mucha información, evidentemente para comprender dicho contenido es necesario leer previamente cierta documentación del lenguaje, pero ¿quien comienza a programar en un lenguaje en particular sin haber leído primero la documentación?, la respuesta parece lógica, ¿cierto?.

La existencia de opciones predefinidas y maneras de ejecutar el interprete de Perl permiten enfocarse únicamente en la resolucion de tareas, cero burocracia.

Un ejemplo de lo mencionado en el párrafo anterior es el siguiente, un bucle lo puedo reducir con la opción de ejecución -n del interprete Perl, simplemente leyendo un poco perlrun6 nos enteramos del asunto, eso quiere decir que podemos reducir a una simple opción de ejecución del interprete de Perl todo esto:

#!/usr/bin/perl
while(<>){
#...
}

¿Qué es ese operador que parece un “platillo volador” 7 (null filehandle)?, bueno, lea perlop, en especial la sección I/O Operators.

La opción -i me permite editar (reescribir) in situ el fichero que vamos a procesar, en el caso de no añadir una extensión no se realizara un respaldo del fichero, el fichero original se sobreescribe. Mayor detalle en perlrun.

Lo que si no sabía hasta ahora, es lo explicado por el profesor acerca de los párrafos (registros multilínea) en Unix, la opción -0 tiene un valor especial, el cual es 00, si este valor es suministrado hace que Perl entre en “modo párrafo”, en pocas palabras, se reconoce una línea en blanco como el separador de los registros.

El resto del código es solo manejo de una sencilla expresión regular, se asume que el lector conoce algo del tema, solo indica el registro que queremos ignorar.

Así que podemos concluir lo siguiente, Perl no es críptico, asumiendo que el programador ha leido suficiente documentación acerca del lenguaje en cuestión, evitamos la burocracia y atendemos el problema de raíz en el menor tiempo posible.

La solución que propone Perl con el lema Hay más de una manera de hacerlo, es ofrecerle al programador libertad en su forma de expresarse, ¿acaso todos hablamos el mismo idioma?, ¿acaso debemos seguir las malas prácticas que intenta difundir el maligno Java?, coartar el pensar del programador y obligarlo a hacer las cosas al estilo Java, ¿dónde queda la imaginación? 8, ¿paso a ser un lujo?.

A todos los que lo deseen, les invito a participar en la lista de correos técnica (l-linux) del Grupo de Usuarios de Linux de Venezuela (VELUG), les recomiendo leer detenidamente las normas de uso antes de inscribirse en la lista.

  1. l-linux es la la lista de correos para Consultas Técnicas sobre Linux y Software Libre en VELUG[regresar]
  2. Quien inicio el hilo de discusión fue José Luis Bazo Villasante[regresar]
  3. ¿Con intención de autoflagelación?[regresar]
  4. Diría Jack El Destripador[regresar]
  5. No dos, ni tres, …[regresar]
  6. man perlrun, perlrun se incluye en la documentación de Perl, en sistemas Debian lo encontramos en el paquete perl-doc, para instalar simplemente hacer ejecutar el comando aptitude install perl-doc como superusuario[regresar]
  7. Según nos conto José Luis Rey, el profesor Ernesto Hernández le llama así de manera informal[regresar]
  8. De hecho, se dice que, un programador experto en Java está muy cerca de convertirse en un autómata[regresar]

FeedJack: Ya está disponible

Ya había comentado acerca de ésta aplicación en la entrada FeedJack: Un Planet con esteroides, resulta que hace pocos días Gustavo Picón anunció la salida de la versión 0.9.6 bajo licencia BSD. Algunas de las características más resaltantes de esta aplicación son:

Soporte de virtual hosts
Esto quiere decir que desde la misma instalación y la misma Base de Datos e interfaz de administración, se manejan múltiples planetas. Si hay feeds en común estos se bajan una sola vez para optimizar recursos.
Temas (Themes)
Cada sitio (virtual host) puede tener temas distintos.
Soporte de folcsonomías (etiquetas o tags)
Muy popular en las aplicaciones de la Web 2.0, se ha optimizado el algoritmo.
Generación de páginas o feeds por folcsonomías
Ejemplo: http://www.chichaplanet.org/tag/django/
Generación de páginas o feeds por miembros
Ejemplo: http://www.chichaplanet.org/user/1/
Generación de páginas o feeds de una categoría en especial de un miembro particular
Ejemplo: http://www.chichaplanet.org/user/1/tag/django/
Generar un feed general.
Ejemplo: http://www.chichaplanet.org/feed/
Histórico de entradas
Entre muchas otras cosas. La principal ventaja frente a Planet es el soporte de un histórico de entradas o posts, por el uso de una Base de Datos.

Para conocer los detalles acerca de los requerimientos, el proceso de instalación, configuración y la modificación de los temas lea con detenimiento la entrada Feedjack - A Django+Python Powered Feed Aggregator (Planet).

Ya que le he quedado un poco mal a Gustavo con la ayuda que me pidio en cuanto al desarrollo de un tema (theme) para FeedJack, invito a mis dos ó tres lectores a colaborar con el proyecto.

Por mi parte solo me queda felicitar a Gustavo Picón por el estupendo trabajo que ha realizado. Además, amigo, aprovecho el momento para decirte que cuentas con mi ayuda para el desarrollo de un theme, solo dame tiempo mientras me desocupo de las actividades en la Universidad, estas últimas semanas han estado muy ocupadas. Entre las asignaturas: Redes de Computadoras, Programación Paralela y Distribuida, Compiladores (menos mal al profesor de Inteligencia Artificial no le ha dado por colocarnos un parcial), si a eso le sumas, el estudio de Haskell y Alex, están contribuyendo sistemáticamente en mi demencia.

Perl: Primeras experiencias

La noche del sábado pasado, después de terminar de estudiar con Ana la cátedra Programación Paralela y Distribuida, me dispuse a revisar las distintas instancias de Planeta Linux, como normalmente hago, pero eso no fué suficiente, me puse a validar el feed que se estaba generando en ese momento (en particular, el feed de la instancia venezolana). Me percate de varios errores y advertencias, entre ellos me llamo la atención:

This feed does not validate.

In addition, this feed has an issue that may cause problems for some users. We recommend fixing this issue.

line 11, column 71: title should not contain HTML (20 occurrences) [help]

Luego de leer la ayuda noto que es recomendable cambiar todos los nombres de las entidades html a su equivalente decimal, es decir, si tenemos por ejemplo: &copy; debe modificarse &#169;, de igual manera con el resto.

Tenía varias opciones, una de ellas era realizar el reemplazo masivo desde vim, pero esta tarea es realmente ineficiente por el hecho de tener que reemplazar todos los nombres de las entidades html a su equivalente decimal uno por uno, además de eso, debía hacerlo para las tres instancias presentes en Planeta Linux, primera opción descartada de entrada.

Aprovechando que la semana pasada, al igual que el profesor Francisco Palm, estuve presente en un curso sobre el lenguaje de programación Perl, el cual fué dictado por José Luis Rey con la ayuda de Daniel Rodríguez en las instalaciones de Fundacite Mérida, quería poner en práctica algunas de las cosas que aprendí en dicho curso.

Antes de continuar debo agradecer al profesor José Aguilar, a la ingeniera Blanca Abraham, y a la Sra. Tauka Shults por la oportunidad que me brindaron.

Una de las cosas que nos recalcó José Luis fué acerca de las virtudes que debía tener un programador, una de ellas debe ser la flojera, es decir, comenzar a escribir código realmente útil de inmediato, sin ningún requerimiento adicional como ocurre en lenguajes de programación como el C/C++, en donde es necesario realizar una serie de procedimientos antes de comenzar a escribir código útil.

Como mencione en el párrafo anterior, la idea es llegar a ser lo más productivo en el menor tiempo posible. Generar un hash de entidades de nombres html no me parecía el camino idóneo, así que recorde el tema de la flojera, sin pensarlo dos veces comence a buscar en search.cpan.org un módulo que me permitiera convertir los nombres de las entidades html a su equivalente decimal, como primer resultado obtuve lo que buscaba, el módulo HTML::Entities::Numbered, había encontrado mi salvación, leo un poco acerca de su uso y es más sencillo de lo que pensaba, siguiente paso, proceder a instalarlo.

Para debianizar un módulo en Perl es muy sencillo, en primer lugar debemos recurrir al comando dh-make-perl, si no lo tenemos instalado ya, debemos proceder como sigue:

# aptitude install dh-make-perl

Ahora ya podemos debianizar el módulo que requerimos, para ello tuve que realizar lo siguiente:

# dh-make-perl --build --cpan HTML::Entities::Numbered

Como lo puede apreciar, su uso es realmente sencillo, para una mejor explicación acerca de este último comando le recomiendo leer la entrada Instalando módulos de Perl en Debian escrita por Christian Sánchez, como era la primera vez que hacia uso del comando cpan tuve que configurarlo, esto no tomo mucho tiempo, el asistente ofrece explicaciones bastante detalladas.

Una vez realizado el proceso más complicado de toda la operación, el resto era escribir el código fuente que me permitiese convertir los nombres de las entidades html a su equivalente decimal, he aquí el resultado.

#!/usr/bin/perl -l

use strict;
use warnings;
use HTML::Entities::Numbered;

unless(open(INPUT, $ARGV[0])) { die "ERROR: No se especifico archivo para abrir. $!"; }
open(OUTPUT, ">$ARGV[0].bak");
while(<INPUT>){ print OUTPUT name2decimal($_) if chomp; }

¡Listo!, en tan pocas líneas de código he logrado resolver el problema, por supuesto, todo se redujo a buscar el módulo apropiado, una vez hecho los cambios a los ficheros de configuración de Planeta Linux procedí a actualizar la última versión en subversion.

Puede apreciar el antes y después de los cambios realizados.

Breve reseña del FLISOL 2006, Capítulo Mérida-Venezuela

Al llegar a eso de las 9:30 a.m. (hora local) estaban transmitiendo el video Trusted Computing (subtítulos español), un excelente video en donde nos muestran cuan peligroso puede ser la “mala interpretación” que tiene la industria acerca del concepto “Trusted Computing”, modelo en el cual la industria no le permite a los usuarios (comunidad) elegir entre lo que ellos consideran malo o nó, el problema es que ya deciden por tí, simplemente porque la industria no confía en nosotros.

Después de mostrar el video, Hector Colina, uno de los coordinadores del evento, procedió a dar la bienvenida a los asistentes al II Festival Latinoamericano de Instalación de Software Libre, capítulo Mérida, Venezuela. De inmediato, Hector continúo hablando y nos sorprendió con una charla denominada Software Libre y Libre Empresa, en donde nos hablaba de la interesante filosofía detrás del modelo de Software Libre, algunos piensan equivocadamente que bajo el esquema de Software Libre no se es posible generar ganancias, se demostró que es posible hacerlo. También hablo sobre las ventajas técnicas que brinda el Software Libre frente al Software Privativo.

Posteriormente se dió comienzo a las demostraciones de LTSP (Linux Terminal Server Project) por parte de José David Gutierrez, quien también coordinó el evento y es miembro de la Cooperativa AndiNuX, no recuerdo en este instante cuales eran las características que poseía el servidor, pero recuerdo que el cliente sobre el cual se hizo la demostración tenía apenas 40 MB de RAM (sí, leyo bien, 40 MB) y se logró levantar el entorno de escritorio KDE y ejecutar algunas aplicaciones, José comentaba que los requisitos mínimos de memoria RAM eran 16, mientras que lo óptimo erán 32 MB de RAM, así que amigo, si usted esta leyendo esto, no bote su potecito (equipo de bajo recursos de hardware), bajo el esquema de Software Libre podemos recuperarlo, quizá podría donarlo y regalarle una sonrisa a un niño que reciba educación en una escuela con pocos recursos.

Posteriormente comenzaron a colocar algunos videos a los asistentes, entre los cuales recuerdo haber visto Revolution OS, en paralelo, se realizaba el proceso de instalación desde tempranas horas de la mañana, al final de la jornada se lograron contabilizar más de 20 máquinas a las cuales se instaló GNU/Linux, incluyendo potecitos de 32 MB de RAM hasta máquinas de escritorio con procesadores de 64 bits, por supuesto, a una que otra portátil también se le instaló GNU/Linux, además, se regalaron CDs de Debian, Ubuntu, entre otros.

En la tarde el profesor Francisco Palm comenzó su charla Carpintería del Software Libre: un enfoque desde el lenguaje de Programación Python, en ella se nos hace reflexionar acerca de nuestra realidad actual en Venezuela, presentamos poca penetración de internet en nuestra sociedad. Bajo el esquema de Software Privativo, no se le brinda apoyo a la comunidad, no se presenta una innovación alguna.

El profesor Palm también converso sobre puntos interesantes acerca de la Ingeniería de Software Libre, como la Fundación Apache, Debian o Mozilla no presentan certificaciones y no les importa éste hecho en particular, puesto que su desarrollo es robusto, de hecho, muestran como funcionan por dentro. Entre otras cosas bastante interesantes.

Enseguida comenzaron otra charla 2 pupilos del profesor Palm, Diego Díaz y Freddy López, en donde se expuso el Proyecto SIGMA: Soluciones Libres para el mundo Científico, en esta charla pudimos observar una serie de demostraciones del sistema estadistico R. El proyecto SIGMA resulta de una iniciativa de los miembros de la Escuela de Estadística y el Instituto de Estadística Aplicada y Computación (IEAC) de la Universidad de Los Andes.

Sin mucho receso, Leonardo Caballero comenzó su charla acerca de Desarrollo Web con Mozilla FireFox, aca se explicó acerca de las extensiones que resultan muy útiles al desarrollador de páginas web, como por ejemplo, la extensión Web Developer, de manera adicional, se demostró cuan personalizable (desde utilizar temas hasta incluso simular comportarse como otro navegador) puede ser Firefox para un usuario particular, desde extensiones para el clima (ForecastFox) hasta herramientas de blogging.

Particularmente, para el desarrollo web utilizo más extensiones de las que mencionó Leonardo, entre ellas puedo mencionar: CSS Validator, ColorZilla, entre otras. Prefiero no continuar mencionando la lista de extensiones que poseo, se supone que sea una breve reseña, quizá en otro artículo hablaremos acerca de las extensiones de Firefox.

Un poco más tarde, el licenciado Axel Pizzi, quien pertenece a la agencia de traducción y servicios lingüisticos translinguas, conversó acerca del uso de herramientas CAT (Computer aided Translation) bajo el esquema de Software Libre, simplemente se mostraba las bondades de la traducción asistida por computadora, es una manera de traducir contenido en donde el ser humano (traductor) utiliza software diseñado para brindar soporte y facilitar ésta ardua tarea.

Algo nervioso se encontraba Jesús Rivero (no confundir con neurogeek, ok?), pues se estaba haciendo tarde para su charla, Cooperativismo y Software Libre, en donde Jesús mostró como el esquema de desarrollo colaborativo es sumamente útil en las Cooperativas.

Y ya para finalizar la jornada, comence mi charla sobre Desarrolo Web en Python utilizando el framework Django, a manera de introducción, comence a hablar del lenguaje de programación Python, sus bondades, que empresas le utilizan actualmente y que proyectos han desarrollado, entre dicha lista se incluyen las siguientes: Google, Yahoo!, empresas farmacéuticas (AstraZeneca) de gran escala mundial, Industrial Light & Magic (sí, esa misma que está pensando, es la empresa iniciada por George Lucas en el año de 1.975, la encargada de los efectos especiales de la saga “Star Wars”, no solo eso, en su lista se incluyen películas como “Forrest Gump”, “Jurassic Park”, “Terminator 2”, entre otros).

Posteriormente comence a adentrarme ya en el tema que me interesaba, Desarrollo Web, en mi caso particular, hable sobre como utilizar el framework Django, desde la instalación del framework, la instalación de PostgreSQL (recomendada) y del adaptador a dicha base de datos en python, psycopg, hasta la construcción de la aplicación. Para mayor detalle acerca de esta presentación solo esperen un próxima entrada, quisiera ampliar algunos tópicos para dejarlos un poco más claros.

Si desean ver algunas fotos que logré tomar del II Festival Latinoamericano de Instalación de Software Libre (FLISOL), Capítulo Mérida - Venezuela, pueden revisar el set de fotos FLISOL 2006 de mi cuenta en flickr.

Debo confesar que estaba bastante nervioso al principio porque era mi primera charla. Espero que todo haya salido bien y les haya gustado.

Bueno, finalizamos las actividades como a las 7:30 p.m. (hora local), luego de ello ayudamos a los muchachos a acomodar las cosas y guardarlas en las oficinas de Fundacite Mérida.

Desde mi punto de vista, ha sido una grata experiencia, cualquier corrección a la reseña es bienvenida, pido disculpas si he dejado a alguien por fuera, esta reseña no estaba anotada en ningún medio escrito, solo he comenzado a describir las situaciones que recuerdo, lo más seguro es que olvide algún detalle importante, andaba un poco distraído instalando Debian y Ubuntu en el Festival.

Por supuesto, cualquier corrección, crítica constructiva acerca de la charla que dí se los agradecería, todo sea por mejorar dicho material y publicarlo, por supuesto, manteniendo una licencia libre.

FeedJack: Un Planet con esteroides

FeedJack es una mejora hecha por Gustavo Picon (a.k.a. tabo) del muy conocido Planet, la mejor muestra de la funcionalidad de este software se puede apreciar en el planeta peruano ChichaPlanet.

Gustavo Picon, autor del reemplazo del Planet en Django, afirma que el código fuente todavía no está disponible, pero piensa hacerlo público bajo el esquema de código abierto tan pronto logre depurarlo un poco y redacte cierta documentación, coincido con el autor cuando éste afirma que: si un software no posee documentación, no existe.

FeedJack ofrece algunas características que le dan cierta ventaja sobre el Planet, algunas de ellas son:

  • Maneja datos históricos. Por lo tanto, usted puede leer entradas antiguas.
  • Realiza un análisis más exhaustivo de las entradas, incluyendo sus categorías.
  • Es capaz de generar páginas de acuerdo a las categorías de las entradas.
  • Brinda soporte al sistema de folcsonomías (etiquetas), opción muy popular en la Web 2.0.
  • Utiliza el lenguaje de plantillas de Django

Mayor información y detalle en la entrada Django powered chicha planet with feedjack, de Gustavo Picon.

Charla sobre el lenguaje de programación Python

La ingeniera Andrea Muñoz me notifica que el día Jueves 23 de Febrero se estará llevando a cabo la charla Carpintería del Software Libre, un enfoque desde el lenguaje de programación Python, en donde el ponente será el profesor Francisco Palm, seguramente estará muy interesante.

La cita es el día 23 de Febrero, a las 8:30 a.m. en el Núcleo La Hechicera, Facultad de Ingeniería, Nivel Patio, Ala Sur, Labtel II, Estado Mérida (Venezuela).

La invitación es realizada por el Consejo de Computación Académica (CCA) de la Universidad de Los Andes, gracias al espacio que ofrecen para la difusión del Software Libre, “Jueves Libre”

Desgraciadamente hasta ahora no puedo asistir a la charla, debo presentar un examen de Ingeniería del Software el mismo día, a la misma hora. Trataré de hablar con Jesús Molina o Andrea Muñoz para ver si puede grabarse en algún medio permanente esta charla.

Clientes BitTorrent

Desde mi punto de vista Azureus es un cliente BitTorrent que cae en los excesos, aparte de ello es demasiado lento y por si fuera poco consume una gran cantidad de recursos del sistema.

Si usted es usuario de Ubuntu Linux, seguramente estará preguntándose, ¿por qué buscar un cliente BitTorrent si Breezy incluye uno? , bueno, si le soy sincero, ese cliente apesta, tiene muy pocas opciones.

En los siguientes párrafos veremos dos alternativas, que desde mi punto de vista tienen ciertas virtudes, las cuales muestro a continuación.

  • No caen en los excesos.
  • Son rápidos.
  • No consumen gran cantidad de recursos del sistema.
  • Ofrecen muchas opciones.

Sin mas preámbulos, les presento a Rufus y freeloader, clientes BitTorrents alternativos de gran envergadura.

FreeLoader

Freeloader, es un manejador de descargas escrito en Python y brinda soporte a torrents.

Para instalar freeloader debemos seguir los siguientes pasos en Breezy.

sudo aptitude install python-gnome2-extras python2.4-gamin

Seguidamente diríjase al sitio oficial de freeloader y descargue las fuentes del programa, para la fecha en la cual se redactó este artículo la versión más reciente de este programa es la 0.3.

wget http://www.ruinedsoft.com/freeloader/freeloader-0.3.tar.bz2

Luego de haber descargado el paquete proceda de la siguiente manera:

$ tar xvjf freeloader-0.3.tar.bz2
$ cd freeloader-0.3
$ ./configure
$ make
$ sudo make install

Recuerde que para poder compilar paquetes desde las fuentes necesita tener instalado previamente el paquete build-essential

Rufus

Rufus es otro cliente BitTorrent escrito en Python.

Vamos a aprovecharnos del hecho que existe una versión estable (0.6.9) compilada * para Breezy, los pasos son los siguientes:

$ wget http://strikeforce.dyndns.org/files/breezy/rufus.0.6.9/rufus_0.6.9-0ubuntu1_i386.deb
$ sudo dpkg -i rufus_0.6.9-0ubuntu1_i386.deb

* Esta versión ha sido compilada por strikeforce, para mayor información lea el hilo Rufus .deb Package.