Páginas

viernes, 29 de junio de 2012

Hemeroteca #1

Ya han pasado seis meses de este 2012 y seguro que muchos estamos ya pensando en coger vacaciones dentro de poco. En esta entrada recopilaré para que han dado estos seis meses en El blog de pico.dev. Si te interesan entradas como estas y aún no lo has hecho suscríbete al feed de mi blog, tengo una buena cantidad de entradas esperando a ser escritas y que iré publicando a razón de una por semana si dispongo del tiempo y el ánimo para escribirlas.

En estos seis meses he escrito estas 23 entradas agrupadas por temática:

Varios
Como mención especial integré el widget de karmacracy que puede verse al final de cada entrada mediante el cual cualquier usuario puede compartir la entradas de este blog en sus redes sociales como facebook, twitter o linkedin de una forma rápida y sencilla obteniendo a cambio un lugar en el widget para los usuarios que más clics atraigan.

Calendario Arch Linux 2012
last, como obtener los últimos inicios de sesión
Obtener la clave de una red WIFI WEP
Guía post instalación Minix
Karmacracy y como integrarlo en Blogger
Guía instalación CyanogenMod

Programación
Esta ha sido la temática de la que más entradas he escrito, principalmente alrededor de la programación en Java y del desarrollo web.

Errores de precisión, redondeo y representación con float y double
Herramienta de construcción Gradle
Usar Gradle mediante Gradle wrapper
Por qué usar enums en vez de constantes en Java
Debug de una aplicación Java
5 opciones de hosting para aplicaciones Java
Patrones de diseño en la programación orientada a objetos
Ejemplo del patrón de diseño Command y programación concurrente en Java
Librerías de logging para Java (slf4j, log4j, java.util.logging, logback, MentaLog)
GitHub, repositorio Git para proyectos
Hojas de estilo css con less

Apache Tapestry
El framework con que algún día me gustaría programar en mi trabajo ya que realmente me lo paso bien programando con él, lamentablemente no encuentro oportunidades laborales en el que poder usarlo y profundizar aún más en él. Dentro de mi experiencia de entre JSP/Servlets, Struts, Grails y JSF es lo mejor que he probado con diferencia. Posee un conjunto de características que lo hacen especialmente agradable trabajar con él, algunas únicas, su código fuente y diseño es un muy buen ejemplo de como aplicar varios patrones de forma útil. Siendo un framework basado en componentes la productividad se consigue a base de hacer el desarrollo una vez y a partir de ese momento reutilizarlo en toda la aplicación. El código queda muy limpio (sin spaguetti code que otros frameworks permiten o con el que al final se acaba) y haciendo un poco bien las cosas apenas hay duplicación de código a lo largo de la aplicación.

Recarga de clases (class reloading) en Apache Tapestry
Conversiones de datos entre el cliente y servidor en Apache Tapestry
Componente selector de fecha para Tapestry 5

Raspberry Pi
La Raspberry Pi es un ordenador completo con el tamaño de una tarjeta de crédito, sus propósitos pueden ser muchos y su consumo de vatios es muy reducido.

Raspberry Pi, desempaquetado («unboxing»)
Guía instalación Raspberry Pi con Arch Linux ARM (Parte I, instalación base)
Guía instalación Raspberry Pi con Arch Linux ARM (Parte II, programas)

Referencia:
Hemeroteca #0

viernes, 22 de junio de 2012

Guía instalación Raspberry Pi con Arch Linux ARM (Parte II, programas)

Raspberry Pi
Nota: la última actualización de esta guía fue el 19-01-2013. Al ser Arch Linux una distribución rolling release puede que cuando la leas algunas cosas hayan cambiado aunque la mayoría seguirán siendo como esta escrito a continuación.

Después de la instalación base de Arch Linux ARM para la Raspberry Pi a partir de la Guía instalación Raspberry Pi con Arch Linux ARM (Parte I, instalación base) toca añadirle los programas que nos proporcionarán la funcionalidad que queramos. Desde luego la capacidad de la Raspberry es limitada y no podremos instalarle todo lo que deseemos, principalmente por la cantidad de memoria que tiene (256 MiB), por la velocidad de lectura desde la tarjeta SDHC que en determinados momentos es el mayor limitante notándose que se ahoga y porque el procesador no tiene la capacidad ni se puede comparar con un Intel o AMD de los que podemos encontrar estos días. Por ello, la Raspberry no será un sustituto de nuestro ordenador de escritorio o portátil aunque dicho esto hay ciertas tareas que puede cumplir a la perfección con capacidad más que suficiente.
Arch Linux ARM

Si necesitamos algo más potente podemos optar por una CuBox o una Pandaboard ES que ambas tienen 1 GiB de memoria y un procesador dual core algo más potente que el de la Raspberry, desde luego ambas funcionarán bastante mejor al ejecutar un entorno gráfico aunque probablemente tampoco sean sustitutos para reemplazar nuestro ordenador de escritorio. El punto fuerte de la Raspberry comparadas con la CuBox o la Pandaboard es su precio, de unos 45€ con gastos de envío a España, contra 99€ y 182$ sin gastos de envío respectivamente.

Volviendo a la guía, seguidamente explicaré algunas de las tareas para las que sí podemos usar la Raspberry.

Programas y servicios

