Monthly Archives: June 2009

Migración de Drupal 5 a la versión 6

Introducción.

Después de utilizar la versión 5 de Drupal por un par de años he decidido que es hora de utilizar la nueva versión; estando relativamente próximos a la versión 7, la estabilidad y disponibilidad de módulos de la versión 6 debe ser suficiente.  Para probar la nueva versión inicié un ejercicio de migración un tanto extraño, quise copiar de la base de datos únicamente las tablas y los registros que fueran necesarios para la instalación fresca.  Al respecto encontré alguna poca información útil pero no lo suficientemente amplia y al incluírse también a los Grupos Orgánicos todos empezó a fallar.

Una segunda aproximación, un tanto mas estándar, fue la de realizar una copia de un sitio versión 5, reemplazar los archivos con la versión 6 y utilizar las facilidades de actualización de la nueva versión.  Con este método no puedo estar seguro de que la base de datos termine con únicamente lo necesario pero es relativamente mas fácil de implementar.

Hasta ahora considero que el producto final de la migración ha sido exitoso aunque no he realizado pruebas exhaustivas, sin embargo hay algo para hacer notas: de todos los módulos utilizados el único inexistente para la versión 6 fue Gallery for Organic Groups lo que me deja algo por definir aún acerca de la idoneidad de su uso en el proyecto que estaba desarrollando.

Procedimiento.

- Realice una copia de seguridad de la base de datos y de los archivos del sitio basado en Drupal 5.

En mi caso, la experimentación la realicé sobre una copia del sitio que establecí a partir de la copia de seguridad.

- Inicie sesión con el usuario administrador (cuyo ID = 1).

- Si la dirección es pública, es recomendable poner el sitio en modo fuera de línea (offline).

- Actualizar Drupal y sus módulos a la última versión disponible.  Ver procedimiento estándar.

- Tome nota de cuales son los módulos que se encuentran instalados y cuales se encuentran activos.

- Remueva los módulos no deseados, tanto desactivándolos como removiendo sus archivos de sites/all/modules o sites/default/modules según sea el caso.

- Desactive los módulos de terceros, es decir, los que no sean de Core.  Verifique especialmente el desactivar el módulo de Update Status.

- Cambie el tema activo a uno incluído en la distribución de Drupal como por ejemplo, Garland.

- Descargue la última distribución disponible de Drupal y de la traducción al español siguiendo estos pasos.

$ mv v2 v2.old
$ wget http://ftp.drupal.org/files/projects/drupal-6.12.tar.gz
$ tar zxvf drupal-6.12.tar.gz
$ mv drupal-6.12 v2

En el experimento realizado el directorio con la versión 5 de Drupal es site/ mientras que directorio objetivo, donde se instalará el nuevo portal con la versión 6 será v2/.  De igual manera, la versión de Drupal disponible en el momento era la 6.12, sin embargo se deberá utilizar la última disponible en el sitio web.

- Descargue la última versión disponible para el paquete de idiomas en español del sitio: http://drupal.org/project/translations?text=spanish.

$ cd v2
$ wget http://ftp.drupal.org/files/projects/es-6.x-1.3.tar.gz
$ tar zxvf es-6.x-1.3.tar.gz
$ rm es-6.x-1.3.tar.gz

- Establezca el archivo base de la configuración.

$ cp ./sites/default/default.settings.php ./sites/default/settings.php
$ chmod 777 ./sites/default/settings.php

- Acceda al sitio web en instalación para iniciar la configuración del nuevo sitio a través de la siguiente dirección: http://www.servidor.com/v2.

Choose language = Spanish (Español)

- Establezca la configuración de la base de datos.

Nombre de la base de datos: <DATABASE NAME>
Usuario de la base de datos: <DATABASE USERNAME>
Contraseña de la base de datos: <DATABASE PASSWORD>
Servidor de la base de datos: <DATABASE HOST>
Prefijo de las tablas: <DATABASE TABLE PREFIX>

- En este punto se deben generar muchos errores de la base de datos debido a que la estructura de las tablas corresponde a la versión anterior, por este motivo se debe realizar el siguiente proceso tantas veces como sea necesario hasta que ya no se generen errores.

Para actualizar la base de datos visitar la siguiente ubicación: http://www.servidor.com/v2/update.php.

