Mostrando las entradas con la etiqueta Tecnología. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Tecnología. Mostrar todas las entradas

jueves, diciembre 14, 2017

El miedo a avanzar al mismo paso que las empresas que SI avanzan

Mirando una realidad que no me resulta ajena, y a punto de emprender un nuevo viaje laboral, me parece oportuno reciclar el artículo que escribí en Agosto de 2013:

No es que estar en el leading edge/bleeding edge sea siempre lo mejor, pero cuando constantemente hablas de innovación y tu estrategia es apostar sobre seguro con la fórmula de siempre, al menos a mi se me genera una contraposición de ideas importante.
En TI a veces es bueno ver regularmente que se está haciendo hoy en día para hacer que las ruedas giren más rápido. Es altamente probable que lo que aprendimos de nuestra escuela madre haya quedado obsoleto  al menos hace una década atrás, y actualizarse pase a ser un deber más que una necesidad.

Para avanzar hay que caminar hacia adelante (idealmente de frente)

martes, julio 01, 2014

AngularJS Case & accent insensitive filter

Siguiendo con AngularJS, requería de un filtro que me permitiera rescatar objetos desde un arreglo, pero con la particularidad de ignorar capitalización y caracteres especiales. Como no encontré nada terminé haciendo mi propio filtro, que comparto con los honorables lectores.

Básicamente la necesidad surgió ya que revisando un proyecto que está casi listo para su entrega final, nos percatamos que en uno de los infinitos procesos de re-creación de base de datos (que la bajaban y la volvían a crear), los datos de algunos conjuntos de combos de selección relacionados entre si (como puede ser país, región, estado, provincia, condado) no eran consistentes.

En este caso (sumamente particular), la relación (lo que podríamos decir "llave foránea") es un descriptor en texto, y el comité creativo por algún misterioso motivo puso en algunos combos datos en mayúsculas con acentos, en otros en minúsculas y todas las variaciones que se puedan imaginar.

El resultado de esto fue que el proceso de filtro que cargaba "el siguiente" combo relacionado, traía todos los datos, ignorando cualquier relación esperable.
Para evitar esto, y suponiendo posible inconsistencia en los datos, se debía construir un filtro personalizado que hiciera que cadenas de caracteres como "REPUBLICA     DE MÉXICO" y "República de México" fueran comparables, y que el resultado fuera true.

Para ello lo más sano era eliminar acentos y espacios, pasar todo a mayúsculas y comparar.

El código:


app.filter('cleancompare', function(){
    return function(items, filterObj){
        if (filterObj === false) {
          return items;
        }
        
        if ((filterObj || angular.isUndefined(filterObj)) && angular.isArray(items)) {
            var newItems = [];
            angular.forEach(items, function (item) {
                var matches = true;                             
                var kArr = Object.keys(filterObj);
                for(key in kArr){                    
                    var cleanItemAttr = removeDiacritics(item[kArr[key]]).replace(/[^\w]/gi, '').toUpperCase();
                    var cleanObjAttr  = removeDiacritics(filterObj[kArr[key]]).replace(/[^\w]/gi, '').toUpperCase();
                    matches = (cleanItemAttr != cleanObjAttr)?false:matches;  
                    // Descomentar la línea únicamente si es estrictamente necesario depurar,
                    // ya que el rendimiento se ve seriamente perjudicado para conjuntos muy 
                    // grandes de datos.
                    /*if(matches){ console.log('Comparacion realizada: ', cleanItemAttr, cleanObjAttr); }*/
                }
                if(matches){
                    newItems.push(item);
                }
            });
            
            items = newItems;
        }
        
        return items;
    }
});
 
La función removeDiacritics() la saqué de http://stackoverflow.com/questions/18123501/replacing-accented-characters-with-plain-ascii-ones
Disfruten ;) 

domingo, diciembre 15, 2013

¿Es el fin de las aplicaciones de escritorio?

Hace poco me encomendaron  el desarrollo de un sistema de software. Inicialmente pensé en usar Java, pero terminé con algo "más web".



Cuando nos enfrentamos al desarrollo de software, aparte del diseño acorde a la captura de requerimientos que se haya realizado, y las interfaces de usuario; entre muchas otras cosas; se debe escoger la tecnología adecuada.

La elección de que tecnología utilizar normalmente va ligada a la instalación, vale decir en las características de la máquina del cliente donde se instalará la aplicación. En la propuesta inicial pensé en realizar el desarrollo usando Java y una base de datos H2. Logré un avance para la generación medianamente rápida de la GUI, sin embargo me di cuenta que para conseguir interfaces de usuario sencillas, y por sobretodo intuitivas, Java me limitaba demasiado, aún considerando Swing, JavaFX y muchas otras librerías de terceros que entregan infinitas alternativas.



La alternativa:

Hacer un desarrollo "más web", vale decir desarrollar el FrontEnd en HTML y el backend en modo "servidor". Entre las elecciones "lógicas" estaba utilizar un servidor Apache Tomcat, un Jetty, o algo para contener JSP y Servlets, o usar Apache (o similar) con PHP.
El problema de esas opciones es que el computador huésped, la máquina del cliente y usuario final, de una u otra manera termina convirtiéndose en un servidor, eso sin considerar la cantidad de dependencias que se deben considerar:
  • JDK de Java
  • Servidor web
  • Motor de base de datos
  • Plugins varios
  • etc.

Pensé ¿.NET será una alternativa? y el problema es similar al de Java, necesitas previamente instalar muchas dependencias. Si el PC del cliente no tiene todo lo necesario, una aplicación que pesa un par de megas significa finalmente descargar sobre 40 MB de instaladores anexos. ¿Cómo evitamos eso?