Las siguientes aplicaciones de muestra son solo una idea de lo que podemos instalar. Además de las anteriores o mencionando algunas de ellas una lista no exhaustiva podría ser la siguiente:
  • Asignar dirección IP fija
  • P2P torrent (transmision-cli)
  • ftp (vsftp)
  • Servidor web (lighttpd)
  • firewall (ufw)
  • PHP
  • Git
  • Sistemas de archivos NTFS, FAT
  • Sonido (cmus)
  • SSH (certificados)
  • SSH y screen
Otras:
  • email (mutt)
  • música (cmus)
Veremos algunas de estas a continuación y la configuración del router que tendremos que hacer. Si quieres instalar todo lo que se comenta en esta quía puedes hacerlo con:


Asignar dirección IP fija

De la lista anterior de aplicaciones algunas de ellas son programas que actuan de servidor. Dado que para conectarnos a un servidor necesitamos conocer la dirección IP en la que se encuentra deberemos asignar a la Raspberry una dirección IP fija en vez de dejar al DHCP del router que le asigne una y que pueda cambiar entre diferentes sesiones, reinicios o al cabo de un tiempo. Para tener una dirección IP fija deberemos crear un servicio de systemd que al iniciarse el sistema se le asigne la que deseamos. Para asignar la dirección IP estática debemos crear el archivo /etc/conf.d/network de configuración donde indicaremos varias propiedades de la red entre ellas la dirección IP:

Y el archivo del servicio de systemd /etc/systemd/system/network.service que se ejecutará cuando se inicie el sistema y realizará las operaciones necesarias para configurar la red:

En address pondremos la dirección IP que queramos dentro de nuestra red y fuera del rango de direcciones IP que asigna el router. Finalmente debemos habilitar e iniciar el servicio network que acabamos de crear.


También deberemos modificar los archivos /etc/dhcpcd.conf y /etc/resolv.conf para que los nombres de los dominios se resuelvan a sus direcciones IP, si al hacer «ping www.google.es» obtenemos un mensaje como «ping: unknown host www.google.es» es que nos falta modificar alguno de estos archivos, poniendo la dirección IP de nuestro router probablemente nos sea suficiente sino podemos usar un servidor de nombre en internet como los que ofrece google:



P2P torrent

tranmision es uno de los programas más populares para realizar descargas P2P mediante torrent. Aparte de a través de la interfaz gráfica puede ser usado desde la linea de comandos y como esto nos es necesario para la Raspberry será el que veremos a continuación. Empezaremos instalando su paquete transmission-cli.

Para poder ejecutarlo como demonio y con un usuario específico debemos seguir los pasos indicados en la wiki de arch linux sobre transmission para el caso de usar systemd.

Siguiendo los pasos de la wiki deberemos hacer las siguientes cosas:
  • Modificar los archivos /usr/lib/systemd/system/transmission.service y /usr/lib/tmpfiles.d/transmission.conf con el usuario con el que queramos que se ejecute transmission.
  • Copiarlos en cada caso a un subdirectorio de /etc.
  • Modificar el propietario y grupo del directorio /run/transmission según el usuario que vaya a iniciar el servicio configurado en transmission.service y transmission.conf.
  • Iniciar el servicio con transmission-daemon y pararlo para que se cree el archivo de configuración.
  • Editarlo para activar la interfaz rpc y el directorio de descargas.
  • Iniciar el servicio con tranmission a través de systemd.
El directorio de descargas incompletas (incomplete-dir), el usuario (rpc-username) y password (rpc-password) para la interfaz remota web (la password la indicaremos en texto plano una vez iniciemos transmision él detectará que está en texto plano y creará un hash de ella para mayor seguridad), si deseamos autenticación en la interfaz remota (rpc-authentication-required) y si queremos un directorio donde transmission buscará archivos torrents para iniciar descargas de forma automática cuando encuentre uno (watch-dir, watch-dir-enabled). En rpc-whitelist deberemos indicar la red local a la que estamos conectados, por ejemplo, 192.168.2.*.


Una vez realizados estos pasos podemos iniciar el demonio de transmission y acceder a su interfaz web con el navegador de nuestro ordenador de escritorio o portatil en la dirección http://[ip-raspberrypi]:9091.

Mediante esta interfaz web podremos modificar algunas propiedades adicionales como los limites de velocidad tanto de bajada como de subida incluso en un horario determinado. Finalmente, mediante esta interfaz web nos aseguraremos en la pestaña Preferences > Network de que tenemos el puerto usado por transmission en estado abierto y accesible desde internet, esto nos será necesario para descargar al máximo de velocidad que dispongamos. Si no lo tenemos tendremos que modificar la configuración del router (lo veremos más adelante en la configuración del router).


FTP

FTP (File Transfer Protocol) es un protocolo para la trasnferencia de archivos entre dos máquinas y puede que nos sea de utilidad para mover archivos entre el sistema que usemos y la raspberry. Por ejemplo, si queremos copiar los archivos descargados por transmission a nuestra máquina podemos extraer la tarjeta de memoria de la raspberry insertarla en nuestro equipo y copiar los archivos, otra forma es instalar un servidor ftp en la raspberry y realizar el copiado mediante el protocolo FTP. La primera opción es más rápida (a 10 MiB/s) pero la segunda es más cómoda (a 2 MiB/s con una tarjeta clase 10) ya que no tendremos que apagar la raspberry y mover la tarjeta SD de un sistema a otro. También nos puede ser útil si queremos dejar en la Raspberry un archivo php.

Si optamos por la segunda opción podemos utilizar Very Secure FTP que ocupa muy poco y no tiene ninguna dependencia, su paquete es vsftd:

Una vez instalado debemos habilitar el servicio e iniciarlo:


Editamos también el archivo de configuración /etc/vsftpd.conf, hay un montón de propiedades pero las básicas que nos interesará modificar son anonymous_enable para permitir o no autenticación anónima, local_enable para permitir iniciar sesión con los usuarios de la raspberry y write_enable para permitir realizar operaciones de escritura como subir o eliminar archivos.

Ya en el ordenador con el que trabajemos deberemos instalar un cliente FTP para realizar las transferencias desde y a la raspberry, podemos utilizar uno de los más conocidos, filezilla.

Para conectarnos en el sitio indicaremos como protocolo SFTP, modo de acceso normal y el nombre de usuario y password de un usuario de la raspberry.

http://welcome.filezilla-project.org/welcome?type=client&category=documentation_basic&version=3.5.3
http://welcome.filezilla-project.org/welcome?type=client&category=documentation_network&version=3.5.3
http://wiki.filezilla-project.org/Documentation

Servidor web

Aunque la raspberry sea pequeña y no parezca muy indicada para actuar como servidor tiene algún punto que la hace especialmente adecuado para ello como es que tiene un consumo muy bajo, ridículo (3 watios) para un servidor mucho más potente (200 watios o más), ocupa también un espacio ridículo en comparación con un servidor más potente, tampoco necesita una refrigeración especial. Al menos para un uso personal o un entorno para un equipo de desarrollo puede ser más que suficiente.

Una muy buena opción es lighttpd, es un servidor de nueva generación de los llamados ligeros que le están ganando terreno a apache, con trasnferencias asíncronas, que ocupa apenas 1 MiB, con muy pocas dependencias. Su paquete es lighttpd. El document root por defecto está en /srv/http donde han de estar alojados los archivos que va a servir.

Me gusta más cherokee, no porque sea mejor ni peor sino porque es un proyecto liderado por un español, Álvaro López Ortega, cosa rara por estos sitios, sin embargo, en la raspberry su consola de administración tiene un funcionamiento pobre llegando a no ser usable, esto unido a que sus archivos de configuración son bastante crípticos para editarlos con un editor de texto la opción que recomiendo es lighttpd. Otra opción sería nginx.

Al igual que con vsftpd debemos habilitar el servicio e iniciarlo.



Acceso desde internet con FreeDNS

Llegados a este punto podemos disponer de un servidor web sin embargo para que sea accesible desde internet necesitamos aún un pieza fundamental en el funcionamiento de la web, un nombre de dominio nos proporcionará un identificador para nuestro servidor que no cambiará con el tiempo aunque la IP pública de nuestro router que nuestro proveedor de servicios de internet (ISP) nos asigna lo haga.

Un opción gratuita es utilizar FeeDSN que nos permitirá obtener un subdominio de ciertos dominios públicos como mooo.com. Necesitaremos crearnos una cuenta en FreeDNS y crear un subdominio. Una vez lo tengamos se nos presenta el problema de como actualizar en FreeDNS nuestra IP pública cada vez que nuestro ISP nos de una distinta. Para ello una opción sencilla es crearnos un script que con cron se ejecute cada cierto tiempo.


Primeramente necesitaremos una serie de utilidades que están contenidas en el paquete dnsutils.

Luego el script con un contenido similar al siguiente cambiando el API_KEY que nos asigne FreeDNS para el dominio:



Le cambiamos de permisos al archivo y añadimos la expresión cron con crontab:

Añadiendo el siguiente contenido para ejecutar el script cada 5 minutos:


En el archivo /var/log/crond.log podemos ver las ejecuciones y resultados del script.

http://freedns.afraid.org/dynamic/index.php
https://wiki.archlinux.org/index.php/Cron

Configuración router

Para hacer que nuestra RPi sea accesible desde internet tendremos que modificar alguna configuración del router como abrir puertos para que el router redirija el tráfico que le llega a un puerto a una determinada direccion IP y puerto de nuestra red. Esto nos será útil principalmente para el caso del servidor web (puerto 80), de transmission (puerto 51413) u otro servidor que queramos que sea accessible desde internet.

Como comentaba en la asignación de IP estática primero comprobaremos el rango de direcciones IP que asigna el servidor DHCP del router y que la dirección IP estática que hemos asignado a la RPi está fuera de ese rango.

Posteriormente abrimos los puertos, las opciones serán diferentes para cada modelo de router pero similares.

Firewall

A pesar de que el router ya hará de firewall podemos utilizar ufw en la propia RPi.



Sistemas de archivos NTFS, FAT

Puede que necesitemos instalar el soporte para acceder a sistemas de archivos con formato NTFS (que es el utilizado por windows) o FAT. Tan solo necesitaremos instalar los siguientes paquetes ntfs-3g, ntfsprogs y dosfstools.

Para realizar el montaje manualmente ejecutaremos el siguiente comando, donde /mnt es la carpeta donde queremos montar el sistema de archivos de la partición de un disco o memoria USB externos:

Si queremos que este montaje se realice de forma automática nada más conectar el cable USB a la RPi instalaremos el paquete udev-automount, que realizará el montaje en la carpeta /media.

PHP

Para instalar PHP basta con instalar los paquetes php php-cgi. Para comprobar que se han instalado correctamente podemos ejecutar:

Ahora nos quedaría integrar el soporte en el servidor web para que sea capaz de procesar los archivos php. La configuración varía en cada servidor web. Aquí explicare como configurarlo con ligthttpd. Para ello deberemos editar el archivo /etc/lighttpd/lighttpd.conf e incluir al final las siguientes lineas:

Ahora deberemos crear el archivo /etc/lighttpd/fastcgi.conf (y el directorio donde está) e incluir en él el siguiente contenido:


Sonido

Primero añadimos nuestro usuario al grupo de audio para reproducir sonidos, cargamos el módulo del sonido y reproducimos un sonido de prueba:

Si no queremos cargar el módulo manualmente cada vez que queramos reproducir sonido se puede cargar el módulo automáticamente cuando se inicie la Raspberry Pi con:

Y añadiendo a ese archivo el módulo que queremos cargar (snd-bcm2835).

Habiendo cargado el módulo snd_bcm2835 con cmus podemos reproducir mp3, ogg entre otros formatos instalando varios paquetes que son: alsa-firmware alsa-lib alsa-plugins alsa-utils cmus pulseaudio libmad libvorbis.

Una cosa que tenemos que tener en cuenta es la salida por la que se emitirá el sonido, por la salida HDMI o por el jack 3.5mm, si no oímos ningún sonido puede que necesitemos cambiar la salida a la que estemos utilizando: Podemos hacerlo con:

Después de instalar los paquetes anteriores puede que necesitemos reiniciar. Podemos probar el sonido con aplay.

Y después cmus:

Si estás interesado en escuchar música con la Raspberry puedes consultar la entrada 4 formas de escuchar música a través de internet en la que se indican varias maneras de hacerlo.

SSH con certificados

El usar SSH puede resultar incómodo ya que hay que estar constantemente introduciendo la clave, para evitarlo en otra entrada explicaré como usar SSH con una clave pública y privada para realizar la autenticación ya que es algo que seguramente sea igual para la RPi o para cualquier otro sistema.

La Raspberry con llos siguientes programas nos puede ofrecer muchas funcionalidades pero tampoco hay que esperar una capacidad igual al de un ordenador de escritorio. En las pruebas que he realizado la velocidad de transferencia que he conseguido desde la tarjeta SD y desde un disco duro externo conectado por USB a la RPi ha sido de tan solo ¡2 MiB/s!.

Utilidad de screen

Si la conexión ssh se cierra todos los programas que se iniciaron en ella se terminan con lo que si estabamos reproduciendo múscica con cmus, cmus se terminará y dejaremos de escuchar música. Para evitarlo podemos usar screen.

Los elementos básicos para usar este miniordenador son la placa de la Raspberry Pi, una cargador de 3A junto con una tarjeta SD.

Referencia:
Raspberry Pi, desempaquetado («unboxing»)
Raspberry Pi, Guía instalación (Parte I) Instalación base
Dejar procesos vivos de conexión SSH con screen

viernes, 15 de junio de 2012

Componente selector de fecha para Tapestry 5

Apache Tapestry
Tapestry tiene un montón de componentes que en la mayoría de los casos serán suficientes para implementar toda la funcionalidad que necesitemos, también disponemos los de librerías de terceros. Sin embargo, quizá en alguna ocasión no encontremos justo lo que necesitemos. Si ese es el caso no nos quedará más remedio que crear uno nuevo a nuestra medida. Si el nuevo componente es sencillo podemos partir desde cero para crearlo pero si el componente el algo más complejo es mejor partir de uno parecido a la funcionalidad que necesitemos, en cualquier caso es recomendable ver el código fuente de algunos componentes para conocer la forma de hacer las cosas, aprederemos nuevas y mejores formas de hacerlos. Esta es una de las ventajas de software libre u código abierto ¡aprovechemosla!.

En mi caso me ha pasado con el componente DateField que permite mostrar un calendario y seleccionar una fecha, también denominado date picker. Su misión principal es recoger un objeto Date del cliente. En el navegador proporciona una interfaz gráfica simple, perfectamente funcional y que cumple con su misión pero que en mi caso no me convence. A pesar de su antiguedad y que ya no está mantenido por su autor el antiguo jsCalendar es uno de los mejores javascripts que he encontrado que proporcionan esta funcionalidad. Tiene una licencia LGPL y por tanto podremos utilizarla en proyectos no-GPL. Posee una interfaz personalizable con skins y hay varios de ellos disponibles, también permite selecciona la hora y minutos y seleccionar los meses y años fácilmente.

Como se trata de un componente complejo en el ejemplo he partido del DateField del propio Tapestry y modificándolo para que incluya las referencias a los javascripts y estilos que necesita, el resto es muy parecido al original. En negrita marco la diferencias con respecto al original.

package es.com.blogspot.elblogdepicodev.tapestry.components;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.EventConstants;
import org.apache.tapestry5.FieldValidationSupport;
import org.apache.tapestry5.FieldValidator;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.ValidationException;
import org.apache.tapestry5.ValidationTracker;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Events;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.corelib.base.AbstractField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.AssetSource;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;

@Events(EventConstants.VALIDATE)
public class FechaField extends AbstractField {
 /**
  * The value parameter of a DateField must be a {@link java.util.Date}.
  */
 @Parameter(required = true, principal = true, autoconnect = true)
 private Date value;

 @Parameter(required = true, allowNull = false, defaultPrefix = BindingConstants.LITERAL)
 private DateFormat format;