- Active desde http://www.servidor.com/v2/?q=admin/build/modules los módulos de Core requeridos.  En caso eran: Comment, Contact, Database logging, Forum, Help, Locale, Menu, PHP Filter, Profile, Search, Statistics, Taxonomy, Update Status y Upload.

- Copie los archivos del sitio.

$ cp -rf ../site/files/* ./files

- Cree el directorio para el almacenamiento de los módulos de terceros.

$ cd sites/all
$ mkdir modules
$ cd modules

- Instale los módulos de terceros que considere convenientes.

Cuando se instalen módulos para la versión 6 que estaban presentes en el portal con la versión 5 es conveniente realizar la actualización de base de datos en la siguiente ubicación: http://www.servidor.com/v2/update.php.  Muy probablemente sea posible agrupar la instalación de varios módulos y realizar una única o pocas actualizaciones de la base de datos, sin embargo yo prefiero hacerlo uno a uno para verificar que no existan problemas específicos.

En mi caso particular se instalaron los siguientes módulos.

Vistas (http://drupal.org/project/views).

$ wget http://ftp.drupal.org/files/projects/views-6.x-2.6.tar.gz
$ tar zxvf views-6.x-2.6.tar.gz
$ rm views-6.x-2.6.tar.gz

Activar los módulos Views, Views Exporter y Views UI, y realizar la actualización de la base de datos.

Grupos orgánicos (http://drupal.org/project/og).

$ wget http://ftp.drupal.org/files/projects/og-6.x-1.3.tar.gz
$ tar zxvf og-6.x-1.3.tar.gz
$ rm og-6.x-1.3.tar.gz

Activar los módulos Organic Groups, Organic Groups Access Control y Organic Groups Views Integration, y realizar la actualización de la base de datos.

Integración con Piwik (http://drupal.org/project/piwik).

$ wget http://ftp.drupal.org/files/projects/piwik-6.x-1.1.tar.gz
$ tar zxvf piwik-6.x-1.1.tar.gz
$ rm piwik-6.x-1.1.tar.gz

Activar los módulos Piwik web analytics y piwik – reports, y realizar la actualización de la base de datos.

Mapa del sitio XML (http://drupal.org/project/xmlsitemap).

$ wget http://ftp.drupal.org/files/projects/xmlsitemap-6.x-1.0-beta5.tar.gz
$ tar zxvf xmlsitemap-6.x-1.0-beta5.tar.gz
$ rm xmlsitemap-6.x-1.0-beta5.tar.gz

Activar los módulos XML Sitemap, XML Sitemap engines y XML Sitemap node, y realizar la actualización de la base de datos.

Web File Manager (http://drupal.org/project/webfm).

$ wget http://ftp.drupal.org/files/projects/webfm-6.x-2.10-rc4.tar.gz
$ tar zxvf webfm-6.x-2.10-rc4.tar.gz
$ rm webfm-6.x-2.10-rc4.tar.gz

Activar los módulos Web File Manager, WebFM Image y WebFM Popup, y realizar la actualización de la base de datos.

En mis sitios he notado que este módulo falla para encontrar las imágenes cuando este se instala en sites/all/modules (como se debería hacer) en lugar de modules (como no se debería hacer).  Este problema se soluciona creando un enlace para este módulo.

$ ln -s <RUTA ABSOLUTA>/v2/sites/all/modules/webfm <RUTA ABSOLUTA>/v2/modules/webfm

Poormans Cron (http://drupal.org/project/poormanscron).

$ wget http://ftp.drupal.org/files/projects/poormanscron-6.x-1.0.tar.gz
$ tar zxvf poormanscron-6.x-1.0.tar.gz
$ rm poormanscron-6.x-1.0.tar.gz

Activar el módulo Poormanscron y realizar la actualización de la base de datos.

Mapa del sitio (http://drupal.org/project/site_map).

$ wget http://ftp.drupal.org/files/projects/site_map-6.x-1.0.tar.gz
$ tar zxvf site_map-6.x-1.0.tar.gz
$ rm site_map-6.x-1.0.tar.gz

Activar el módulo Site map y realizar la actualización de la base de datos.

Integración con Google Analytics (http://drupal.org/project/google_analytics).

$ wget http://ftp.drupal.org/files/projects/google_analytics-6.x-2.2.tar.gz
$ tar zxvf google_analytics-6.x-2.2.tar.gz
$ rm google_analytics-6.x-2.2.tar.gz

Activar el módulo Google Analytics y realizar la actualización de la base de datos.

Auto Logout (http://drupal.org/project/autologout).

$ wget http://ftp.drupal.org/files/projects/autologout-6.x-1.5.tar.gz
$ tar zxvf autologout-6.x-1.5.tar.gz
$ rm autologout-6.x-1.5.tar.gz

Activar el módulo Autologout y realizar la actualización de la base de datos.

Integración con TinyMCE.

Instalación de TinyMCE (http://tinymce.moxiecode.com/download.php).

$ mkdir -p v2/sites/all/libraries/tinymce
$ cd v2/sites/all/libraries/tinymce
$ wget http://prdownloads.sourceforge.net/tinymce/tinymce_3_2_4_1.zip?download
$ unzip tinymce_3_2_4_1.zip
$ rm tinymce_3_2_4_1.zip

Instalación del paquete de idiomas de TinyMCE (http://tinymce.moxiecode.com/download_i18n.php).

Descargar tinymce_lang_pack.zip con el idioma requerido.

$ cd jscripts/tiny_mce/
$ unzip ../../tinymce_lang_pack.zip
$ cd ../..
$ rm tinymce_lang_pack.zip

API del módulo WYSIWYG (http://drupal.org/project/wysiwyg).

$ wget http://ftp.drupal.org/files/projects/wysiwyg-6.x-2.0.tar.gz
$ tar zxvf wysiwyg-6.x-2.0.tar.gz
$ rm wysiwyg-6.x-2.0.tar.gz

Activar el módulo Wysiwyg.

Configuración del módulo Wysiwyg: Asociación con los formatos de entrada.

Visite http://www.servidor.com/v2/?q=admin/settings/wysiwyg.

Filtered HTML: TinyMCE
PHP code: No editor
Full HTML: TinyMCE

$ cd <RUTA ABSOLUTA>/v2/sites/all/modules

Captcha (http://drupal.org/project/captcha).

$ wget http://ftp.drupal.org/files/projects/captcha-6.x-1.0-rc2.tar.gz
$ tar zxvf captcha-6.x-1.0-rc2.tar.gz
$ rm captcha-6.x-1.0-rc2.tar.gz

Activar los módulos Captcha, Image Captcha, y realizar la actualización de la base de datos.

Realizar la configuración del módulo en http://www.servidor.com/v2/?q=admin/user/captcha.

Nombre real (http://drupal.org/project/realname).

$ wget http://ftp.drupal.org/files/projects/realname-6.x-1.2.tar.gz
$ tar zxvf realname-6.x-1.2.tar.gz
$ rm realname-6.x-1.2.tar.gz

Activar el módulo RealName.

Módulo de soporte para imágenes (http://drupal.org/project/image).

$ wget http://ftp.drupal.org/files/projects/image-6.x-1.0-alpha4.tar.gz
$ tar zxvf image-6.x-1.0-alpha4.tar.gz
$ rm image-6.x-1.0-alpha4.tar.gz

Activar el módulo Image.

Image Assistant for Wysiwyg  (http://drupal.org/project/img_assist).

$ wget http://ftp.drupal.org/files/projects/img_assist-6.x-2.0-alpha3.tar.gz
$ tar zxvf img_assist-6.x-2.0-alpha3.tar.gz
$ rm img_assist-6.x-2.0-alpha3.tar.gz

Activar el módulo Image assist.

Modificar el filtro de HTML restringido para permitir el uso de etiquetas de imagen.

Visitar http://www.servidor.com/v2/?q=admin/settings/filters.

Filtered HTML > Configurar
Configurar
Etiquetas HTML Permitidas += <span> <img>
Guardar la configuración

Configurar los permisos de acceso al módulo en http://www.servidor.com/v2/?q=admin/user/permissions.

IMCE for TinyMCE (http://drupal.org/project/imce).

$ wget http://ftp.drupal.org/files/projects/imce-6.x-1.2.tar.gz
$ tar zxvf imce-6.x-1.2.tar.gz
$ rm imce-6.x-1.2.tar.gz

Activar el módulo IMCE y realizar la actualización de la base de datos.

Puente IMCE para Wysiwyg (http://drupal.org/project/imce_wysiwyg).

$ wget http://ftp.drupal.org/files/projects/imce_wysiwyg-6.x-1.0.tar.gz
$ tar zxvf imce_wysiwyg-6.x-1.0.tar.gz
$ rm imce_wysiwyg-6.x-1.0.tar.gz

Activar el módulo IMCE Wysiwyg API bridge.

Enlaces web (http://drupal.org/project/weblinks).

$ wget http://ftp.drupal.org/files/projects/weblinks-6.x-2.0.tar.gz
$ tar zxvf weblinks-6.x-2.0.tar.gz
$ rm weblinks-6.x-2.0.tar.gz

Activar los módulos Web Links y Web Links Checker, y realizar la actualización de la base de datos.

Content Construction Kit (http://drupal.org/project/cck).

$ wget http://ftp.drupal.org/files/projects/cck-6.x-2.4.tar.gz
$ tar zxvf cck-6.x-2.4.tar.gz
$ rm cck-6.x-2.4.tar.gz

Activar los módulos Content y Text, y realizar la actualización de la base de datos.

Javascript tools (http://drupal.org/project/jstools).

$ wget http://ftp.drupal.org/files/projects/jstools-6.x-1.0.tar.gz
$ tar zxvf jstools-6.x-1.0.tar.gz
$ rm jstools-6.x-1.0.tar.gz

Activar el módulo Javascript tools y realizar la actualización de la base de datos.

Menúes activos – depende de jstools (http://drupal.org/project/activemenu).

$ wget http://ftp.drupal.org/files/projects/activemenu-6.x-1.x-dev.tar.gz
$ tar zxvf activemenu-6.x-1.x-dev.tar.gz
$ rm activemenu-6.x-1.x-dev.tar.gz

Activar el módulo Active menu y realizar la actualización de la base de datos.

Módulo de soporte para eventos (http://drupal.org/project/event).

$ wget http://ftp.drupal.org/files/projects/event-6.x-2.x-dev.tar.gz
$ tar zxvf event-6.x-2.x-dev.tar.gz
$ rm event-6.x-2.x-dev.tar.gz

Activar el módulo Event y realizar la actualización de la base de datos.

Organic Groups Calendar (http://drupal.org/project/og_calendar).

$ wget http://ftp.drupal.org/files/projects/og_calendar-6.x-1.0.tar.gz
$ tar zxvf og_calendar-6.x-1.0.tar.gz
$ rm og_calendar-6.x-1.0.tar.gz

Activar el módulo OG Calendar y realizar la actualización de la base de datos.

Organic Groups User Roles (http://drupal.org/project/og_user_roles).

$ wget http://ftp.drupal.org/files/projects/og_user_roles-6.x-1.5.tar.gz
$ tar zxvf og_user_roles-6.x-1.5.tar.gz
$ rm og_user_roles-6.x-1.5.tar.gz

Activar el módulo OG User Roles y realizar la actualización de la base de datos.

Realice la reconstrucción de los permisos en la nueva versión de Drupal visitando el siguiente enlace: http://www.servidor.com/v2/?q=admin/content/node-settings/rebuild.

Comunicación de la tarjeta Arduino con el computador

Introducción.

La tarjeta Arduino incluye un puerto serial que puede accederse a través de los pines digitales 0 (RX) y 1 (TX) o desde el computador a través del puerto USB.  Esto se realiza a través del objeto Serial con el que es posible realizar las siguientes acciones.

Descripción general de las funciones de E/S.

Establecer tasa de transmisión de datos.

void Serial.begin(int velocidad);
  • Debe realizarse como paso previo a la emisión/recepción de información a través del puerto serial.
  • La tasa puede ser una de las estándar: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 y 115200, o cualquiera personalizada.
  • La velocidad utilizada para realizar la conexión con el computador es de 9600.

Verificar bytes pendientes por lectura.

int Serial.available();
  • Como su nombre lo indica, la transmisión de información a través del puerto serial se realiza de manera serial, es decir un byte a la vez.
  • Este método permite verificar si hay bytes pendientes de lectura retornando el número de bytes disponibles en el buffer del puerto serial.
  • El buffer del puerto serial puede retener hasta 128 bytes.
  • Retorna 0 si no hay bytes pendientes de lectura en el puerto.

Leer información.

int Serial.read();
  • Obtiene el siguiente byte disponible en el buffer del puerto serial.
  • Retorna -1 si no hay información disponible.

Limpiar el buffer de entrada.

void Serial.flush();
  • Limpia el buffer de entrada del puerto serial, descartando cualquier contenido que se encuentre allí.

Enviar información.

void Serial.print(datos);
void Serial.print(datos, tipo);
void Serial.println(datos);
void Serial.println(datos, tipo);
  • Envían la información (datos) en el formato especificado (tipo) a través del puerto serial.
  • El formato (tipo) puede ser uno de los siguientes.
    • DEC: representación en cadena de un número decimal (79).
    • HEX: representación en cadena de un número hexadecimal (4F).
    • OCT: representación en cadena de un número octal (117).
    • BIN: representación en cadena de un número binario (1001111).
    • BYTE: un único byte.
  • Si no se especifica un formato (tipo), se utiliza por defecto a DEC.
  • La diferencia entre print y println es que el segundo agrega un retorno de carro (ASCII 13 o '\r') y un salto de línea (ASCII 10 o '\n') al final de de la información enviada.

Enviar información binaria.

void Serial.write(datos);
void Serial.write(buffer, longitud);
  • Envía información binaria: un byte o una secuencia de bytes, al puerto serial.
  • Los datos a enviarse pueden ser un número o una cadena.
  • Si se desea enviar un arreglo (buffer) es necesario especificar su longitud.

Depurando la transmisión de datos.

Es posible revisar fácilmente con el IDE de Arduino lo que la tarjeta está transmitiendo al computador a través del puerto USB mediante el Monitor Serial.  Esto es muy útil también para la depuración rápida de los sketches.

Para activar el Monitor Serial se debe presionar el ícono serial_monitor y utilizar las funciones de envío de información mencionadas anteriormente, de esta manera aparecerá en la sección inferior del IDE una consola donde se podrán apreciar los mensajes enviados por la Arduino.

void Serial.print(datos, tipo);

El cuarto sketch: The LED with fotoresistor

Sketch 'The LED with fotoresistor'.

Sketch 'The LED with fotoresistor'.

Descripción.

Este sketch utiliza una fotoresistencia como sensor, es decir, la cantidad de luz recibida por el componente determina la cantidad de voltaje que es permitido pasar a través de él.  Como actuador se utiliza el mismo LED de siempre que nos mostrará de manera visual cuanto voltaje atravieza por el sistema.

A mayor cantidad de luz percibida el LED tendrá un mayor brillo.

Implementación.

Hardware.

En términos de la implementación del hardware suceden dos cosas interesantes.

  1. Como ya se había hecho en el sketch anterior, The LED with button and fade, para provocar el efecto de intensidad de luz del LED es necesario conectarlo a uno de los pines con soporte para modulación por ancho de pulsos (PWM), es decir, a los pines 9, 10 y 11, y enviarle la inforamción correspondiente con la instrucción analogWrite.
  2. La foto resistencia, a diferencia del botón que tiene sólo dos estados: presionado o no presionado, es capaz de producir un rango de valores según la cantidad de luz que recibe en un momento específico del tiempo.  Para leer su información es necesario utilizar las entradas (pines) análogos ubicados en la parte inferior derecha de la tarjeta Arduino y leer su información con la instrucción analogRead.

Software.

En términos de software el sketch es muy sencillo, sólo debe realizar los siguientes pasos.

  1. Leer estado del sensor.
  2. Modificar la intensidad del LED de acuerdo a lo leído del sensor.
  3. Esperar un momento para reinciar la iteración.

Es muy importante tener en cuenta que la instrucción analogRead retornará un número entre 0 y 1023 mientras que la instrucción analogWrite espera un valor numérico como parámetro entre 0 y 255, por esto será necesario dividir entre 4 el valor de la lectura hacia la escritura si se va a utilizar directamente.

#define SENSOR 0                    // Analog pin for the fotoresistor
#define LED    9                    // Digital pin (PWM) for the LED
void setup()
{
  pinMode(LED, OUTPUT);            // LED pin is output
  // Analog pins are always INPUT.
}
void loop()
{
  int fr = analogRead(SENSOR);      // Read the status of the fotoresistor
  analogWrite(LED, fr/4);           // Change the brightness of the LED
                                    // acording the fotoresistor's value
  delay(10);                        // Wait a moment fot next iteration
}

Actualización del Kernel en Ubuntu 9.04

Introducción.

El día de hoy voy a actulizar el kernel del equipo de la oficina que tiene actualmente un 2.6.28-11-generic #42-Ubuntu SMP.  La nueva versión será la 2.6.29-4.

Supuestamente la versión actual tiene algunos problemas, en particular con las tarjetas de video Intel.  A pesar de que la tarjeta de video de este equipo es NVidia 7x si he notado a esta nueva versión de Ubuntu mas lenta, especialmente en temas de manejo de ventanas, así que voy a experimentar con la actualización a ver si se mejoran.

La versión 2.6.30 se encuentra disponible desde el día de ayer sin embargo leí en varios foros acerca de la posible incompatibildad con cierto hardware así que prefiero ir dando un pasito a la vez.

Procedimiento.

Descargar los paquetes requeridos del Kernel.

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-headers-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-headers-2.6.29-02062904_2.6.29-02062904_all.deb

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-image-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

Instalar los paquetes del Kernel.

$ sudo dpkg -i linux-headers-2.6.29-02062904-generic_2.6.29-02062904_i386.deb linux-headers-2.6.29-02062904_2.6.29-02062904_all.deb linux-image-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

Reiniciar el sistema.

$ sudo reboot.

Enlaces.

Procedimiento de instalación básica de Drupal 6

Problemas con los foros de Drupal 5

Identificación del problema.

Desde hace varios días había detectado un problema con el módulo de foros de Drupal, el cual permitía ingresar nuevas colaboraciones (forum posts) al foro pero estas no eran asociadas a ningún tema o contenedor siendo imposible consultarlas posteriormente a través de la página del módulo (?q=forum) pero visibles como nodos de contenido (?q=admin/content/node).

Implementación de la solución.

Después de muchas pruebas infructuosas concluí que el problema no parecía ser de mis datos o de la configuración de los módulos, tenía que ser del core de Drupal.  Verifiqué tres sitios mas y estaban en iguales condiciones.

Gracias a un artículo que publicó NZ WebHosting en su blog, pude determinar que el problema se originaba en un conflicto del vocabulario.

En condiciones normales la tabla cms_vocabulary tiene una entrada para la categoría de los foros.  Su llave primaria es el vid el cual es un valor entero específico que debe coincidir con el esperado por Drupal.

INSERT INTO `cms_vocabulary` (`vid`, `name`, `description`, `help`, `relations`, `hierarchy`, `multiple`, `required`, `tags`, `module`, `weight`) VALUES (vid, 'Forums', ", ", 0, 1, 0, 1, 0, 'forum', -10);

Si no se tiene este registro y es necesario crearlo, antes se debe consultar cual es el valor de vid que se debe utilizar.  Para esto es necesario ejecutar el siguiente código PHP que puede ser inmerso en una página temporalmente.

<?php
$vid = _forum_get_vid();
print 'vid = ' . $vid;
$vid = variable_get('forum_nav_vocabulary', '');
print '<br /> variable_get("forum_nav_vocabulary", "") = ' . $vid;
?>

La ejecución de este código debe mostrar algo similar a lo siguiente.

vid = XXX
variable_get("forum_nav_vocabulary", "") = XXX

Donde XXX deberá ser el valor del vid.  Si no aparece un valor para forum_nav_vocabulary significa que es necesario realizar el siguiente paso tal y como fue mi caso.

Así como en la tabla cms_vocabulary debe existir un registro para la categoría, en la tabla cms_vocabulary_node_types deberá existir un registro para el término asociado mediante el mismo vid.

INSERT INTO `cms_vocabulary_node_types` (`vid`, `type`) VALUES (vid, 'forum');

Teniendo estos dos registros asociados el formulario de creación de contenido para los foros empieza a incluír un campo Foros, antes inexistente, para la selección del foro (contenedor o tema) al que va dirigida la participación.  De igual manera, los artículos empiezan a aparecer correctamente desde la página principal de los foros.

Crear contenido > Tema del foro

Crear contenido > Tema del foro

Enlaces.

El tercer sketch: The LED with button and fade

Sketch 'The LED with button and fade'

Sketch 'The LED with button and fade'

Descripción.

Este sketch es la continuación del anterior, The LED with button and state, agregándole el efecto de desvanecimiento mientras se modifica la intensidad del LED.

Si se mantiene presionado el botón (mas de 500 ms.) la intensidad del LED aumenta hasta llegar a su máximo, momento en el cual se apaga por completo y vuelve a iniciar el proceso.  Si se presiona el botón por un momento corto (menos de 500 ms.) la luz del LED se desvanece hasta llegar a cero brillo.

El proceso aparente de desvanecimiento se logra con la combinación de pulsos cada vez mas largos (o mas cortos) que se traducen longitudes de tiempo en que el LED permanece encendido, esto unido al efecto de persistencia del ojo humano (lentitud en el refrescamiento de la imagen de la retina).

Implementación.

Hardware.

Para hacer esto se utilizan los pines digitales 9, 10 u 11 que soportan Modulación por ancho de pulsos (PWM) y permiten manipular la longitud de los pulsos, por esto se movió el LED del pin 13 que había sido habitual hasta ahora, al 9.  Probablemente habría sido precavido agregar una resistencia entre el LED y la tierra (cable azul).

La magia del desvanecimiento se observa en el software.

Software.

En términos generales el sketch realiza lo siguiente.

  • Si se presionó el botón:
    • Cambia el estado a encendido (HIGH).
    • Almacena el momento en que fue presionado.
  • Si se presionó el botón y se mantiene presionado (mas de 500 ms.):
    • Aumenta el brillo.
    • Reinicia el brillo (0) si este excede el máximo (255).
  • Si se presionó el botón corto tiempo (menos de 500 ms.):
    • Cambia el estado a apagado (LOW).
  • Almacena el estado actual del botón como último estado para la siguiente iteración.
  • Si el estado es encendido aumenta el brillo con la instrucción: analogWrite(LED, brightness).
  • Si el estado es apagado disminuye gradualmente el brillo del LED hasta llegar a cero.

Se debe tener siempre en cuenta que la función analogRead retorna un entero entre 0 y 1023 mientras que analogWrite recibe un entero entre 0 y 255, un cuarto del rango del valor retornado por la lectura.

#define LED 9              // Digital PIN for the LED
#define BUTTON 7           // Digital PIN for the Button
int brightness          = 0;      // Amount of light of LED
int lastValue           = LOW;    // Last button status
int state               = LOW;    // Current button status
unsigned long startTime = 0;      // Time of last button pressed
/**
 * Executes only once when the sketch starts, sets initial values
 */