De vuelta al enfoque inicial

¿Una WebApp local quizás? Con eso se soluciona el peso de la aplicación, aunque hay 2 problemas:
  1. El almacenamiento de datos usando WebDB está limitado a las restricciones del navegador que se utilice. Eso y los riesgos que el usuario utilice distintos navegadores, generando inconsistencias en la información, o que haga una limpieza agresiva del caché del navegador (lo que eliminaría la BD).
  2. La versión del navegador es un elemento que no se puede ignorar, y créanlo, aún hay usuarios de Internet Explorer 6...

Busqué alternativas disponibles, y ahorrándoles el proceso de análisis y selección de la a mi parecer mejor, finalmente llegué a node-webkit.
Aprovechando mi reciente incursión con Node.js decidí hacer algunas pruebas, que luego de resolver un par de problemas han resultado en una aplicación que cumple todas mis expectativas. Lo que utilicé:


Y una vez llegado a esto empiezo a cuestionar que tanto vale la pena desgastarse tratando de hacer una aplicación de escritorio, con miles de dependencias y limitaciones. Más considerando que hoy en día todo avanza hacia convertirse en Web:
  • La comunicación entre las personas se vuelve más y más Web, sólo piensen en las redes sociales.
  • La experiencia de juego cada vez se enlaza más a la Web.
  • Aplicaciones móviles desarrolladas de manera híbrida, vale decir HTML5+CSS3+JavaScript+API nativas. Phonegap lleva mucho avanzado en esta línea.
  • Las aplicaciones de Windows 8, que muchas veces están desarrolladas 100% usando tecnologías web.
  • Los temas de escritorio de GnomeShell utilizan CSS para muchas de sus definiciones.
  • Muchos widgets de escritorio de cada uno de los distintos sistemas operativos
  • El mismo Node.js que es JavaScript en el servidor.
  • Me arriesgaría a decir que más del 90% de los desarrollos de Google.

Incluso escalar este el modelo de aplicación de escritorio web no es tan difícil, pensando en un escenario en el que se decida masificar el uso de la aplicación en la organización.

Estoy claro que esta línea puede no ser la respuesta a todos los problemas que podemos enfrentar en desarrollo de software, pero al menos a mi me hace dar una segunda mirada cada vez que me hablan de desarrollar una aplicación de escritorio.

Si tienen dudas sobretodo respecto a como resolver la persistencia de datos con node-webkit, Sequelize y SQLite no duden en hacerlas.


lunes, mayo 21, 2012

Instalación de Phreeze: Framework MVC para PHP

Desde hace poco estoy desempolvando mis destrezas programando PHP. Estaba entre arreglar mi generador de código (algún día hablaré del mítico DbCommand y su generador de código) y crear unas plantillas Velocity para generar código  PHP o encontrar un Framework FRB (Fácil, Rápido y Bonito)  que me cree los CRUDs que necesito y me permita seguir usándolo sin demasiada dificultad (por eso lo fácil).

No puedo decir que evalué, sino más bien miré, varios Frameworks. CodeIgniter, Zend, CakePHP, y varios otros algo más desconocidos, todos son muy muy completos, pero son tan completos como complejos. Yo buscaba algo fácil. Y llegué a Phreeze.

Phreeze me convención en un video de 3 minutos. La aplicación genera un CRUD completo para bases de datos MySQL con sólo algunos clicks. Me dejé seducir por el video ya que Phreeze es bastante complejo y hay mucho de magia detrás.
A punta de prueba y error logré decifrar como instalarlo en un entorno "no preparado". Hay que decirlo la documentación es completa, pero hasta hace poco carecía de tutoriales, y no es precisamente un Framework para enfrentarse sin un buen ejemplo, o un buen tutorial (personalmente prefiero los 2dos).

Requerimientos previos:

  •  Apache
  •  MySQL, sino no tiene sentido haberlo bajado...
  •  PHP, sino no va a funcionar
  •  PEAR  para PHP
  •  Habilitar mod_rewrite en la configuración del Apache

En mi caso yo uso Ubuntu, así que la instalación la hice usando apt-get y Synaptic (ya se que el nuevo Software Center supuestamente es más simple, pero yo soy de la vieja escuela).

La habilitación de mod_rewrite tiene sus "ques":

  • Se debe editar el archivo de configuración de sitios de Apache reemplazando donde dice
    AllowOverride None
    por
    AllowOverride All
    para que  los directorios que deban ser afectados por este módulo.
    En Ubuntu el archivo se encuentra en:
    /etc/apache2/sites-enabled/000-default
  • Habilitar el módulo mod_rewrite copiando el archivo a la carpeta de módulos habilitados (comando en una sola línea):
    cp /etc/apache2/mods-available/rewrite.load/etc/apache2/mods-enabled/rewrite.load
  • Reiniciar Apache:
    service apache2 restart


Supongo que está de sobra decir que los comandos se ejecutan en modo root ( sudo su - , o derechamente con sudo) .


Instalación:

  • Bajar el archivo comprimido desde la página oficial y descomprimir en alguna carpeta que sea visible desde su servidor web, por ejemplo /var/www/phreeze (de hecho llamarla phreeze es lo recomendado).
  • Ajustar los permisos para la carpeta temporal de Phreeze, en 
    /var/www/phreeze/builder/temp
    ejecutando
    chmod -R 777 /var/www/phreeze/builder/temp
    Los permisos 777 suelen ser  "complicados", pero claramente no van a asignar todos los permisos en un servidor de producción.
    ¡HÁGANLO SOLAMENTE EN MÁQUINAS DE DESARROLLO NO EXPUESTAS!
    (Sí, les grité, pero fue sólo para asegurarme que entienden esto.)
  • Verificar que funcione visitando http://localhost/phreeze/builder
  • Generar sus CRUDs.

