jueves, 23 de octubre de 2008

GWT & Norton 360

Despues de encontrarnos con problemas para correr una aplicación hecha con GWT nos dimos cuenta que seguramente se debía al control por parte de Norton de las iframes que son creadas dinamicamente y que cargan contenido dinamico, un metodo común para cargar archivos remotos en el "background" de la página, método que muchos sitios utilizan. Si utilizas Norton, desde su versión 2006 y encuentras que alguna aplicación estilo Gmail es extrañamente lenta prueba de desactivar la comprobación "phishing" del sitio.
Para los que desarrollen en GWT, a continuación adjunto un pequeño script que puede solucionar los problemas de GWT con Norton Antivirus, se trata de un pequeño script en bash que reemplaza las ocurrencias de la cadena javascript:'' en todos los archivos .cache.html y lo reemplaza por blank.html de modo que debe añadirse un archivo que teoricamente nunca es requerido, pero por si acaso ;).
El único parametro es la raiz de los archivos compilados por GWT, la carpeta en donde se encuentra los archivos .cache.html .

#!/bin/bash
# GWT Norton Hack Script
# This script is to solve the slow down problem of GWT applications
# when viewed in systems which have Norton AV installed. This hack was
# inspired by Gonzalo Domenechs and coded by Iago Tomas, it consists in
# a simple script which searches for files with .cache.html extension in
# a given directory and replaces all javascript:'' occurrences in them.
# This when used in a dynamic builded iframe slows down enormously the
# GWT application if it makes use of such. This tool doesn't provide any
# guarantee to solve your problems its just a script to
# avoid making hand work.

VERSION="0.1"