void setup ()
{
  pinMode(LED, OUTPUT);      // LED pin is output
  pinMode(BUTTON, INPUT);    // Button pin is input
}
/**
 * Executes continuously and infinitely
 */
void loop()
{
  int button = digitalRead(BUTTON);         // Reads the button status
  if(button == HIGH && lastValue == LOW)    // The button is pressed
  {
    state = HIGH;                           // The state is ON now
    startTime = millis();                   // Gets the current time
    delay(10);                              // Waits 10 ms.
  }
  if(button == HIGH && lastValue == HIGH)   // The button keeps beign pressed
  {
    if(millis() - startTime >= 500)         // Checks if the button is pressed by
    {                                       // more than 500 ms.
      brightness ++;                        // Amounts the brightness of the LED
      delay(15);                            // Waits for 15 ms.
      if(brightness > 255)                  // If the brightness exceeds 255
        brightness = 0;                     // backs to 0, its a byte
    }
  }
  if(button == LOW && lastValue == HIGH)    // The button is released
  {
    if(millis() - startTime < 500)          // and was pressed less than 500 ms.
      state = LOW;                          // The state is OFF now
  }
  lastValue = button;                       // Sets the current button status as
                                            // last value for the next iteration
  if(state == HIGH)                         // If the state is ON ...
    analogWrite(LED, brightness);           // Make the LED shine with its new brightness
  else                                      // Else, because its OFF ...
    fadeOut();                              // Turn it off gracefully
}
/**
 * Turns off the LED by reducing its brightness until total darkness
 */