Instalación de los CRUDs:

  • Descompriman el archivo que les generó Phreeze en alguna carpeta. Procuren  respetar los parámetros de configuración que dieron en el builder.
  • Ajusten los permisos de la aplicación a 755
    chmod -R 755 *
  • Cambien los permisos de la carpeta template_c a 777
    chmod -R 777 templatec
    Esto es para permitir que las plantillas puedan ser compiladas a la carpeta local.
    OJO
    : Yo uso Smarty, Phreeze permite usar Smarty o Savant como motores de plantillas (templates), la carpeta template_c es de Smarty, si usan Savant es otra carpeta.

Los comandos los ejecutan en la carpeta donde descomprimieron su aplicación.

Creo que con eso tienen para entretenerse. Les recomiendo que vean los tutoriales en video de Phreeze, son muy ilustrativos de como se usa la aplicación.

jueves, noviembre 17, 2011

Gnome-Shell, LXDE, Compiz y los atajos de mouse

Mi computador normalmente está en modo experimental, y este períoo no ha sido la excepción. Estuve usando un Ubuntu Daily con Gnome-Shell un tiempo. Me dejé seducir por la promesa de funcionalidad sobre lo regular, y ¡FUNCIONÓ! Gnome-Shell merece ser instalado y utilizado, pero sin "ajustarlo". Como buen Giro-sin-tornillos instalé cuanto plugin encontré y Gnome-Shell se suicidó sin vuelta.
Solución radical, cambiarme a LXDE, un entorno liviano, sencillo, sin fuegos artificiales. Pero "necesitaba" ciertas cosas, como cambiar de escritorio con el toque de uno de los 7 botones de mi mouse, o el selector global de ventanas al poner el mouse en una esquina de la pantalla, son cosas que no transo. Así que instalé Compiz.

Para mi sorpresa, la configuración "habitual" que me resultaba más familiar, no funcionó. El cambio de escritorios utilizando el plugin  Desktop Wall tiene un error no resuelto. Los atajos de mouse no funcionan, y tampoco funcionan los atajos de teclado para Next y Prev (usados para desplazarse a los escritorios siguiente y anterior). Por eso olvídense de tener un muro de 2x2 (a lo Mac), a menos que sobrevivan con Ctrl+Alt+Izq/Der/Arriba/Abajo , lo que según yo es soportable pero a la larga intolerable.

Si bien recomiendan volver a una versión anterior de Compiz, el proceso es  más complicado que instalar un adicional y configurarlo.

La solución es instalar la herramienta xdotool para simular instrucciones de teclado (algo así como macros por decirlo de alguna manera):
sudo apt-get install xdotool

Y después configurar el plugin de Comandos, asignando como comandos:
  1. Command 0: xdotool key ctrl+alt+Left
  2. Command 1: xdotool key ctrl+alt+Right
Noten las mayúsculas, son importantes ya que o si no no reconoce el comando (si no me creen pruébenlo en un terminal).

Y luego configurar los correspondientes atajos de mouse para cada comando:
  1. Run command 0: Button8
  2. Run command 0: Button9
Y listo. FUNCIONA. Claro que  por sanidad mental en la configuración general indiqué tener un espacio de trabajo de 4 escritorios, dispuestos en una fila (matriz de 1x4). Además marqué la opción de Allow Wrap Around en la pestaña Viewport Switching del plugin Desktop Wall.

Basado en: http://askubuntu.com/questions/41058/how-can-i-enable-bindings-in-desktop-wall

A mi me gusta, y con esto seré feliz hasta que no me cautive XFCE.

Si van a jugar con LXDE, les recomiendo no instalar el Cairo Composite Manager (ni siquiera les pondré el enlace para que no se tienten), es insufríblemente lento.

miércoles, noviembre 16, 2011

Comandos *nix para archivos de texto

Hace poco me enfrenté al siguiente problema, una aplicación desarrollada para una importante empresa internacional de confites realiza una descarga de información desde una base de datos. Ya que el desarrollo fue ad-hok, los archivos de descarga inicial de datos quedaban con líneas en blanco cada ciertos intervalos. Esto se generaba ya que estos archivos son resultado de una concatenación de consultas parciales más pequeñas.
Ya que los colegas manifestaron una ineptitud imposibilidad informática (ni les explico mi cara, mi respuesta, y mi indignación al respecto) para eliminar las líneas en blanco, el problema debí resolverlo yo.

Esto es plataforma Ms Windows, utilizando las GNU Utils, que son herramientas de línea de comandos para *nix (Unix y Linux, en sus diversos sabores).
Cualquiera de estos enlaces les sirve:


Cuento corto, terminé haciendo una llamada a un .bat con el comando sed:
@echo Limpiando archivosed.exe "/^$/d" %1 > %1.delete@exit 1 

De aquí vamos a desprender algunos comandos relevantes:

  • sed.exe "/^$/d" archivo > archivo2sirve para eliminar las líneas en blanco del archivo. Los que tengan algún tipo de familiaridad con vi (el editor de textos para hombres en *nix), o con expresiones regulares, reconocerán el patrón:
    • ^$cadena que empieza y termina inmediatamente (^ empieza, $ termina), sin nada entremedio. Esto es una línea vacía (sólo por si no lo hubieran notado)
    • /ddelete, ie borrar, es decir borra la línea (¡BRILLANTE! no se cómo no me han llevado los rusos)
    • archivo > archivo2 : le indica al comando que opere sobre archivo y redirija los resultados a archivo2. Si archivo2 existiera previamente, este será sobreescrito.
  • wc -l archivo : Cuenta el total de líneas de un archivo de texto
  • grep -c "^$" archivo : cuenta las líneas vacías que hay dentro del archivo.
