Jan 31

Windows Vista sin problemas

No sé de qué se queja la gente con Windows Vista. Si se instala correctamente, como se indica en este video, queda listo para su uso y no da ningún problema… nunca.

Visto en Instalar Window Vista correctamente.

Jan 30

Apache con Python en ubuntu

Para empezar a jugar con la mini-aplicación que comenté en el post anterior, me he dedicado a instalar en casa Apache en ubuntu, y luego el módulo de Python.

Lo de Apache sin problemas. Usé el gestor de paquetes de synaptic, busqué apache2 para marcar el servidor Apache y busqué "apache2 python", para el mod de Apache/Python. La instalación sin problemas.

Python viene instalado en ubuntu y MySQL ya lo tenía.

El módulo de Apache/python parece que se carga el solito en la configuración de Apache. El fichero /etc/apache2/apache2.conf hace un include de /etc/apache2/mods-enabled/*.load y ahí dentro está el fichero mod-python.load que se encarga de cargar el módulo.

En el fichero /etc/apache2/apache2.conf añadí al final unas líneas para indicar en qué directorios estarán mis programas python y que Apache sepa redirigir las peticiones al sitio adecuado. Según veo en la ayuda, hay dos posibles formas de hacerlo. Una consiste en indicar un directorio y un handler en python que nos hagamos a medida. La otra  opción, que yo he usado, es poner un handler por defecto. Las líneas añadidas al final del fichero apache2.conf son

<Directory /var/www/python>
        SetHandler mod_python
        PythonHandler mod_python.publisher
</Directory>

De esta forma, cualquier petición a http://localhost/python/cosa se traduce en la llamada a la función cosa() dentro del fichero index.py. También, si tenemos un fichero kk.py con una función hola(), se puede poner http://localhost/python/kk.py/hola. Si simplemente ponemos http://localhost/python/, buscará un index.py y dentro la función index().

Esto es algo que me ha llamado mucho la atención. De php, jsp o html estoy acostumbrado a llamar desde la url directamente a un fichero .php, .jsp o .html. Aquí se llama a la función de dentro del fichero.

Las funciones que ponemos en python reciben un parámetro req. Este es un objeto que contiene la información de la petición hecha por el cliente -ip del cliente, uri pedida, etc- y que a su vez se usa para devolver los resultados al cliente. Algo típico podría ser esto

def funcion(req):
   req.content_type = "text/html"
   req.write("<html><head></head><body><p>hola mundo</p></body></html>")
  

Una vez vistos los rudimentos de cómo va esto y sin tener ni pajolera idea de python, me decidí a intentar conectarme a la base de datos de mysql. Un copy-paste de código encontrado por internet me da esto

def db(req):
   try:
      import MySQLdb
      db=MySQLdb.connect(host=’localhost’,user=’el_user’, passwd=’la_passwd’,db=’la_bd’)
      cursor=db.cursor()
      sql=’Select * From tabla’
      cursor.execute(sql)
      resultado=cursor.fetchall()
      req.content_type="text/html"
      req.write(’Datos de la tabla<br>’)
      for registro in resultado:
         #suponemos tres campos, uno numerico y dos string
         #el numerico necesita conversion a string str(…)
         req.write(str(registro[0])+’,'+registro[1]+’,'+registro[2]+’<br>’)
         req.write(”)
   except:
      return ‘error’

y listo, funcionó tras algunas pruebas y cambios. El return "error" del final es en caso de excepción. Ese texto se mostrará en el navegador tal cual.

Ahora sólo me queda empollar un poco de python.

Jan 29

Seguiré jugando

La verdad es que muchas veces el trabajo es aburrido y rutinario. Cuando tienes que codificar, muchas veces son cosas no especialmente interesantes, que no te aportan nada nuevo o que estás aburrido de hacer una y otra vez. En mi caso, suelo buscar nuevas formas de hacerlo, mejoras, herramientas, formas más rápidas y trato de evitar la rutina.

Un ejemplo es la traducción a ruso que comenté en un post anterior. Un trabajo estúpido, como sacar etiquetas de texto de java y pasarlas a un excel me ha servidor para jugar un poco con POI.

El otro día, en casa, se me ocurrió bajarme y jugar un poco con python, para ver qué pinta tiene. Pues bien, hoy en el trabajo se me ha presentado la oportunidad de darle la vuelta a las cosas y una petición capciosa de mi jefa me va a proporcionar un rato de entretenimiento.

Ella normalmente tiene que pasar el tiempo que han dedicado las treinta personas bajo su mando a los diferentes proyectos. Debe hacerlo una vez al mes y una vez al mes pierde uno o dos días preguntando a todos uno por uno en qué proyectos han trabajado ese mes y generando el excel correspondiente.

Debido a una baja prolongada de ella -dos meses- me tocó a mi durante dos meses hacer esa tarea tediosa. Como era algo temporal, tampoco me preocupé demasiado. Sin embargo, este mes ha intentado volver a "delegar" la tarea en mí, a pesar de que ya no está de baja, y me ha soltado una indirecta estilo "pensé que después de dos meses ya habías inventado algo para hacer este trabajo más fácil" -lo dijo de buen rollo :-) , haciendo alusión a que soy el más vago del mundo y que por no trabajar siempre encuentro la forma fácil de resolver los problemas-. Además, me ha amenazado con que a partir del próximo mes me va a tocar a mí para siempre jamás, para forzarme a encontrar esa forma fácil.

Pues bien, me da una mano y voy a cogerme el brazo entero. Cogeré una base de datos, el servidor Apache y haré en Python, para aprenderlo, una mini-aplicación para que la gente pueda meter sus tiempos. Una vez que lo tenga, un pequeño botón de exportar a excel en el formato requerido. No sé lo que me llevará ni lo complejo que será, pero desde luego es más divertido que perder todos los meses dos días recogiendo dedicaciones de la gente.

De todas formas, es algo que había empezado en php en su día -ya andaba yo con la mosca detrás de la oreja- y que tendré que retomar ahora. Pero ahora me mola más python…

Jan 25

… y del ruso pasamos al Excel con POI

Siguiendo el post anterior, ya me  he dado la pequeña paliza de ir externalizando String por todo el código eclipse para sacar los textos y que alguien los traduzca al inglés y al ruso. Yo domino varios idiomas: colombiano, cubano, chileno, argentino, mexicano, etc, pero inglés no y el ruso menos, así que todo el trabajo para el traductor, que para eso le pagan.

Me comentan que el traductor, cómo no, es ofimático, así que lo de darle los ficheros de propiedades que encima son textos técnicos pues no vale. Tenemos que pasar esos textos en una columna de una hoja excel. Debemos añadir otra columna en la hoja con explicaciones de los textos más complejos, palabras que no se traducen o significado de ciertas palabras técnicas o propias del proyecto. Y dos columnas más vacías, una para que lo ponga en inglés y otra en ruso.

Pues bien, es una oportunidad estupenda para aprender a usar POI y hacer un programa java que haga:

  • Se le indica un directorio a partir del cual buscar, que será el directorio del proyecto. A partir de ahí, busca recursivamente todos los ficheros messages.properties generados por eclipse. Para la búsqueda de ficheros recursivamente, he usado un pequeño buscador de ficheros en java que me hice en su día.
  • Lee cada uno de esos ficheros y genera varios EXCEL con el formato indicado anteriormente. De cosecha propia he añadido una columna con la "clave" de la etiqueta en el properties, de forma que luego pueda generar los messages_en.properties y messages_ru.properties también de forma automática. Me he inventado lo de _ru, de ruso.
  • Salva el excel poniendo un nombre al fichero xls que corresponda más o menos con el paquete donde está el messages.properties. Algo como cambiar los puntos de los paquetes por _

Dicho y hecho. Me he cogido POI, un pequeño ejemplo de uso de otro compañero y me he hecho el programita java. Ahora ando con la tontería de poner en la hoja una cabecera bonita, unos bordes para las celdas y demás.

Aprovecho para dar unas pequeñas indicaciones de cómo se usa POI para crear un EXCEL.

Ante todo, bajarnos el jar de poi. Como lo he hecho con maven, lo he añadido como dependencia en el pom.xml copiando del pom.xml de poi, así que sin problemas, maven crea el proyecto eclipse y se baja el jar.

Y en el código java, lo primero, crear el cuaderno de excel y una hoja

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("Hoja 1");

creamos ahora una fila, la fila cero, y le ponemos celdas de cabecera

HSSFRow row = sheet1.createRow((short) 0);
HSSFCell cell = row.createCell((short) 0);  // celda de columna 0
cell.setCellValue("ESPAÑOL");
cell = row.createCell((short) 1);  // celda de columna 1
cell.setCellValue("RUSO");

y así sucesivamente con el resto de filas y columnas y todos los datos. Finalmente, para guardar definitivamente el fichero

FileOutputStream fileOut = new FileOutputStream("fichero.xls");
wb.write(fileOut);
fileOut.close();

y listo. La verdad es que me ha asombrado lo sencillo que es. Ahora ando metiendo estilos en las celdas y tampoco parece complejo, aunque sí un poco más laborioso. Así que ya tengo dos entretenimientos que hacer. Un par de pequeños tutoriales en la Chuwiki: Un ejemplo sencillo y algo como "ExportTableModelToExcel" y el viceinverso.

Jan 24

Traduciendo al ruso

Nuestros proyectos son -o eran- habitualmente para España, por lo que nunca hemos prestado demasiada atención al idioma de las interfaces gráficas, ni a la internacionalización de java, ni a los ResourceBundle, ni a ninguna otra cosa parecida. El texto va directamente en el código y en español.

Pero la hemos liado. Tenemos que hacer uno de nuestros proyectos para un país de habla rusa. Tenemos que traducir todas las etiquetas al ruso, con caracteres cirílicos, por supuesto.

Pues nada, me he puesto a ello. He cogido eclipse y con su "externalize strings…" me he puesto a sacar ficheros de propiedades con los textos. Eclipse es una pequeña maravilla y todo eso se hacer rápido. Sin embargo, se me han planteado varias dudas.

Hay cosas, como los formatos de fecha y hora que no sé si tienen o no tienen traducción al ruso, si el formato usado en código para las máscaras sería correcto o no en ruso. Por ejemplo, en inglés suele ponerse delante el mes, luego el día y finalmente el año, mientras que en español va primero el día. Algo como dd/mm/yy en inglés podría ser mm/dd/yy. Encima, esa posible traducción visible no sé hasta qué punto es compatible con el cirílico.

Por otro lado tenemos mensajes que se componen de cosas como "hay " + variable + "chirimbolos en " +otraVariable. ¿Se compondrá la frase igual en ruso?. El que nos traduzca los ficheros de propiedades traducirá literalmente "hay" y "chirimbolos en". La cadena en cirílico se compondrá de la misma forma. ¿tendrá sentido?. Veo aquí que la internacionalización no es sólo sacar cadenas de texto y usar ResourceBundle. Posiblemente también hubieras sido necesario usar cosas como la clase MessageFormat, que compone mensajes de ese tipo. Siempre me pregunté para qué serviría esa clase. Ahora lo veo más claro. El formato del mensaje sería "hay {0} chirimbolos en {1}". Indicándole al traductor que [0} {1} son números y no se traducen, el traductor puede componer la frase correctamente en ruso sabiendo todo el significado.

Y se me ocurren otras chorradas, pero supongo que Windows es Windows para todos. ¿localhost es también localhost en ruso o hay que ponerlo en cirílico? ¿y los nombres de los servidores con los que debemos conectarnos por socket? ¿En cirílico se usan las mismas comas, puntos, barras separadoras de directorios \ y demás con el mismo significado?.

En fin, que veo altas probabilidades de pequeños problemas de funcionamiento de código debidos a la traducción a cirílico de ciertas cosas…. Si ya en español tenemos problemas con las vocales acentuadas que a veces salen como gurruños o cuadraditos según cómo se escriban y vengan de la base de datos, no te digo si encima no hay dos letras que se parezcan.

Jan 23

Actualización fallida de Wordpress

Ayer se me ocurrió intentar actualiza la versión de Wordpress de este blog. Todo contento, fuí al panel de control de mi hosting y le dí al botón de "actualizar" a la nueva versión disponible. Tras tres segundos escasos, un mensaje me dice que ya está actualizado. Efectivamente, así era, pero con dos pegas importantes.

La primera, menos importante pero estúpida, es que le dio por cambiarme los acentos de títulos, categorías y demás por carcateres extraños.

La segunda y que me llevó a deshacer el cambio, es que el video de youtube que hay en el post de "Fantastic Machine", se empeñó en desplazarse hacia abajo hasta que las barras de enlaces laterales quedaban vacías y entonces, pegarse totalmente a la izquierda. Vaya, que no se salía de la pantalla por la izquierda porque tiene afán de protagonismo y como todo video que se precie quiere ser visto, pero allí estaba, pegadito al borde. A partir de ahí, el resto del texto también.

Por más que me puse a jugar con el editor para tratar de arreglarlo, poniéndolo en formato HTML para controlar exactamente qué es lo que estaba escribiendo y por más que revise las hojas css por si había algún float:left en algún sitio, nada de nada. Totalmente incapaz de poner el video en la columna central, que es donde debe estar. Es más, comparando lo que yo ponía en el editor HTML y el código HTML de la página resultante cuando la estaba visualizando en el navegador, se parecían como un higo a una castaña. En el momento de publicar, wordpress o el editor "se inventan" cosas.

Así que deshice todos los cambios y volví a la versión antigua. Afortunadamente estas actualizaciones automáticas desde el panel de control del hosting se respaldan, de forma que es relativamente sencillo echarse atrás.

Sin embargo, todo esto me confirma dos fallos que veo en aplicaciones como wordpress y que creo que son generales para muchas aplicaciones de este tipo o que generan contenido web.

El primer fallo es que para el contenido principal sí tienen en cuenta los acentos y esas cosas para reemplazarlos por los famosos &aacute; de HTML. Sin embargo, no lo hace en las pequeñas cajitas de texto para título, etiquetas, tags, metas, etc. Ahí, si pones un acento, va como acento a la página web, con lo que según el navegador que tengas, codificación de caracteres y demás, lo verás bien o no.

El segundo fallo es que todos estos editores de contenido, en su afán por dejar en condiciones el código HTML que un torpe como tú mete, se ven con la libertad de tocarlo a su gusto. Muchas veces es completamente imposible -o al menos muy difícil- encontrar el truco para conseguir lo que quieres. Por ejemplo, cuando escribes código java para que se vea en un post, es bastante fastidiado conseguir el sangrado de una forma simple. En mi caso, los tags <pre> no sirven para nada, el editor se los come. Tras mucho probar, he descubierto que metiéndolo en un <blockquote> entonces sí respeta los sangrados. A poco que te fijes en foros y blogs por ahí, verás que es un mal bastante extendido el "no sangrar" los ejemplos de código. Muchas veces tiene la culpa la persona que es poco cuidadosa, pero muchas veces es el dichoso gestor de contenido que hace lo que le da la gana. De la misma forma, yo he tenido problemas en la nueva versión de wordpress con el tag <object> del video de youtube. Aunque yo dejaba el HTML correcto, el editor se empeñaba en meterme el <object> entre <p> y </p>, pero dejando fuera todo lo demás, tal que así

<p><object …></p>….</object>

e incluso en algún momento le dio por cerrarme y abrirme un nuevo <object> entre medias, de forma que veía dos cuadros de video, pero vacíos, ya que el contenido de los object era totalmente caótico.

Ojo, no quiero decir que no acabe funcionando, sino que a veces algo que debería ser evidente hay que andar liándolo demasiado hasta pillar el truco. ¿Tanto cuesta que si pongo tres espacios en un editor WYSIWYG para sangrar algo, lo convierta en el código HTML necesario para que haya tres espacios sangrando ese algo? ¿Por qué no puedo sangrar la primera línea de cada párrafo tres espacios desde el editor WYSIWG sin necesidad de hacer cosas raras con el CSS o los TAGS?. Me direis que para eso está CSS y tendréis razón, pero entonces WYSIWYG pierde totalmente su significado. Sería WYSIWYG…SYQ (What You See Is What You Get … Si Yo Quiero)

¿Alguien tiene estos problemas o es que soy demasiado torpe?.

Jan 21

Aprendiendo a cabezazos

Pues acabo de aprender una cosa nueva. Cómo no, una cosa que NO debo hacer, porque hoy me ha tocado sufrir las consecuencias.

Hace aproximadamente un año tuve que hacer un cambio importante en un proyecto. Un cambio en unos pocos ficheros fuente, pero que podían dejar "descojonado" el sistema durante una buena temporada hasta que se volviera a afinar. Así que me decidí a abrir una rama de CVS para hacer mis cambios, de forma que cuando en esa rama todo estuviera adecuadamente depurado, juntarlo con la rama principal con ciertas garantías.

Pues bien, comencé los cambios y lo dejé después de un par de semanas de trabajo casi todo a punto… pero me interrumpieron con otra de esas labores super importantes que no pueden esperar a otro día … y aquella rama se quedó sin juntar … hasta ahora.

Hoy me he puesto a intentar juntar aquella rama con la principal y es un verdadero lio. En parte por recordar qué es lo que había tocado, pero principalmente he tenido que sufrir una de mis pequñas manías. Tengo la manía de refactorizar el código que toco, comentar lo que está sin comentar, arreglar los sangrados, eliminar warnings, etc, etc. Pues bien, eso ha hecho que sea prácticamente imposible ver qué cambios reales de código se hicieron entre la rama principal y la rama secundaria. Un diff de ambas versiones daba por cambiadas casi todas las líneas, aunque sólo fuera por temas de sangrado.

Así que ya sé dos cosas que NO debo hacer:

  1. Dedicarme a hacer refactoring en una rama. En las ramas hay que tocar lo mínimo imprescindible para facilitar la tarea de unirlas a la rama principal.
  2. No dejar tanto tiempo hasta integrar la rama. Si dejas mucho tiempo, es posible incluso que se te ocurra hacer refactoring y comentar el código de la rama principal, aunque no lo hagas en la secundaria, con lo que el efecto es el mismo.

Y de paso, sé una cosa que no deben hacer NUNCA los jefes

  1. Interrumpir a un currito cuando tiene algo a medias con otra cosa muy importante. Y menos interrumpirlo durante un año.

Jan 19

Fantastic Machine

Es algo casi increíble.

Fijaos como todas las bolas acaban entrando en los conos receptores.

Esta increíble máquina fué construída gracias a un esfuerzo de colaboración entre el Conservatorio de Música Robert M. Trammell y la Escuela de Ingeniería Sharon Wick en la Universidad de Iowa. Increíblemente, el 97% de los componentes de la máquina vienen de las fábricas de John Deere y de Equipos de Riego Bancroft, de Iowa.

Sí !!!… equipamientos para granjas !!!.

Al equipo le llevó 13.029 horas el montaje, alineación, calibración y decoración antes de poder grabar este video, aunque como puedes ver el esfuerzo mereció la pena.

Hoy día está en funcionamiento en el Matthew Gerhard Alumni Hall, de la Indiana University , Bloomington , y ya está programada su donación al Instituto Smithsonian.

Lástima que sea mentira y sólo sea una animación de video….

Jan 18

Temas con iGoogle

No me fijo mucho en las cosas, así que no sé el tiempo que lleva, pero en iGoogle pone "nuevo…."

La cosa es que con tu cuenta de gmail puedes entrar en sesión en la página de google, con lo que puedes "personalizar" google. Hasta ahora lo usaba para tener ahí los "feeds" de los blogs que visito y el de la Chuwiki, por si alguien se equivoca algún día y escribe algo.

Pues bien, ahora en la parte superior derecha del buscador de google, cuando estás en sesión, tienes un enlace a "seleccione un tema". Pinchando ahí se puede seleccionar una especie de "tema" para google, de forma que luego la caja de busqueda te aparece dentro de un "banner" y los colores de la página en general toman los tonos propios del tema.

Lo más curioso es que muchos de los banner son un paisaje con un sol. Al instalar el tema, te pide que digas en que ciudad/pais/zona horaria vives, de forma que la foto del "banner" y el sol van cambiando de posisición. Lo he instalado hace un par de horas y el sol efectivamente ha cambiado de posición. Esta noche veré si se hace de noche…

ACTUALIZADO TRES SEGUNDOS DESPUÉS:

Voy a ahorraros el comentario y ya lo pongo yo.  ¡¡ A buenas horas, mangas verdes !!. Esto ya lleva desde Marzo del año pasado, por lo menos.

¿Se habrán olvidado google de la etiqueta "nuevo" o caduca al año?

Jan 18

Ordenar y Filtrar JTable en Java

La versión 6 de java soporta, por fin, el ordenado y filtrado de tablas JTable. Existen clases que se pueden asociar al JTable, de forma que las filas de este podrán ordenarse pinchando en la cabecera de la columna, o bien podrán filtrarse para ocultar algunas de ellas pasando un filtro desde código.

Los trozos de código que pongo aquí son copia de los de la API.

Para que una tabla se pueda ordenar pinchando en la cabecera, el trozo de código es el siguiente

TableModel modelo = …;
JTable tabla = new JTable(modelo);
tabla.setRowSorter (new TableRowSorter(modelo));

Naturalmente, podemos hacer nuestro propio RowSorter para que las filas se ordenen como nosotros queramos.

Una vez ordenada la tabla de alguna forma, tenemos un problema con el número de fila. Si el número de fila es, por ejemplo, el 7, ese 7 ¿correspone a la fila 7 del modelo o a la fila 7 que se ve en la tabla?. Para solucionar esto, el JTable proporciona además métodos para convertir el número de fila del modelo a número de fila de la vista y vicevesa

int indiceModelo = tabla.convertRowIndexToModel (indiceTablaOrdenada);
int indiceTablaOrdenada = tabla.convertRowIndexToView (indiceModelo);

En cuanto a filtrado, podemos pasar al JTable un filtro, de forma que sólo se mostrarán aquellas filas que pasen el filtro. Disponemos, por supuesto, de varios filtros por defecto y podemos, por supuesto, hacernos nuestros propios filtros. El código para pasar un filtro que muestre todas aquellas filas que contengan "foo" en alguna de sus columnas puede ser este

TableRowSorter sorter = new TableRowSorter(modelo);
sorter.setRowFilter (RowFilter.regexFilter(".*foo.*"));
tabla.setRowSorter (sorter);

Me alegra que por fin hayan incluido esto. Por fin podremos tirar a la basura unas tablas que nos hicimos justo con estas dos posibilidades y que, por supuesto, se nos embarullaron más de lo debido según iba tocando y añadiendo cosas la gente.