void fadeOut()
{
  for(int i=brightness; i>=0; i--)          // Begins with the current level of brightness
  {                                         // decreasing by units until complete off
    analogWrite(LED, i);                    // Sends the reduced brightness to the LED
    delay(10);                              // Waits for 10 ms.
  }
  brightness = 0;                           // Resets the brightness reference to zero
}

Problemas con mod_security

Introducción.

Mod_security es una herramienta extremadamente útil que actúa como un firewall para los sitios web permitiendo filtrar de manera muy flexible la forma como los usuarios acceden a las aplicaciones web, evitando por ejemplo vulnerabilidades conocidas o accesos inválidos.  Mas información.

Su flexibilidad la convierte también en algo un tanto compleja de entender, como todo en la vida tendré que sacar un tiempo para estudiarla y entender en serio como se implementan sus reglas.

Descripción del problema.

En la vida práctica algunas veces las restricciones por defecto que por seguridad el módulo impone interfieren con el correcto funcionamiento de la aplicación web y es cuando suceden mis problemas.  Me sucedió alguna vez con un sitio basado en CodeIgniter y ahora con una instalación de Piwik.

El acceso al script de generación de estadísticas funcionaba correctamente cuando este era accedido directamente.

http://www.server.com/piwik/piwik.php

Sin embargo fallaba por extrañas razones cuando era accedido con parámetros GET tal y como se debe hacer cuando se instala en un sitio web para que lleve las estadísticas de acceso a sus páginas.