Y cualquier duda al respecto pueden revisar los manuales de cada comando (con man comando (nótese man de manual)), o la ayuda correspondiente con comando --help ó comando -h . Incluso hay veces que ejecutar el comando sin parámetros da un pincelazo de como se usa cada instrucción.


miércoles, abril 13, 2011

Compilando aplicaciones JME para Blackberry: Error de verificación

En caso que alguno de ustedes esté compilando aplicaciones JME para BlackBerry, existe una probabilidad que les aparezca un error del tipo:
"Error de verificación"

Si eso sucediera la solución es NO incluir la librería RIM de BlackBerry, y usarla ÚNICAMENTE para compilar. La razón es "obvia" la librería ya se encuentra en el teléfono.

Recorrimos medio Google y no encontramos esta referencia. Espero que a alguien le sirva.

jueves, julio 08, 2010

Teorizando respecto a los celulares

Mi zapatófono está agonizando. He sido fiel a Palm desde la primera Handspring que tuve, después una Treo 180 (ese si que es zapatófono) y ahora mi Treo 680.

Es sabido, como falla documentada, que desde la Treo 600 estos equipos tienen un problema no menor en el jack de entrada del manos libres, falla, se muere y muere el audio del equipo, pués "cree" que los audífonos están conectados. Hay soluciones por software que no siempre funcionan, accesorios que bypassean ella entrada del manos libres, golpes "estratégicamente dados" en la posición correcta del equipo, soplidos mágicos y reparaciones pseudo-definitivas que solucionarían el problema.
Mi equipo ya tienen una reparación a cuestas, no me salío precisamente barata, y muy fuera de la garantía, está fallando de nuevo por lo mismo.

Sin embargo a pesar de las miles de fallas que pueda tener el equipo, además del problema de audio, como que de repente se quede derechamente pegado, he aprendido a vivir con ello. Y si lo pensamos, sucede de la misma manera con las fallas y carencias de cualquier equipo.

Si la máquina no tienen cámara de fotos, "da lo mismo total nunca la he usado". Si el equipo viene sin opción de hacer copy paste, "da lo mismo, con suerte mando SMS". Si el teclado numérico es incómodo "da lo mismo, siempre llamo a mis contactos que tengo en la memoria del celular". Si el equipo pierde señal cuando lo tomas de determinada forma "da lo mismo, lo tomo de otra forma y listo". Si el equipo es frágil, "da lo mismo, le compro una buena carcaza".
Siempre buscamos justificar nuestras decisiones. Es como si el dicho "No me ayude, gracias; puedo equivocarme solo", fuera la respuesta a todo.

Entonces empiezo a pensar que debo renovar/cambiar mi celular. La pregunta del millón es por cuál.
Si me preguntan a mi, este es el listado de los que consideraría seriamente para comprar (sin orden de preferencia):

El problema es que no están en el mercado chileno, al menos no en el mercado normal. Y si es que están están a precios que bordean la usura de caros (y hay quienes están dispuestos a pagar sobre 300 mil pesos por ellos (casi 600 dolares)).

Entonces debo restringirme a lo que hay en el mercado chileno. Pero antes de enumerar mis opciones, qué busco yo en un celular (de paquete, sin aplicaciones): Lo mismo que ya tengo con mi Treo 680:
  • Tethering
  • Bluetooth (con A2DP)
  • MP3
  • Cámara
  • Geolocalización
  • Acceso a internet
  • Documentos
  • Agenda
  • Lista de tareas por hacer
  • Sincronización con el PC
  • Calculadora
  • Reloj
  • Teclado QWERTY (ideal), aunque ya me resigné a que quizás deba sacrificarlo.
  • Pantalla táctil

El software no me preocupa, ya que en teoría todo lo que necesito debiera existir, pero si me gustaría que hubiera un buen stock de aplicaciones, y Java (por si me dan ganas de hacer cosas).

Mis deseables:
  • 3G
  • Wifi
  • GPS
  • Sistema operativo Android (ideal)

Entonces en el mercado chileno mis opciones se reducen inmediatamente a 2:

Pero ambos son equipos "antiguos", sin ir más lejos el LG Eve no puede ser actualizado y se quedó estancado en Android 1.5, siendo que ya estamos en Android 2.1 (es como que sus PCs no pudieran usar nada sobre Windows 95). El HTC es casi de la vieja generación de HTCs, han salido demasiados modelos después de, aunque sigue siendo mi "mejor opción".

Entonces me puse a ver celulares, y a excepción de las BlackBerries (que no me gustan, y estaría haciendo caso omiso del sistema operativo), no hay nada excepto los modelos mencionados que me deje conforme. Entonces me dije a mi mishmo "Mishmo, ¿y si vemosh un aifoun?"

Y nuevamente haciendo caso omiso del sistema operativo, me voy dando triste cuenta que es lejos el celular "más avanzado" disponible en el mercado chileno. Salvo por un tema particular que me descompone que es la batería no cambiable, el "y pone" casi me convence. No tiene Java, pero tiene litros y litros de aplicaciones, te vacuna con lo que tio Jobs dice que es bueno, es más o menos actualizable, y lo peor es que hay un plan que en teoría me sale mensual practicamente lo mismo que lo que estoy pagando actualmente.

Entonces (nuevamente entonces) todo tiende a apuntar hacia que me compre un "y pone", pero mi mishmo interior me dice "¡Nooooo!, no te vayash al lado oshcuro".