 @Parameter(required = true, allowNull = false, defaultPrefix = BindingConstants.LITERAL)
 private String ifFormat;

 @Parameter
 private boolean hideTextField;

 @Parameter(defaultPrefix = BindingConstants.VALIDATE)
 @SuppressWarnings("unchecked")
 private FieldValidator<object> validate;

 @Parameter(defaultPrefix = BindingConstants.ASSET, value = "calendar.png")
 private Asset icon;
 
 @Environmental
 private JavaScriptSupport javascriptSupport;

 @Environmental
 private ValidationTracker tracker;

 @Inject
 private ComponentResources resources;
 
 @Inject 
    private AssetSource assetSource;

 @Inject
 private Request request;

 @Inject
 private Locale locale;

 @Inject
 private FieldValidationSupport fieldValidationSupport;

 void beginRender(MarkupWriter writer) {  
  javascriptSupport.importStylesheet(assetSource.getClasspathAsset("classpath:com/evandti/ticketbis/tapestry/components/calendar-system.css"));
  javascriptSupport.importJavaScriptLibrary(assetSource.getClasspathAsset("classpath:com/blogspot/elblogdepicodev/tapestry/components/calendar.js"));
  javascriptSupport.importJavaScriptLibrary(assetSource.getClasspathAsset("classpath:com/blogspot/elblogdepicodev/tapestry/components/calendar-setup.js"));
  javascriptSupport.importJavaScriptLibrary(assetSource.getClasspathAsset("classpath:com/blogspot/elblogdepicodev/tapestry/components/calendar/calendar-" + locale.getLanguage() + ".js"));
  javascriptSupport.importJavaScriptLibrary(assetSource.getClasspathAsset("classpath:com/blogspot/elblogdepicodev/tapestry/components/FechaField.js"));

  String value = tracker.getInput(this);

  if (value == null)
   value = formatCurrentValue();

  String clientId = getClientId();
  String triggerId = clientId + "-trigger";

  // Input
  writer.element("input", "type", hideTextField ? "hidden" : "text", "name", getControlName(), "id", clientId, "value", value);

  writeDisabled(writer);

  putPropertyNameIntoBeanValidationContext("value");

  validate.render(writer);

  removePropertyNameFromBeanValidationContext();

  resources.renderInformalParameters(writer);

  decorateInsideField();

  writer.end();

  // Now the trigger icon.
  writer.element("img", "id", triggerId, "class", "t-fechafield-trigger", "src", icon.toClientURL(), "alt", resources.getMessages().get("Mostrar_calendario"), "title", resources.getMessages().get("Mostrar_calendario"));
  writer.end();

  JSONObject spec = new JSONObject();

  spec.put("inputField", clientId);
  spec.put("button", triggerId);
  spec.put("ifFormat", ifFormat);

  javascriptSupport.addInitializerCall("fechaField", spec);
 }

 private void writeDisabled(MarkupWriter writer) {
  if (isDisabled())
   writer.attributes("disabled", "disabled");
 }

 private String formatCurrentValue() {
  if (value == null)
   return "";

  return format.format(value);
 }

 @Override
 protected void processSubmission(String elementName) {
  String value = request.getParameter(elementName);

  tracker.recordInput(this, value);

  // Parsear el valor
  Date parsedValue = null;

  try {
   if (StringUtils.isNotBlank(value))
    parsedValue = format.parse(value);
  } catch (ParseException ex) {
   tracker.recordError(this, resources.getMessages().format("date-value-not-parseable", value));
   return;
  }

  // Validar el valor
  putPropertyNameIntoBeanValidationContext("value");
  try {
   fieldValidationSupport.validate(parsedValue, resources, validate);

   this.value = parsedValue;
  } catch (ValidationException ex) {
   tracker.recordError(this, ex.getMessage());
  }

  removePropertyNameFromBeanValidationContext();
 }

 void injectResources(ComponentResources resources) {
  this.resources = resources;
 }

 @Override
 public boolean isRequired() {
  return validate.isRequired();
 }
}

El codigo javascript de inicialización:

function FechaField(spec) {
    Calendar.setup({
        inputField     :    spec.inputField,
        button         :    spec.button,
        ifFormat       :    spec.ifFormat
    });
}

Tapestry.Initializer.fechaField = function(spec) {
 new FechaField(spec);
}

Y su uso será tan simple como:

<t:fechafield t:id="fechaNacimiento" value="persona.fechaNacimiento" format="dd/MM/yyyy" ifFormat="%d/%m/%Y" validate="required" label="Fecha de nacimiento" placeholder="Fecha de nacimiento"/>

Una captura de pantalla con la versión original y la personalizada en la que el componente se usa varias veces en una misma página:



Hay que hacer notar algunas características de este componente (y por extensión de los componentes Tapestry). Alguna ya le he comentado en otra entrada pero las vuelvo a repetir porque son interesantes y definen sus características. Una importante es que como usuarios del componente no trabajamos con parámetros de la request (Strings) como haríamos con otros frameworks/lenguajes, trabajamos directamente con objetos de un tipo ya convertido a lo que necesitamos, en este caso un objeto java.util.Date, Tapestry se encargar de hacer la conversión del String que se recibe en el servidor en primera instancia al Date y de dejarlo en la propiedad fechaNacimiento del objeto persona tal y como se indica en el parámetro value, también se encarga de validarlo y de mostrar el error cuando la validación sea incorrecta. Al usar un componente tampoco tenemos que preocuparnos de que librerías javascript o estilos necesita en la página o cual es el código javascript para inicializarlo en el navegador, además, los estilos y javascript necesarios solo se incluirán si se usa en la página un componente FechaField sino no se incluirán, así las páginas serán un poco más eficientes. De lo anterior debió preocuparse el creador del componente y Tapestry proporciona las facilidades para ello y se encarga de incluir lo que se necesite en la página según los componetes que se usen en ella. Estas características nos hacen la vida más sencilla como desarrolladores y evitan que tengamos que incluir el mismo código una y otra vez para hacer lo mismo o de forma global aunque luego no se use en la página, tampoco es necesario que conozcamos como usuarios que necesita el componente para que funcione. Algo tan común como esto se puede usar varias veces en una misma página, en diferentes páginas o proyectos (se pueden crear librerías de componentes, en un archivo jar, que incluyen todo, imágenes, css, javascript, clases), lo que simplifica el mantenimiento y es la forma en que conseguimos aumentar la productividad (entre otras cosas, esta es solo una de ellas). Son motivos por los que darle una oportunidad a Apache Tapestry. ¡Bienvenido!.

Comentar que este componente ya esta hecho en la librería tapx de @hlship pero si no quieres tener una dependencia más para usar solo un componente esto puede ser suficiente.

Si quieres conocer más revisa la documentación sobre Apache Tapestry que he ido recopilando sobre este framework.

Referencia:
http://tapestry.apache.org/current/tapestry-core/ref/
http://tapestry.apache.org/current/tapestry-core/ref/org/apache/tapestry5/corelib/components/DateField.html
http://www.gnu.org/licenses/lgpl-3.0.html
http://es.wikipedia.org/wiki/GNU_Lesser_General_Public_License

viernes, 8 de junio de 2012

Guía instalación Raspberry Pi con Arch Linux ARM (Parte I, instalación base)

Raspberry Pi
Nota: la última actualización de esta guía fue el 19-01-2013. Al ser Arch Linux una distribución rolling release puede que cuando la leas algunas cosas hayan cambiado aunque la mayoría seguirán siendo como esta escrito a continuación.

Si ya tenemos en nuestras manos una Raspberry Pi convencidos de que nos puede ser de utilidad para algunas tareas y la hemos desempaquetado el primer paso que deberemos de dar es instalar alguna de las distribuciones GNU/Linux disponibles, en este momento Debian y Arch Linux ARM, Fedora finalmente ha tenido algún problema y desapareció de la lista de descargas aunque es probable que en algún momento vuelva a ofrecer soporte.
Arch Linux ARM

Los materiales que deberemos tener para realizar el proceso además de la propia Raspberry son:
  • un cargador USB y un cable adaptador USB a micro USB (un cargador de móvil capaz de dar al menos 750mA)
  • Una tarjeta de memoria SD o SDHC (en la lista de periféricos verificados puedes comprobar las tarjetas compatibles)
  • Un cable de red y un router al que conectarlo
  • Conexión a internet para realizar la instalación de paquetes y actualizaciones
  • Un ordenador con un lector de tarjetas SD o SDHC.
  • Última imagen de la distribución Arch Linux ARM que podemos obtener de la página de descargas.
Este es material básico que deberemos disponer, opcionalmente podemos tener un teclado USB y un monitor con entrada de vídeo HDMI (además de un cable HDMI), pero es opcional ya que desde un inicio podremos conectarnos via SSH a la Raspberry Pi con lo que el teclado y monitor son prescindibles salvo que queramos disponer de un entorno gráfico (y con una terminal remota gráfica como VNC tal vez ni eso).

Los pasos para realizar la instalación son los siguientes:

Grabar la imagen de Arch Linux ARM en la tarjeta SDHC

Este es el primer paso que deberemos hacer pero para ello deberemos averiguar el dispositivo correspondiente a la tarjeta SD ejecutando el comando antes de insertarla y después de insertarla:



El nuevo dispositivo que nos aparezca será el correspondiente a la tarjeta SD, en la imagen /dev/mmcblk0 (sin el p1 o p2, que indican la partición). Hay que prestar especial atención a este paso ya que si grabamos la imagen en otro dispositivo probablemente perderemos datos en el mejor de los casos o destruiremos el sistema de archivos dejando el ordenador inservible.

Una vez averiguado el dispositivo destino de la imagen la grabaremos con el siguiente comando, cambiando la ruta del parámetro if a donde tengamos la imagen:

El proceso tardará un rato y si todo ha ido bien montando la tarjeta veremos dos particiones, una de 100 MiB que es la partición de arranque y otra de 1,9 GiB para el usuario.

Redimensionar partición del sistema

Los tamaños de las particiones serán los anteriores (100 MiB y 1,9 GiB) independientemente de si tenemos una tarjeta SDHC de más capacidad como 4/8/16/32 GiB. Si queremos aprovechar el espacio total de nuestra tarjeta deberemos redimensionar la partición de 1,9 GiB o crear una tercera partición. Aquí explicaré la opción de redimensionarla que se puede hacer por linea de comandos o de forma gráfica con gparted ya sea con un live CD si somos usuarios de windows o instalando su paquete para nuestra distribución GNU/Linux.

Seleccionamos el dispositivo de la tarjeta en gparted y con el botón derecho sobre la partición de 1,9 GiB le damos a redimensionar (la partición deberá estar desmontada), agrandamos la partición hasta el máximo y le damos a Redimensionar/mover. Todavía los cambios no se han aplicado, hacemos clic en el menu «Editar > Aplicar todas las operaciones». Este proceso también tardará uno o dos minutos.