http://www.server.com/piwik/piwik.php?url=http%3A%2F%2Fwww.server.com%2Fsite%2F&action_name=Main&idsite=1&res=1280×1024&h=10&m=55&s=25&fla=1&dir=0&realp=0&pdf=1&wma=1&java=0&cookie=1&title=Main%20|%20My%20Site&urlref=

Si se invocaba directamente se producía un error 503 (Service Temporarily Unavailable) y en las aplicaciones que lo tuvieran instalado para el control de sus estadísticas aparecía como una imagen al final de su contenido (en lugar de un cuadrado transparente).

El problema era que mod_security estaba impidiendo el acceso normal al sitio debido a alguna de sus reglas.

Descripción de la solución.

Sin tener profundos conocimientos en la creación y manipulación de las reglas de mod_security la idea no era modificarlas sino evitar que se aplicara el filtro sobre la aplicación web afectada.

Una primera solución fue desactivar por completo a mod_security para esa aplicación específica.  Para hacer esto es necesario crear un archivo .htaccess en el directorio raíz de la aplicación con el siguiente contenido.

SecFilterEngine Off
SecFilterScanPOST Off

Esto soluciona el problema sin embargo también elimina las ventajas de seguridad que trae consigo el módulo.  Una segunda opción sería entonces evitar que el filtro se aplique al archivo específico que está teniendo el problema con el filtro.  Para hacer esto el contenido del archivo .htaccess debe ser el siguiente.