Así que lo dejo a votación objetiva popular:
Aún considerando todo lo que a los usuarios de y Pones no les gusta, ¿vale la pena comprarse uno?

Por mientras seguiré usando mi fiel zapatófono.

jueves, marzo 25, 2010

Construcción masiva de consultas SQL desde una consulta SQL

Nota: Como ha sido habitual desde mis últimos artículos, y para que los que misteriosamente me leen sigan creyendo que trabajo en mis horas laborales comprendan lo difícil de las labores que desempeño, he aquí otro problema técnico y su correspondiente solución.
Nuevamente, si no le interesa el tema, simplemente pase a saludar, y será retribuido con mi eterno agradecimiento temporal.

Supuesto a priori: El lector tienen mediano entendimiento y nociones de SQL.

Problema: Se tiene cierta información distribuida en 2 tablas distintas dentro de una base de datos y se desea hacer un cruce de esta, actualizando los datos de la tabla 1 con ciertos datos de la tabla 2.
En el caso particular de la problemática enfrentada, se tiene la codificación estándar de enfermedades y se desea agregar una sup-clasificación que permita agruparlas según ciertos criterios, también estandarizados.

Solución: Lo más lógico sería hacer un update utilizando los datos de un select. El problema es que la consulta arroja más de un resultado.
Por ello se debe recurrir a la segunda opción, que es construir los updates necesarios a partir de los resultados del select que entrega la información que se va a actualizar.

Para ello:
  1. Rescatar la información desde las tablas correspondientes hacia un archivo, ejecutando:
    psql -h servidorbasedatos -U usuariobasedatos basedatos -c 'select tipodiagnostico.idtipodiagnostico, care_icd10_bg.diagnosis_code from care_icd10_bg, tipodiagnostico where substring(care_icd10_bg.diagnosis_code, 1, 3) between tipodiagnostico.rangoini and tipodiagnostico.rangofin' -t > archivo_resultados.txt
    Notar la sutilezas:
    • -c indica al comando psql que ejecute la consulta SQL escrita entre las comillas simples.
    • -t indica que el resultado de la ejecución sea presentado sin las cabeceras que indican los nombres de las columnas involucradas.
    • Dentro de la consulta la llamada a la función substring se asegura que los códigos de diagnóstico se encuentren dentro de los rangos expresados en la tabla tipodiagnostico. Al respecto, los códigos de diagnóstico se representan con 3 caracteres . Hay casos particulares en que este código va precedido por un punto y otro código numérico, o un signo de suma, o un asterisco. dado que los rangos están expresados sólo en 3 caracteres, es necesario usar la función substring.
  2. Construir los updates que sea necesario ejecutar. Para ello se debe ejecutar el toxi-comando:
    cat archivo_resultados.txt | awk -v q="'" -F'|' '{ gsub(/[[:space:]]*/,"",$1); gsub(/[[:space:]]*/,"",$2); print "update care_icd10_bg set type =", q $1 q, " where diagnosis_code=", q $2 q, "\;" }' > archivo_consultas.sql
    Las sutilezas de esta maravilla de la concatenación y del copiar-pegar:
    • -v q="'" le indica al comando awk que el caracter comilla simple (que tantos dolores de cabeza nos da cuando lo queremos usar dentro del awk), sea representado por una q. La otra solución es usar \x27 como caracter al escribirla, pero al menos a mi me resulta más clara la q.
    • -F'|' le indica al comando awk que el caracter pipe (|) es el separador de campos, para cada línea a procesar. Esto es debido a que la salida del comando psql entrega resultados como:
      207 | A01
      207 | A01.0
      207 | A01.1
    • Dentro de la secuencia de instrucciones awk, la función gsub(/[[:space:]]*/,"",$1); aplicada sobre $1 y $2 se encargará de eliminar los espacios sobrantes en $1 y $2 (207 y A01 en el ejemplo).
    El resultado de la ejecución de este comando es algo como:
    update care_icd10_bg set type = '207' where diagnosis_code= 'A01' ;
    update care_icd10_bg set type = '207' where diagnosis_code= 'A01.0' ;
    update care_icd10_bg set type = '207' where diagnosis_code= 'A01.1' ;
  3. Ejecutar la consultas recién creadas, ejecutando:
    psql -h servidorbasedatos -U usuariobasedatos basedatos -f archivo_consultas.sql
  4. Y esperar. Utilizando la base de datos de códigos de diagnósticos de http://www.care2x.com/ , se deben actualizar del orden de 13 mil registros lo que en una máquina medianamente actualizada (Athlon x64, 4GB de RAM) se demora alrededor de 2 minutos.

Y eso sería. Que les vaya bonito.

martes, marzo 23, 2010

No funciona el ssh -Y (X11 forwarding)

Nota al lector casual: Si su interés no es netamente técnico o si no entiende el título del artículo, se le recomienda pasar a saludar.

Problema: Le dieron acceso a un servidor vía SSH y necesita abrir un programa, digamos el navegador Firefox para configurar algo de manera local (a ese servidor). Por mucho que lo intente y que setee las variables de ambiente (emulando las de otras máquinas donde si funciona) sigue sin funcionar:
[root@localhost ~]# firefox
Error: no display specified
[root@localhost ~]# export DISPLAY=localhost:10.0
[root@localhost ~]# firefox
Error: cannot open display: localhost:10.0
[root@localhost ~]# firefox --no-remote
Error: cannot open display: localhost:10.0

Solución: Ejecutar la conexion ssh de la siguiente manera
ssh -XYv root@ip.servidor.ajeno
y analizar la salida
... muchas líneas ...
debug1: Requesting X11 forwarding with authentication spoofing.
debug1: Sending environment.
debug1: Sending env LANG = es_CL.ISO-8859-1
debug1: Remote: No xauth program; cannot forward with spoofing.