if [ $# -lt 1 ]; then
echo "GWT Norton Hack Script $VERSION"
echo "Usage: $0 [path-to-files]"
exit 0
fi
VAR="$1*.cache.html"
for i in $( ls $VAR); do
echo "Found: $i"
cp $i "$i.bak"
$(sed "s/javascript:''/blank.html/g"<$i&>"$i.new")
mv $i "$i.bak"
mv "$i.new" $i
rm -f "$i.bak"
done
echo "Backup files where created"

lunes, 11 de agosto de 2008

GWT RequestBuilder

Despues de ver la presentación de Google I/O http://sites.google.com/site/io/gwt-and-client-server-communication en la cual se presentan y se comentan las mejoras de GWT 1.5 y además se aconsejan ciertas técnicas para la optimización de la comunicación entre cliente y servidor, GWT RPC es una de las mejores opciones para la comunicación entre servidor y cliente. GWT RPC es un protocolo creado por los desarrolladores de GWT que codifica los datos para guardando los tipos. Este protocolo es una extension de JSON codificada, permite una comunicación segura y con un payload mínimo ya que al ser JSON los datos son interpretados directamente por el navegador no hay descodificación costosa como en el caso de XML u otros servicios REST.

viernes, 11 de abril de 2008

Si los lenguajes de programación flotaran en el agua…

¿Nunca os habéis preguntado cómo serían los lenguajes de programación si… estos flotaran como barcos en el agua? ¿Cómo serían los lenguajes de programación si fueran barcos, si fuera botes?
Turing
Turing sería definitivamente un kayak. Pequeño. Propulsado por energía humana. Se suele usar para aprender a usar los barcos… y es muy canadiense

Java
Java puede ser fácilmente un buque de carga. Es voluminoso. Comercial. Aunque puede cargar mucho peso, llevará un proyecto pero no será muy divertido de llevar a cabo.
Perl
Perl será un remolcador. Poderoso para remolcar a Java donde sea en 80 caracteres o menos.
Ruby
Quizás… una lancha sería la mejor forma de describir a Ruby. Elegante, sexy, muy divertido de conducir. Muy moderno.

PHP
PHP… será una balsa de bambú. Un montón de apaños seguidos… aunque todavía consigue mantenerse a flote.

C
C es un submarino nuclear. Las instrucciones estarán posiblemente en una lengua extranjera (extraña) pero… todo el código del hardware estará creado para el rendimiento perfecto.HTML
HTML…. realmente no es un bote.Lenguaje ensamblador
Barco-casa flotante. Potente… pero cansino, abominable y pedante.
.NET (Microsoft .NET Framework)
El… RMS Titatic. Grande, poderoso, con mucha tripulación y puede con todo…. pero con con un pequeño y ridículo golpe te quedas sin.
Pascal
Pascal entraría en lo que se dice en un buque viejo a vapor. Tan grande como antiguo. Los jóvenes marineros siempre lo usaron para aprender… ahora solo se exhibe en algunos museos, así como la fecha de su muerte.
Esta es una traducción realizada por Boozox.net
Además de la traducción ha añadido un par de definiciones, en todo caso muy buen trabajo. Un saludo.
NB: Sí sabeis de alguno más no dudéis, vía una entrada de meneame desde un blog… inglés con mucha comunidad en un foro.

jueves, 10 de abril de 2008

Ubuntu no tan libre como se pinta

Llevo utilizando Ubuntu desde hace algo más de un año en la versión desktop para mi portatil y desde hace poco que tomamos en serio la versión Server de esta distribución. Pero después de lo que leí en una página publicada por Jordi Mas, un activista en la comunidad opensource catalana, coordinador del proyecto Softcatalà, en donde denunciaba la falta de colaboración por parte del proyecto Ubuntu en la traducción de aplicaciones.
Al parecer todas las traducciones aportadas por los usuarios para internacionalizar las aplicaciones de la distribución no son agregadas a las traducciones oficiales, duplicando así el trabajo realizado. Esto no encaja con la imagen social y colaborativa que presenta Ubuntu, por lo visto aprovecha las aportaciones de la comunidad opensource pero no participa en ella. Estoy seguro que varios de los colaboradores y creadores de Ubuntu participan de forma activa en proyectos Open Source pero al no contribuir con las traducciones desde su distribución parece que Ubuntu quiera aprovecharse de la buena fe de los usuarios.
De todos modos por el momento seguiré utilizando la versión Desktop y seguiré apoyando su uso para servidores, pero esto me deja con ciertas dudas para apoyarlo en futuras ocasiones si sigue leyendo por ahí su falta de participación.

miércoles, 9 de abril de 2008

Cpan Writing Makefile Not OK

Despues de estar rebuscando en la red sobre el último problema que me ha surgido durante la instalación de modulos a traves de CPAN para perl he podido hallar la solución en uno de los foros escondidos de CPAN. El enlace http://www.cpanforum.com/threads/502 y ahora resumo un poco el problema y la solución que he encontrado.
Resulta que despues de una instalación de una Ubuntu Server sín más que el entorno base, al ir instalando paquetes necesarios manualmente a traves de apt-get ninguno de los paquetes de desarrollo como make se instalaron por dependencia y la instalación de Perl no dió ningún mensaje de advertencia de que requiriese de estos para utilizarse, lo cual era cierto, solo que hay el pequeño detalle de que entonces no se podrán instalar modulos adicionales, al intentar instalarlos siempre falla en la fase de creación del Makefile, con un escueto
Writing Makefile
----Not OK

Bueno pues como se indica en el foro, el problema reside en que aun habiendo instalado make, si este se ha instalado posteriormente a la instalación de Perl, perl no define en la configuración del entorno de CPAN los parametros para utilizar make. Esto se puede verificar ejecutando CPAN,
  • cpan> o conf
el comando devuelve las variables de entorno fijadas, en mi caso solo definiendo la variable make ya he resuelto el problema pero esto depende del entorno de cada uno.

miércoles, 20 de febrero de 2008

ffencoderd el demonio de YouTube

Bueno esta vez solo quería comentaros sobre el nuevo proyecto en el que me he embarcado. Despues de decidirse que en el nuevo portal que estoy desarrollando debía incluirse una sección de videos estilo YouTube, empecé ha indagar por la red para ver si encontraba la manera de facilitar a los usuarios la codificación de videos a formato flv sin penalizar nuestro pobre servidor demasiado.
Mi idea era encontrar algún tipo de programa que permitiese programar las conversiones de formatos, idealmente este sería un servidor independiente que permitiese codificar, y servir los videos una vez codificados.
Pues despues de unos días (no intensivos) de búsqueda solo encontré la solución de On2, los mismos que desarrollaron uno de los codecs que pueden utilizarse nativamente en flash video. Su solución, de pago obviamente, incluia un pequeño servidor con un servicio rpc permitiendo la interactuación para enviar videos a ser codificados, realizar un seguimiento de la conversión y obtenerlos codificados.
On2 lo llama flixd o la solucion completa (cliente/servidor) Flix Engine/SDK. Proporciona implementaciones para C/Java/Perl y Python, también parace que hay disponible una par a ruby (no lo sé, eh! no conozco ruby)
ffencoderd intenta realizar unas funciones similares a las de flixd, aunque por el momento solo realiza las funciones básicas espero que pronto pueda tener tiempo para desarrollarlo e implementar funcionalidades como servicio soap y servicio http para servir los videos.
Por ahora este pequeño demonio (daemon ;) permite programar diferentes conversiones utilizando ficheros xml para definir un proceso de conversion y obtener los datos de los ficheros convertidos. Junto con el programa se ha adjuntado un ejemplo de implementacion en php. Vamos a ver como utilizariamos ffencoderd en un entorno PHP.
Lo primero sería descargar ffencoderd de http://ffencoderd.sourceforge.net , disponer de ffmpeg,PHP y Perl instalados en nuestro sistema (opcionalmente perl y ffmpeg en el servidor donde se ejecutará el proceso de ffencoderd y PHP en el servidor desde donde se servirán los videos).
Una vez tengamos descargado ffencoderd descomprimimos los contenidos en cualquier carpeta de nuestro sistema, lo primero será crear un fichero de configuración para ello encontraremos una versión inicial en la carpeta 'ffencoderd/doc' editamos el fichero para que coincida con nuestro sistema, cada opcion esta comentada en el fichero original. En principio los cambios necesarios serán los parametros referentes a los directorios y ficheros utilizados/creados por ffencoderd.
A revisar :
  • output.file : ruta y nombre del fichero de salida (ej: /home/iago/ffencoderd.xml)
  • process.dir : ruta hacia el directorio albergando los ficheros de procesos
  • video.output.dir : ruta hacia el directorio albergando los videos codificados
  • video.input.dir : ruta hacia el directorio albergando los videos sin codificar
  • pid.dir : ruta hacia una carpeta cualquiera, normalmente /var/run
  • log.dir : ruta hacia una carpeta cualquiera, este directorio albergara los archivos de registro
  • data.dir : ruta hacia un directorio cualquiera, este directorio albergara los ficheros que crea ffencoderd durante la ejecución
Una vez revisado el fichero de configuracion, solo debemos ejecutar en la linea de comandos el archivo principal "ffencoderd.pl" , este acepta varios parametros, puede utilizarse el parametro '-h' para ver todos los parametros aceptados. Nosotros por el momento solo utilizaremos el parametro '-c' que nos permite indicar el fichero de configuracion que deseamos utilizar.
En una consola ejecutamos ffencoderd:
'./ffencoderd.pl -c fichero_configuracion'
Esto iniciará el programa, lo pasará al background y nos devolverá a la consola. Podemos verificar si el se ha puesto en marcha utilizando 'ps -HA|grep ffencoderd', debería devolver una linea como '/usr/bin/perl -X ./ffencoderd.pl ...'
Esto significa que el proceso esta funcionando correctamente, si hemos habilitado el registro (definiendo true en el parametro del fichero de configuración 'log') también podemos verificar el funcionamiento en la carpeta que se ha definido en 'log.dir'.
Bien ahora ya podemos enviar video para ser codificados, los videos deben copiarse a la carpeta definida en 'video.input.dir', esto lo podemos hacer utilizando cualquier método en el servidor, con PHP, via FTP, SSH...
En la carpeta 'doc/php' hay un ejemplo de interfaz en PHP, los archivos Ffencoderd.php, Process.php y IProcess.php.
En la misma carpeta encontramos un ejemplo de utilización en Example.php, a continuación se detalla un poco este archivo.

Instanciamos la interfaz de ffencoderd, el primer parametro es el archivo que ffencoderd crea con su salida, este concuerda con el parametro 'output.file' el segundo parametro es el directorio que ffencoderd lee para los procesos corresponde a 'process.dir'
$ffencoderd = new Ffencoderd('http://localhost/ffencoderd/ffencoder.xml','/opt/ffencoderd/process/');
Añadir un nuevo proceso, para ello instanciamos la clase Process, el primer parametro sera un identificador unico para el proceso, podemos utilizar cualquier tipo, en principio un entero nos servirá
$process = new Process(1,'ser5.mov','220x300');
Añadimos el proceso para ser procesado
$ffencoderd->addProcess($process);
Comunicamos a ffencoderd que ya puede codificar, se ha finalizado el envio
$ffencoderd->process();

Ahora si queremos podemos verificar si ffencoderd ha terminado de codificar el video utilizando
$ffencoderd = new Ffencoderd('http://localhost/ffencoderd/ffencoder.xml','/opt/ffencoderd/process/');
$process = new Process(1,'ser5.mov');
$status = $ffencoderd->verify($process);
switch($status){
case Ffencoderd::PROCESS_OK :
echo "
Video encoding process ended";
break;
case Ffencoderd::PROCESS_IN_WORK:
echo "
Video encoding process in work";
break;
}

lunes, 4 de febrero de 2008

La clase Locale de AS3, internacionalización en actionscript 3

Como no me fue fácil decubrir cómo funcionaba la clase Locale en AS3, quería dejarlo para la bitácora por si a alguién le puede ser útil.
Éste es un método para permitir internacionalizar una aplicación flash, ActionScript 3, este método no puede utilizarse con ActionScript 2. Además éste método es para utilizar principalmente con FlashDevelop, supongo que con Flash CS3 IDE puede también hacerse pero no lo he probado.
Primero ActionScript 3 tiene soporte para los archivos XLIFF , este es una especificación para archivos XML, lo básico es que debemos crear un archivo por cada idioma que queramos implementar con el siguiente formato. Al crear este archivo XML debemos vigilar de utilizar una codificación UTF-8, si lo creamos con notepad al guardar se puede definir el tipo de codificación en el desplegable de debajo del nombre del arhivo a guardar.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN"
"http://www.oasis-open.org/committees/xliff/documents/xliff.dtd" >
<xliff version="1.0" lang="es">
<file datatype="plaintext" original="ICCS.swf" language="ES">
<header></header>
<body>
<trans-unit id="010" resname="VER_TODO">
<source>Ver todo</source>
</trans-unit>
</body>
</file>
</xliff>



Una vez creado nuestro archivo lo guardamos en cualquier carpeta dentro de nuestro proyecto (o en cualquier lugar del sistema), lo único que debermos indicarle a la clase Locale donde se halla cada archivo de localización (nuestro archivos XML). Podemos utilizar una ruta absoluta o relativa, aunque aconsejo que sea relativa y ubicar la carpeta dentro de la misma carpeta donde se encuentra nuestro SWF principal.
Para cargar los archivos de localización y poder utilizarlos dentro de la aplicación, debemos definir en nuestro método principal las siguientes lineas:
package {
...
import flash.Locale.*;
...
Locale.addXMLPath("es", "lang/es.xml");
Locale.initialize();
Locale.setDefaultLang("es");
Locale.setLoadCallback(init);
....
public function init(success:Boolean):void {

trace(Locale.loadString("ID_PRUEBA"));
}

Bien, estas lineas cargarán los archivos de localización y el método loadString nos permite llamar a nuestras traducciones en el idioma definido.
Así por encima los métodos que llamamos hacen lo siguiente:
Locale.addXMLPath(id,path) , añade al listado interno la ruta y el identificador del archivo de localización, luego Locale.initialize() inicializa la instancia con todos los idiomas, Locale.setDefaultLang define el idioma principal a utilizar y Locale.setLoadCallback(funcion) define la funcion que se llamara una vez finalizada la carga de los archivos de localización.
Una vez finalizada la carga podremos llamar al método Locale.loadString(id_traduccion) el cual nos devuelve la traduccion referenciada por el id proporcionado en el idioma definido.

jueves, 31 de enero de 2008

Pixelizer AS3

Hace un par de meses que he descubierto AS3 (actionscript 3) y el montón de cosas que permite hacer, bueno ya os contaré más adelante algunas de ellas de momento quería compartir una modesta clase que he adaptado a ActionScript 3 para hacer el efecto de pixelización de una imagen, la clase es muy fácil de utilizar. La he adaptado de actionscript 2 que he encontrado en el blog de sephorith.com

package {
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.geom.Rectangle;

public class Pixelizer extends MovieClip {
/** define the variables used **/
private var img:Bitmap;
private var cloned:Bitmap;
private var mc:MovieClip;
private var rect:Rectangle;
private var row:Number;
private var w:Number;
private var h:Number;
private var diff:Number;
private var pixelSize:Number;
private var iPixelSize:Number;
private var step:Number;
private var _timer:Timer;
public function Pixelizer(image_path:Class, pixelSz:Number = 30, _step:Number = 5) {
iPixelSize = pixelSz;
step = _step;
pixelSize = pixelSz;
// attach a bitmapData loading an image
// from the library
img = Bitmap(new image_path);

// and clone it
cloned = Bitmap(new image_path);
// getting the bitmapdata width and height
w = img.width;
h = img.height;

// create a new movieclip and attach the image
// to it
addChild(img);
rect = new Rectangle();
row = -1;
while(row < diff =" w" width =" diff" height =" pixelSize" number =" 0;" y =" c;" _timer =" new" rect =" new" row =" 0;" diff =" w" width =" diff" height =" pixelSize" number =" 0;" y =" c"> 1) {
pixelSize -= step;
}
else if (pixelSize == 1) {
_timer.stop();
}
else {
pixelSize = 1;
}
e.updateAfterEvent();
}
}
}

Para utilizarla solo debe importarse la clase e instanciarla pasandole como parametro una imagen cargada
ej:

[Embed(source = '../library/ojo.jpg')] private var FondoImage:Class;
...
var p:Pixelizer = new Pixelizer(FondoImage,20,2);
...

La clase extiende a la clase MovieClip así que una vez instanciada solo hay que añadirla mediante el método addChild al escenario o a otro elemento.

lunes, 28 de enero de 2008

A2DP en Qtek s200

Esta vez sólo quería hacer una recopilación de la información que he encontrado en los foros de TodoPocketPc.com, ahí se explica como instalar unos cascos bluetooth en diversos dispositivos a través de diversos posts por los cuales me ví obligado a indagar. Visto el caos que me suponía entender todas la instrucciones necesarias para instalar unos simples archivos para hacer funcionar mis recientemente obtenidos (regalados por mi novia :P) cascos Nokia bluetooth, he decidido dejar un post con las instrucciones necesarias para ello, por si le sirve a alguien.
De hecho el proceso es muy simple, si habeis leido los foros de todopocketpc al respecto sabreis que no es complicado o si crees que lo es no te preocupes.
En primer lugar debes descargar http://www.megaupload.com/es/?d=QCMU40SQ (sigue las instrucciones de megaupload para hacerlo), este archivo contiene los archivos necesarios para activar el servicio A2DP requerido para hacer funcionar cascos bluetooth estereo funcionando con este servicio (estos no són cascos manos libres normales, sino estereo).

Una vez descargado el archivo, descomprimelo en cualquier lugar.
Copia los archivos .dll a la carpeta \Windows de la Qtek S200
Copia los otros dos archivos "a2dp.reg" y "Tor_A2DP_cert.cab".
Instala "Tor_A2DP_cert.cab"
Utilizando Resco Explorer Registry Add-in haz click en "Menú>Importar" e importa el archivo "a2dp.reg" (puedes bajar una version de prueba en http://www.resco.net/pocketpc/explorer/downloads.asp , tienes de instalar Resco Explorer y Resco Explorer Add-In)
Reinicia la Qtek

Una vez reiniciada la Qtek crea una nueva asociación con los cascos bluetooth (sí ya la has creado elimina la asociación y creala de nuevo) al asociar los cascos se mostrará un nuevo servicio, "Wireless stereo", activalo.
Ya está, si todo ha funcionado deberás poder escuchar tus canciones preferidas con tus cascos bluetooth.