En este punto ya tenemos la tarjeta SD lista para arrancar la Raspberry Pi y será lo que hagamos a continuación.

Primer arranque de la Raspberry Pi

Como vemos el proceso de instalación hasta aquí tiene unos cuantos pasos pero no corremos ningún peligro de dejar la Raspberry Pi tan útil como un ladrillo («briked») como nos podría ocurrir con otras placas. Lo peor que podremos conseguir es que no arranque con la tarjeta SD.

Teniendo el cable de red de la raspberry conectado al router y nuestro ordenador conectado al mismo router estamos listos para arrancar la Raspberry, como no tiene un botón de encendido o apagado solo tendremos que conectar el cable USB y el cargador a la toma de corriente. Yo recomiendo tener un cargador al cual se le pueda quitar el cable USB (que el cargador y el cable USB no estén unidos de manera fija) de esta manera para apagar la Raspberry cuando queramos podremos quitar el cable USB del cargador o también podemos optar por desenchufar el cargador. Esto lo recomiendo ya que al no tener caja la Raspberry evitamos tocar la placa muy amenudo para evitar dañarla (tiene un condensador al lado de la conexión micro USB que corre cierto peligro de se arrancado si no tenemos cuidado). De esta forma dejamos el conector micro USB siempre conectado y reducimos la manipulación de la placa al mínimo.

Conectamos el cable USB y el cargador a la corriente, si todo va bien veremos unos cuantos LED encenderse (Red, Link, Full Duplex, Power y Ok). Pasados unos cuantos segundos podremos iniciar sesión con SSH para lo cual necesitaremos conocer la IP que ha asignado nuestro router por DHCP a la Raspberry, cosa que podemos ver en el apartado de administración del router.


Iniciar sesión conectando via SSH

La imagen de Arch Linux ARM viene ya por defecto con el demonio sshd instalado. Esto es muy útil ya que nos permite entrar en la Raspberry sin necesidad de tener un monitor o teclado conectado directamente a ella y podemos utilizar los del ordenador en el que trabajamos tal y como si lo hiciésemos en él pero realmente ejecutando los comandos en la Raspberry. Para ello ejecutamos (tal vez cambiando la dirección IP):