Interesante: Parece que falta algo.
Así que procedemos a conectarnos nuevamente y a instalar el paquete xauth.

Nos desconectamos y tratamos nuevamente.
Debiera funcionar.

lunes, marzo 22, 2010

Haciendo un respaldo total de las bases de datos PostgreSQL

Nota para el lector casual: Si su interés no es técnico o si el título de este artículo le resulta familiar al arameo antiguo entonces le recomiendo solamente pasar a saludar :-)

Problema: Es necesario realizar un respaldo total de todas las bases de datos que existen en una máquina. Estas bases de datos están sostenidas sobre PostgreSQL.

Solución:
  1. Acceder como root
  2. Habilitar el acceso en modo confianza (trust) para las conexiones locales. Para ello bastará editar el archivo pg_hba.conf , buscar la línea que se refiere a 127.0.0.1 y editarla para que quede como:
    host all all 127.0.0.1/32 trust
    Si no sabemos donde puede estar este archivo, lo podemos encontrar ejecutando:
    find / | grep pg_hba.conf
    lo que nos entregará la ruta completa hacia el archivo.
  3. Reiniciar el servicio de PostgreSQL. Normalmente esto resulta con alguno de estos comandos:
    service postgresql restart
    o bién
    /etc/init.d/postgresql restart
    Eventualmente, dependiendo de la distribución de Linux usada, y del PostgreSQL instalado, el nombre del servicio puede variar. Ante la duda vayan a /etc/init.d y ejecuten un:
    ls p*
    lo que listará todas las opciones de servicios que empiecen con p.
  4. Crear una ruta donde guardar los respaldos, por ejemplo una carpeta sql
    mkdir sql
  5. Cambiar a la carpeta recien creada
    cd sql
  6. Ejecutar el toxi-comando (en una sola línea):
    psql -lt -U postgres | awk '{ print $1 }' | xargs -i pg_dump -h localhost -U postgres -cO -Ft -f `date +%Y%m%d%H%M%S`_{}.tar -d {}
    Esto creará un archivo de extensión .tar con prefijo fecha_actual_ seguidi por el nombre de la base de datos.

Es recomendable que trás hacer el respaldo de la base de datos, restauren la línea del archivo pg_hba.conf que cambiaron a su estado anterior (posiblemente en vez de trust sea md5 o sameuser) y reinicien PostgreSQL (ver paso 3).

La restauración de estos archivos se hace con pg_restore, pero eso lo dejamos para otro día. Si su urgencia es mayor ejecuten el comando:
man pg_restore
o bién
pg_restore --help

Eso sería por el día de hoy. Que les vaya bonito.

martes, febrero 02, 2010

Formularios ZK: Comboboxes y temas de constraints

Hace algún tiempo que vengo desarrollando formularios usando ZK.
ZK es un RIA Framework, muy potente, muy completo, y a veces bastante complejo, sin embargo nada no abordable. Si el objetivo es tener prototipos funcionales cercanos a la versión definitiva, de manera medianamente rápida (a menos que se trate de formularios de más de 20 hojas impresas, llenos de miles de restricciones, y solicitados para plazos imposibles (para ayer)), ZK debiera ser uno de los primeros referentes.

La cosa es que me he enfrentado a 2 problemas recurrentes con una solución no demasiado natural.
Problema: Es necesario rescatar el valor de un campo de selección. El problema radica en que no se puede depender del valor que supuestamente se haya seleccionado en el ComboBox ya que muchas veces no se seleccionan los valores.
Solución: Lo que funciona para mi, y aplica para los casos que he trabajado, es asignar primeramente un valor por defecto al Combobox, un valor que se sepa que existe, Y lo segundo es asignar un evento donde al seleccionar un item del campo de selección, el valor del mismo cambia a la etiqueta.
Problema: Es necesario precargar un formulario con datos, pero al hacerlo se gatillan las restricciones que se han definido.
Solución: Hay 2 opciones, una es cargar los valores con setRawValue(), que permite setear null como valor, quedando el formulario en un estado previo a ser llenado. La otra opción, más directa, es aprovechar el databinding, asignar los valores a variables y cargarlas con value="${valor_variable}" . En este caso hay que tener el cuidado de asignar el valor antes de la definición de las restricciones.

Por algún misterioso motivo había postergado la publicación de este artículo. Seguramente había algo qeu precisar y que había olvidado. En fin.

viernes, enero 01, 2010

Nautilus con doble panel en Ubuntu Karmic

Se inicia el 2010 y junto con recibir los inevitables saludos de todos aquellos a quienes no interese este artículo les traigo otra nota técnica para los que si deseen saberlo.

Personalmente me agrada que el navegador de archivos tenga 2 paneles, de manera de poder explorar 2 o más carpetas de manera simultánea. En Windows esto se logra con el 2x Explorer, o con el xplorer2 de Zabkat, también con el Norton Commander y con el DOS Navigator. En Linux hay varias alternativas, pero la más representativa es el Midnight Commander (algo así como el Norton Commander).

Quienes usan Gnome extrañarán algunas funcionalidades, pero pueden instalar un nautilus con doble panel siguiendo los siguientes pasos:
  • Agregar el repositorio PPA:
    sudo add-apt-repository ppa:berndth/ppa
  • Actualizar los repositiorios:
    sudo apt-get update
  • Instalar nautilus y sus extras:
    sudo apt-get install nautilus libnautilus-extension1 nautilus-data
  • Reiniciar todas las instancias de nautilus:
    killall nautilus && nautilus &
  • Activar el doble panel:
    menú superior de nautilus -> ver-> extra pane ó en su defecto simplemente presionar la tecla F3