SetEnvIfNoCase Request_URI ^/piwik/piwik\.php$ MODSEC_ENABLE=Off

Donde se especifica la ubicación exacta (relativa o absoluta) del archivo con problemas.

Enlaces.

Modificación del segundo sketch: The LED with button and state

Descripción.

Este sketch se encuentra completamente basado en el anterior al cual se le modifica su funcionalidad permitiendo manipular un estado para el LED, es decir, cuando se presiona el botón el LED se enciende, aún sin necesidad de que el usuario final continúe presionandolo; este comportamiento se mantendrá hasta que el usuario presione nuevamente el botón para apagar el LED.

Ya que los cambios introducidos desde el sketch anterior corresponden a su funcionalidad, el hardware permanece sin variaciones y estas son introducidas en el software.

Implementación.

Software.

#define LED 13              // Digital PIN for the LED
#define BUTTON 7            // Digital PIN for the Button
int state = 0;              // The current state of the LED
int lastState = 0;          // The past state of the button
void setup ()
{
  pinMode(LED, OUTPUT);      // LED pin is output: turn it on/off
  pinMode(BUTTON, INPUT);    // Button pin is input: read it
}
void loop()
{
  int currentState = digitalRead(BUTTON);
  // Consider a button's change of state only when is pressed
  if (lastState == LOW && currentState == HIGH)
  {
    state = !state;
    delay(10);
  }
  lastState = currentState;
  digitalWrite(LED, state);
}

Instalar Twhirl en Linux Ubuntu 9.04

Procedimiento.

Descargar la última versión disponible del framework de Adobe Air desde la siguiente ubicación.

http://get.adobe.com/air/

Instalar Adobe Air.

$ chmod +x AdobeAIRInstaller.bin

$ ./AdobeAIRInstaller.bin

Descargar la última versión disponible de Twhirl desde la siguiente ubicación.

http://www.twhirl.org/download

$ wget http://d.seesmic.com/twhirl/twhirl-0.9.2.air

Instalar Twhirl desde el instalador de aplicaciones de Adobe Air.

$ /opt/Adobe\ AIR/Versions/1.0/airappinstaller

Seleccionar el instalador de Twhirl recién descargado: twhirl-0.9.2.air.

Para ejecutar la aplicación seleccionar los menúes Application > Accesories > twhirl o ejecutar la siguiente instrucción desde línea de comando.

$ /opt/twhirl/bin/twhirl

Enlaces.