Nos mostrará el fingerprint de la clave SSH y preguntará si confiamos en ella, después de responder que sí introducimos la clave que por defecto es root. Ya podemos ver el prompt ([root@alarmpi ~]#).


Actualizar los paquetes de la imagen

Casi seguro (por no decir seguro) que los paquetes de la imagen estén desactualizados ya que Arch Linux es una distribución rolling release, por tanto el primer comando que ejecutaremos será para actualizar a sus últimas versiones todos los paquetes del sistema:



Con los cambios realizados al gestor de paquetes de arch linux con los cuales desde la versión 4.0 de pacman  los paquetes se firman digitalmente probablemente necesitemos actualizar el paquete pacman e inicializar la cadena de firmas con:

El paquete haveged proporcionará la entropía necesaria al ejecutar pacman-key, sino pacman-key puede que tardase en ejecutarse mucho tiempo.

Cambiar la clave del usuario root

La clave por defecto de root es lo siguiente a modificar ya que es conocida y por tanto no es nada segura, por lo que la cambiaremos:



Crear un usuario

Lo siguiente será crear un usuario para no conectarnos siempre con permisos de root, lo que haremos no es muy diferente de lo que haríamos para una instalación de Arch Linux en cualquier computadora:

Tambien instalamos el paquete sudo para en el momento que necesitemos poder ganar pemisos de super usuario como en el caso de una actualización del sistema.

Le damos permisos al usuario que hayamos creado:

Elimando un # y dejando en el archivo (esto no cambia de la guía de instalación para un ordenado de escritorio)

Con esto todo los usuarios del grupo wheel, como en el caso del que acabamos de crear, podrán hacer sudo.


Edición propiedades del sistema

Ahora cambiaremos algunas propiedades del sistema como el idioma, el nombre del sistema, la zona horaria del reloj. Para el idioma editamos el archivo /etc/locale.gen y descomentamos nuestro locale en español según sea nuestra región como puede ser es_ES.UTF-8. Seguidamente lanzaremos el siguiente comando para que el sistema se actualice al nuevo idioma.



Para terminar con el idioma lanzamos los siguientes dos comandos:


Nombre del sistema

Para identificar la máquina podemos darle al sistema un nombre fácil de recordar y que nos permita diferenciarlo de otros. Para ello lanzaremos el siguiente comando modificado el nombre según queramos:

Cambiar la zona horaria

La Raspberry no tiene el hardware del reloj del sistema es por ello que la imagen de Arch Linux ARM arranca el servicio de red ntp para obtener la hora desde internet. Pero seguramente tendremos que actualizar la zona horaria de Arch en la que estemos. En mi caso:


Partición de memoria y ver memoria libre

La Raspberry Pi tiene 256 MiB (512MiB en los modelos nuevos) que son compartidos entre la GPU y la CPU. La memoria dedicada a la GPU y CPU puede modificarse según nuestras necesidades, por ejemplo, si solo nos conectamos a la Raspberry Pi por ssh y no hacemos uso de un entorno de escritorio no hace falta que le dediquemos mucha memoria a la GPU, la GPU solo necesitará más memoria si ejecutamos programas que hagan uso de ella. Esto se configura en el archivo /boot/config.txt con la propiedad gpu_mem. Por lo que podemos editar el archivo y añadir esa propiedad al final de todas con:

La memoria libre la podemos consultar con cualquiera de los dos siguientes comandos:


Overclock

Si queremos sacarle algo más de rendimiento a la RPi podemos subir la frecuencia del procesador. Esto no es ningún peligro y no se pierde la garantía por ello si se usa el valor recomendado de 800 Mhz, la RPi por defecto funciona a 700 Mhz es decir le estamos haciendo un overclock de 100 Mhz. Hay que editar el archivo /boot/config.txt y descomentar la propiedad arm_freq=800.

Dar color al prompt de la terminal

Dar color al prompt de la terminal nos ayudará a distinguir mejor donde estamos ejecutando los comandos con lo que para evitar algún riesgo lo podemos hacer. Necesitaremos editar los archivos ~/.bashrc y /root/.bashrc con el siguiente contenido para nuestro usuario (~/.bashrc):

Y para el usuario root (/etc/.bash_profile y /root/.bashrc):




Si queremos autocompletado en el comando sudo deberemos añadir lo siguiente al archivo .bashrc de nuestro usuario:

Y estos son los pasos básicos para tener la Raspberry Pi funcionando. De momento no tenemos algo que nos aporte valor pero la instalación de algunos programas que nos lo proporcionarán como programa de descargas torrent, servidor web con php, ftp u otros los explicaré en la segunda parte de esta Guía de instalación Raspberry Pi. El software que tenemos a nuestra disposición en Arch Linux ARM salvo algunas excepciones es mucho de lo que tenemos en Arch Linux prácticamente para cada necesidad tengamos una o más opciones entre las que elegir y la wiki de Arch Linux es una de los mejores recursos para aprender como instalarlos y usarlos, todo ello con la característica de Arch Linus de tener siempre las últimas versiones de cada paquete, los paquetes de Arch Linux ARM van a la par de los que encontramos en Arch Linux.

La siguiente página (La guarida de Smaug) que he creado es es una muestra y un adelanto de algunas funciones que podemos obtener con una placa de este tipo que comentaré en la siguiente parte de esta guía. Nota: puede que en algún momento la página anterior no sea accesible ya que no tengo siempre encendida la Raspberry.

Los elementos básicos para usar este miniordenador son la placa de la Raspberry Pi, una cargador de 3A junto con una tarjeta SD.

Referencia:
Raspberry Pi, desempaquetado («unboxing»)
Raspberry Pi, Guía instalación (Parte II) Programas
Dejar procesos vivos de conexión SSH con screen
Raspberry Pi
Arch Linux ARM
Paquetes de Arch Linux ARM

viernes, 1 de junio de 2012

Hojas de estilo CSS con less

less
Hay herrmientas que surgen con el paso del tiempo y uno se pregunta como podría haber vivido antes sin ella o como no ha existido desde un principio. Una de ellas podría ser perfectamente less. Esta herramienta permite generar archivos css utilizando una notación más legible,  mantenible y compacta que se agradece cuando estamos desarrollando un proyecto con gran cantidad de trabajo de diseño además de poder usar variables y operaciones que la propia notación de las hojas de estilo css no soportan. En la propia página de less puede verse como es el lenguaje, no es muy complicado y en unas pocas horas ya estamos capacitados para utilizarlo de forma básica.

Los archivos less se compilan con nodejs generando archivos css tradicionales. Esta compilación no hace falta que la hagamos nosotros a través de nodejs ya que se puede delegar en el navegador del usuario si no nos importa cargar un archivo js más en nuestra página y vemos que la carga no se ralentiza en demasía. En la propia página de inicio de less está perfectamente explicado con un ejemplo de dos líneas.

Si optamos por compilar archivos less primeramente deberemos instalar el paquete nodejs que para Windows hay un binario y para otros sistemas quizá haya que compilarlo desde el código fuente. En Arch Linux, como siempre, es tan fácil instalarlo como ejecutar un comando y tendremos su la última versión cada vez que hagamos una actualización del sistema:

$ yaourt -S nodejs

Una vez que tenemos nodejs descargaremos la propia librería less y con el siguiente comando podremos compilar un archivo less:

$ lessc ejemplo.less > ejemplo.css
$ lessc -x ejemplo.less > ejemplo.css

Con la opción «-x» generamos un archivo eliminando los espacios innecesarios lo que hará que el archivo sea más pequeño. Si en vez de ejecutarlo desde la línea de comandos queremos incluir la compilación dentro de la herramienta de construcción que utilicemos podemos hacerlo con lo siguiente en caso de utilizar Gradle:

task less << {
 ant.exec(executable: "${LIB_HOME}/less.js-1.0/bin/lessc", output: 'src/main/webapp/css/ejemplo.css') {
  arg(line: 'src/main/webapp/css/less/ejemplo.less')
 }
}

Y con Ant sería similar:

<target name="less">
    <exec executable="${LIB_HOME}/less.js-1.0/bin/lessc" output="src/main/webapp/css/ejemplo.css">
     <arg line="src/main/webapp/less/ejemplo.less"/>
    </exec>
</target>

Referencia:
http://lesscss.org/
http://twitter.github.com/bootstrap/
http://www.archlinux.org/packages/community/x86_64/nodejs/
Como crear y usar sprites en páginas HTML