Desde: http://berndth.blogspot.com/search/label/Gnome

viernes, noviembre 06, 2009

Internet Explorer en Ubuntu Linux

No es misterio que hasta junio del 2008 IE 4 Linux era la solución para quienes requeríamos tener Internet Explorer sin tener que instalar Windows.
Wine hacía toda la magia.

El problema comenzó cuando la versión de Wine paso de las 0.9 a la 1.x, el instalador de IE4Linux dejó de funcionar y muchos empezaron a calificar al proyecto como basura. Otros, como yo, decidimos descontinuar el uso de Internet Explorer, pero siempre había alguien que lo usaba.

Hoy fue uno de esos días, y muchos de mis desarrollos sobre el CDF de Pentaho no se veían en Internet Explorer 7. Dado que no uso Internet Explorer, no lo supe hasta que un cliente manifestó la inquietud.
Por eso decidí volver a intentar con IE4Linux. Nuevamente sin éxito, tomando como referencia lo que sucedió al actualizar Wine, busqué como poder instalar la aplicación.

Todas las rutas están referenciadas desde la ruta donde se descomprimió el instalador.
  1. Primer problema: La versión de Wine no calzaba.
    Solución: Reemplazar el grep en el archivo lib/functions.sh de
    wine --version 2>&1 | grep -q "0.9."

    a
    wine --version 2>&1 | grep -q "-1."
  2. Segundo problema: No pudo descargar los Internet Explorer 5*
    Solución: Descargarlos a mano desde el archivo de navegadores de evolt.org a la ruta
    ~/.ie4linux/downloads

    y comentar las líneas que hacen referencia a la descarga en el archivo lib/install.sh , antecediéndolas con un #
    #[ "$INSTALLIE55" = "1" ] && downloadEvolt ie/win32/standalone/ie55sp2_9x.zip
    #[ "$INSTALLIE5" = "1" ] && downloadEvolt ie/win32/standalone/ie501sp2_9x.zip
    #[ "$INSTALLIE1" = "1" ] && downloadEvolt ie/win32/1.0/Msie10.exe
    #[ "$INSTALLIE15" = "1" ] && downloadEvolt ie/win32/1.5/IE15I386.EXE
    #[ "$INSTALLIE2" = "1" ] && downloadEvolt ie/win32/2.0/msie20.exe
    #[ "$INSTALLIE3" = "1" ] && downloadEvolt ie/win32/3.02/win95typical/msie302r.exe
  3. Tercer problema: El instalador arroja errores al intentar instalar los navegadores
    Solución: Usar el instalador en modo línea de comandos
    ies4linux --install-ie5 --no-gui
    ies4linux --install-ie55 --no-gui

Y luego probar. Y lo bueno es que funciona.

Y para Internet Explorer 7, Play On Linux tiene la solución.

Ojala esta barbaridad le sirva a alguien aparte de a mi.
Suerte

lunes, octubre 05, 2009

Java y la pesadilla del encoding: Invalid byte 2 of 2-byte UTF-8 sequence

Advertencia: Nota sin relevancia para el lector casual. Acepto saludos, completos y cervezas.

Haciendo unas validaciones de Schema contra ciertos XML que estoy recibiendo me enfrenté a un error recurrente:
Invalid byte 2 of 2-byte UTF-8 sequence

Lo peor de todo es que a simple vista no había nada extraño o fuera de lugar en el XML. Después de realizar algunas pruebas y de buscar en Google, di con la respuesta. Lo que sucede es que se gatilla este error cuando la codificación del archivo no concuerda con lo especificado en la cabecera del XML, ie: si mi cabecera dice
< ?xml version="1.0" encoding="UTF-8"? >
se esperará que el archivo efectivamente este almacenado como UTF-8.

Dado eso sospeché que el archivo estaba en otra codificación, como por ejemplo WINDOWS-1252, o ISO-8859-1, cambié la definición a ISO, y funcionó sin problemas. El truco para asegurarse de ser consistente con los encodings es:
  • O pasar el parámetro -Dfile.encoding=UTF-8 (en mi caso era UTF-8) como parámetro del comando java
  • O rescatar los Strings especificando la codificación de caracteres, y guardando los archivos como ByteStreams especificando el encoding.
No en vano dicen que el encoding es uno de los monstruos y pesadillas de los desarrolladores de software.

Referencia: http://www.biglist.com/lists/xsl-list/archives/200702/msg00044.html

viernes, julio 31, 2009

UnknownHostException instalando Glassfish

Nota: Información sin relevancia para el lector casual

Problema: Al intentar instalar el servidor de aplicaciones Glassfish, se presenta el siguiente error:

Glassfish cannot resolve the hostname and throws this exception:
SEVERE: property_reader.unknownHost
java.net.UnknownHostException: ...


Esto es debido a que el instalador es incapaz de reconocer el nombre de la máquina como un host válido.

Solución: Editar el archivo /etc/hosts de manera que la línea donde aparece referenciado 127.0.0.1 y localhost quede más o menos así:

127.0.0.1 localhost nombre_del_servidor


donde nombre_del_servidor es el nombre del servidor, tal como se presenta en el error mencionado.

Referencias:

miércoles, junio 10, 2009

Porqué estoy empezando a odiar a Netbeans

Netbeans es una IDE para trabajar con Java.
No niego las innumerables ventajas que tiene; incluso sobre Eclipse, la IDE de mi preferencia; al momento de hacer GUIs, WebServices, e incluso clientes para los WebServices. Sin embargo da la sensación que los desarrolladores no se preocuparon del usuario final.

Si yo defino un CLASSPATH, lo mínimo que espero es que la IDE reconozca las librerías incluidas, y no que me empiece a marcar errores inexistentes. Me pasó con log4j, que está en varios de mis desarrollos, no hay caso para que me reconozca la librería.
Esto fue hasta que hice algo, que obviamente no recuerdo (sino no estaría manifestando mi desagrado), para que funcionara.

No es buena una aplicación que para que responda a un comportamiento objetivamente natural haya que realizar ajustes poco naturales.
En todo caso es solamente mi humilde opinión.

sábado, mayo 30, 2009

Puro Eye Candy


Así se ve mi computador ahora. No he visto efectos similares en Windows... ;-D

martes, mayo 26, 2009

Software indispensable (que yo necesito)

Hace pocas semanas tuve que instalar todo de nuevo en mi PC de escritorio de la casa. Estaba probando el RC de Windows 7 y dado que mi equipo no es de última tecnologia, y por ende mucho menos los accesorios de hardware que lo acompañan, y dado que MS no me va a financiar un equipo nuevo solamente para proveerme de una "Mejor experiencia de usuario", Windows 7 se fue de desinstalada.

Los problemas de hardware que me estaba dando Windows 7 son absolutamente comparables con los que ya me da Linux, con la diferencia que los de Linux me interesa saber como solucionarlos, y me motiva hacerlo.

Entonces comencé por instalar Windows XP (gracias san Dell por licencia concedida). Como mi actual experiencia de usuario requiere múltiples escritorios y ciertas añadiduras a los controles de las ventanas de aplicación, recordé algunos programas gratuitos que cubren estas necesidades:
  1. Deskloops: Ahora descontinuado y con bastantes alternativas muy similares, transforma el Escritorio en un tubo. El grado de utilidad es relativo, pero al menos es entretenido.
  2. The Wonderful Icon (TWI): Uno de los mejores descubrimientos que he hecho. El programa agrega una banderita roja al área de notificaciones, y con ella es posible configurar varias macros muy útiles, así como agregar funcionalidades como Siempre arriba a las ventanas.
  3. Power Menu: Este apareció receintemente en mi lista dado que me malacostumbré a tener ventanas transparentes (mínimo para aprovechar la tarjeta de video). Aparte de eso agrega ciertas cosillas anáñogas al TWI.
En Linux, el asunto ha sido casi 100% Eye Candy. ha sido tanto lo que me han alegado que Linux es feo que he buscado como hacerlo más atractivo. Y una cosa que necesito (motivacionalmente) es una manera de tener distintos fondos de pantalla en cada uno de mis escritorios (mi área de trabajo se separa en 4 secciones, y las uso a concho). Para ello Wallpapoz ha sido la solución.

Y Compiz junto a mi mouse de 5 botones son la combinación perfecta para poder desplazarse sin problemas en este caos.
Probé las alternativas a usar Compiz, puesto que tanto Eye Candy termina consumiendo más recursos de lo recomendado, pero mi la combinación de xbindkeys + xmacro, ni btnx tienen una respuesta decente a las instrucciones con el ratón.

jueves, mayo 21, 2009

OpenSource - Windows vs Linux ¿A qué le tienen miedo?

Las pasadas semanas han estado relativamente llenas de ciertas noticias que de una u otramanera guardan relación al OpenSource:
son algunas de las que me han llamado la atención, pero no solamente por la noticia en si, sino también por los comentarios que genera.

Ahí es donde saltan los fanáticos religiosos de esta o esta otra plataforma y sistemas operativos, normalmente:
Windows vs Linux

Yo me pregunto ¿a qué le tienen miedo? No es una competencia, ni se destrona a nadie, en la práctica no hay ganadores. Puede que haya quienes ahorran más, pero ambas caras responden a cosas distintas. Nadie va a dudar de la masculinidad del otro por que use Linux o Windows.
Al final el que tan bueno o que tan malo sea uno en comparación al otro dependerá estrictamente de las necesidades de cada uno, o del contexto que estemos abordando.

Mi propia experiencia es un proceso de evangelización fallido, donde a pesar de haber demostrado que puedo hacer que Linux se vea EXACTAMENTE IGUAL a MS Windows, el problema no es que funcione mal, sino que simplemente NO ES Windows.

Hay cosas que indudablemente no cambio de Linux, por decir la más importante, el precio, no tengo que pagar ninguna licencia (o temer que me persigan por no pagarlas). Tampoco existe el riesgo de virus de computador que me puedan dejar la escoba (en rigor siempre los hay, pero en Linux es algo más que controlado).
De Windows siempre preferiré el concepto de Plug & Play, practicamente no existen los problemas de hardware.

Si las necesidades de una empresa requieren utilizar Windows o cualquier otro paquete de software cerrado propietario, lo va a usar y estarán dispuestas a cargar con los costos que eso tenga asociado (arriesgarse a tener que pagar una multa por usar software de dudosa procedencia también es un costo). Sin embargo en mi opinión, para el caso de los usuarios finales, pagar por una licencia de Windows original (y hablemos de una edición decente y no de la Starter...) es caro, de hecho si lo piensan friamente casi siempre termina duplicando el costo de la máquina.

Yo elegí abanderarme con Linux y el OpenSource, en el peor de los casos un Windows OEM que venía con mi computador y solamente freeware. Lo mejor de todo es que funciona, y mi conciencia está medianamente tranquila.

Nota: Los Mac son para nenas, así que ni siquiera entran en la discusión :-D
(Respuesta del Apple fanboy en 10, 9, 8, 7...)