Tip: Arrancando RabbitMQ en Mac OS

He empezado a trastear con RabbitMQ, que hacía mucho que lo tenía entre ceja y ceja. La instalación en un servidor con ubuntu fue trivial, en unos minutos estaba instalado y en marcha, pero no fue así en mi Mac.

Tras instalarlo con homebrew no conseguía arrancarlo, me daba el siguiente error:

ERROR: epmd error for host "vodkalimon": address (unable to establish tcp connection)

Al parecer se intentaba conectar con mi máquina por su nombre (efectivamente se llama vodkalimon ;)), no por localhost o la ip de loopback.

La solución es muy simple, aunque a mi me costó un buen rato darme cuenta, que uno es un poco torpe para los sistemas.

Simplemente añadir en /private/etc/hosts el nombre de la máquina apuntando a la ip de loopback. Lo que a mi me ha quedado como algo así:


...
127.0.0.1 localhost
127.0.0.1 vodkalimon
255.255.255.255 broadcasthost
...

Y con esto, ya podemos arrancar normalmente RabbitMQ.

Instalar gemas en Dreamhost

Estoy haciendo unas pequeñas pruebas con Sinatra para un pequeño proyecto personal. El caso es que al ir a instalar la gema de sinatra(y un par más que estoy usando) en dreamhost, me surgió el error de no tener permisos de escritura.

$ gem install sinatra
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions into the /usr/lib/ruby/gems/1.8 directory.

La solución es simplemente añadir unos exports al .bash_profile


export GEM_HOME="$HOME/.gems"
export GEM_PATH="$GEM_HOME:/usr/lib/ruby/gems/1.8"
export PATH="$HOME/.gems/bin:$PATH"

Y tras ejecutar source .bash_profile para que coja los cambios, ya podemos instalar nuevas gemas.

DNDzgz Lite, porque yo también lo necesito

Como supongo que sabréis la mayoría de los que seguís este humilde(y muchas veces olvidado :P) blog, hace unos meses participando en el AbreDatos formé parte del equipo de DNDzgz una aplicación web para móviles de última generación, en principio para cualquier terminal cuyo navegador web soporte geolocalización.

Algo de tiempo después gimenete, junto a Sergio, lanzaron la versión nativa para iPhone de DNDzgz. Adelanto aque hora están trabajando en una nueva versión, y por lo que he visto hasta ahora… a mi me dan ganas de comprarme un iPhone para aprovecharla! :D

Hace poco más de una semana, se anunció la aplicación ViveZaragoza para Android. Una aplicación desarrollada por la gente de warp para el Ayuntamiento de Zaragoza, con las funcionalidades de consulta de Bus y Bizi, además de poder consultar el programa de actos de las fiestas del pilar(recién acabadas) con sus respectivas localizaciones.

Y como algunos ya saben, soy poseedor de un “flamante” Nokia 5130 XpressMusic(también conocido como un “nokia guarro” ;)), y desde primeros de Octubre me he vuelto a mudar ooootra vez a Zaragoza(veremos por cuanto tiempo :P).

La cuestión es que, esta semana pasada llevaba esperando a un autobús durante bastante rato, lo suficiente como para proponerme que iba a ser la última semana que no sabía cuanto me tocaba esperar. Lo bueno ha sido que este fin de semana no he recibido visitas “pilaristas” y he podido dedicar un par de ratos a tirar un poco de código, lo que me ha permitido lanzar DNDzgz Lite. Ahora con el Opera Mini de mi “nokia guarro”, ya puedo saber cuánto tarda el autobús usando el número de poste y cuantas bicicletas hay en una parada de bizi consultando por su número.

Tengo la sensación de que lo vamos a utilizar muy poquitos, pero al menos a mi me es útil y por fin voy a aprovechar parte de mi trabajo en el AbreDatos :P

PD: Por si hay algún despistado, para acceder a la versión lite directamente http://www.dndzgz.com/lite(que con terminales “viejos” no creo que tengamos tarifas planas y hay que ahorrar ancho de banda :P)

grails.sh, trabaja fácilmente con distintas versiones de Grails

Leyendo la lista de correo de grails, me encuentro un pequeño script, que al menos a mi me parece muy útil para los que a veces andamos cambiando entre varias versiones de grails: grails.sh.

  • En el directorio de un proyecto ejecuta la versión del mismo proyecto.
  • Desde otros directorios se ejecutará la versión de grails que tengamos por defecto en GRAILS_HOME.
  • Y para utilizar una versión concreta, simplemente se lo debemos pasar como parámetro.

Sencillo y cumple su función. Al parecer funciona perfectamente en Mac, Linux y Windows con cygwin. Y para los despistados como yo, recordad darle permisos de ejecución al script :P

SQL con Javascript: Web SQL Database

Como supongo que muchos ya sabréis, una especificación de HTML5 es Web SQL Database para persirtir datos en una base de datos relacional embebidos en el navegador web(la otra alternativa es Web Storage, para persistir datos como clave valor). Esto puede tener muchas aplicaciones, en mi caso lo he utilizado para implementar el sistema de favoritos de DNDzgz.

Cuando pretendamos sacar partido de las nuevas características de HTML5 debemos tener en cuenta que cada navegador puede soportar sólo algunas especificaciones, no es un todo o nada, por lo que lo primero que deberemos hacer es comprobar que soporta la especificación que queremos usar, por ejemplo:

function supports_local_database() {
return !!window.openDatabase;
}

Si existe openDatabase, crearemos la conexión a la base de datos:


db = openDatabase('dndzgz', '1.0', 'DNDzgz', 65536);

Una vez abierta la conexión, podremos ejecutar cualquier tipo de query SQL(compatible con SQLite), dentro de una transacción. Por ejemplo crear una tabla:

db.transaction(
function(transaction) {
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS favorites ' +
' (id INTEGER NOT NULL, ' +
' service VARCHAR(255) NOT NULL, ' +
' date DATE NOT NULL,' +
' name VARCHAR(255) NOT NULL, ' +
' latitude REAL NOT NULL, ' +
' longitude REAL NOT NULL, ' +
' PRIMARY KEY (id,service));'
);
}
);

Insertar datos:

db.transaction(
function(transaction) {
transaction.executeSql(
'INSERT INTO favorites (id, service, date, name, latitude, longitude) VALUES (?, ?, ?, ?, ?, ?);',
[id, service, new Date(), name, latitude, longitude],
callBack,
errorCallBack
);
}
);

Eliminar datos:

db.transaction(
function(transaction) {
transaction.executeSql('DELETE FROM favorites WHERE id=? AND service=?;',
[id,service], null, errorCallBack);
}
);

Y por supuesto mostrarlos:

db.readTransaction(
function(transaction) {
transaction.executeSql(
'Select * from favorites;', [],
function(transaction, result){
for (var i=0; i < result.rows.length; i++) {
var row = result.rows.item(i);
alert(row.name);
alert(row.service);
}
},
errorCallBack
);
}
);

Como podéis ver, a executeSql se le pasa primero la query, seguidamente un array con los valores de los argumentos de la query, y finalmente una función de callback y otra de callback para el caso de que existan errores. Y existen dos tipos de transacciones: transaction y readTransaction, la primera es de lectura-escritura, mientras que la segunda es de sólo lectura.

En fin, supongo que a otros también os pasará lo mismo, resulta bastante raro estar tirando queries SQL desde javascript. Pero puede resultar útil para muchos casos, empezando por descargar de responsabilidades y carga al lado servidor.

Las entrañas de DNDzgz

Lo prometido es deuda, tenía pendiente escribir un poco acerca de la parte técnica del fin de semana del desafío AbreDatos y de DNDzgz. A grosso modo las tecnologías utilizadas fueron Google App Engine(GAE) y Python del lado servidor; del lado cliente fueron Javascript con jQuery, la versión 3 del API de Google Maps, algunas de las novedades de HTML5, unas gotas de CSS3 y jQTouch para ayudarnos para que tuviera pinta de aplicación nativa iPhone. Usamos Git como repositorio de código, el repositorio está concretamente en github; para los documentos, diseños, fotos, etc. utilizamos dropbox(antes del fin de semana yo no tenía ni cuenta :P).

Logo DNDzgz

La elección de GAE fue casi instantánea cuando empezamos a hablar con gimenete acerca de presentarnos al AbreDatos, las razones: hosting gratis y capacidad de escalar mucho sin tener que gastarnos ni un euro, despreocuparnos de la parte de sistemas, ningún problema con las limitaciones por correr sobre la plataforma de Google.

Que usáramos Python, aún siendo más javeros que otra cosa, fue por que ninguno de los 2 teníamos experiencia con GAE en Java(okok, yo había hecho un pequeño experimento, pero muy poca cosa para llegar a ninguna conclusión). Por eso preferimos aprovechar su experiencia desarrollando la primera versión de debug_mode=ON con Python+GAE; mientras que varias semanas antes yo me ojeé un par de manuales de inicio rápido, retomé el ebook Python para todos que tenía a medio leer(hace muuuucho :P) y un par de días antes, me hice en poco rato el proyecto de ejemplo de GAE. Para extraer los datos utilizamos tanto Beautiful Soup como expresiones regulares para hacer scraping de HTML o Javascript de Tuzsa y Bizi, y simplejson para cargar los datos JSON de datos.zaragoza.es.

Que utilizáramos jQuery como framework Javascript, fue una elección posterior a jQTouch(que está basado en jQuery) pero de todas formas, seguramente lo hubiéramos elegido. Google Maps es la elección “por defecto” para todo el que quiere hacer algo con mapas :P. Gimenete es quien estuvo peleando con esto, teníamos problemas con la fluidez en la navegación de los mapas, que al final consiguió mejorar… Eso sí, fuera del navegador Safari del iPhone no conseguimos que los mapas funcionaran correctamente, ni en terminales con distintas versiones de Android y ni si quiera en el Safari de Mac(tenemos que ver que pasa exactamente, tras algunas pruebas, el sospechoso principal es jQTouch).

Gracias a que iPhone(y las últimas versiones de Android) soportan parte de HTML5, se ponían a nuestra disposición algunas de esas novedades que molan tanto (Flash, tiemblaaa!! ;)):

  • La posibilidad de geolocalizar al usuario por medio del GPS del terminal (no es exactamente HTML5, pero parece que la mayoría lo ponemos en el mismo saco) muy fácilmente utilizando navigator.geolocation.
  • Para implementar los favoritos/acceso rápido estuvimos usando Web SQL Database, lo que supone guardar los datos en una base de datos embebida al navegador web(actualmente parece que en todos es SQLite, o al menos parece ser la implementación de referencia), que finalmente se quedó fuera por falta de 3/4 horas :S.

En fin, que debemos molar, porque nuestro proyecto es una pequeña colección de buzzwords: Cloud Computing vía Google App Engine, HTML5, iPhone… XD

Nuestra aportación en el Desafío AbreDatos 2010: DNDzgz.com

Este fin de semana se celebró el Desafío AbreDatos 2010, desde las 00:00 de la noche del Viernes al Sábado hasta las 00:00 del Domingo al Lunes, 48 horitas trabajando para desarrollar servicios que utilizaran datos de fuentes públicas. El desafío lo convocaba la asociación Pro Bono Publico para tratar de concienciar de la necesidad de que se abran los datos generados con dinero público(o sea, el nuestro); y por lo que dicen, nos habíamos presentado 47 equipos de los que hemos conseguido algo funcional unos 30. Y como publiqué en el anterior post, estuve participando.

El equipo del que formaba parte era closin, donde he programado con Alberto Gimeno, la encargada de diseño es Mamen Pradel y el responsable de marketing y comunicación es Lucas Aisa. Aún con la desventaja de que sólo habíamos trabajado anteriormente juntos Mamen y yo, creo que hemos sido un equipo muy compensado y junto al buen rollo durante todo el fin de semana, se ha notado en el resultado final con DNDzgz(o Dónde en Zaragoza ;)).

DNDzgz TEAM

La idea de DNDzgz, era principalmente crear una aplicación web móvil que mostrara servicios ciudadanos de Zaragoza geolocalizados y su información útil asociada, que además tuviera aspecto de aplicación nativa de iPhone(sin cerrarnos a que funcionara en otros terminales/navegadores, claro).

Nuestra idea inicial fue extraer los datos sólo de las fuentes que aparecen en datos.zaragoza.es, pero la información de servicios como el autobús urbano o el bizi no eran suficientes para nuestro objetivo:

  • En el caso del autobús, nos servía para posicionar las paradas y nos daba una url de la web de tuzsa, en donde aparecía una estimación para saber cuando tardarán en llegar los autobuses de ese poste, por lo que tenemos que hace scraping de ese HTML para poder consumir esos datos.
  • Sobre el bizi, sólo posicionaba las paradas sin ninguna información añadida… pero vimos que en la web de bizi se podía hacer scraping para obtener el número de bicicletas y aparcamientos libres en una estación bizi además de su posición, lo que es realmente útil.
  • La que sacamos íntegramente de la web de datos abiertos del ayuntamiento de Zaragoza, fue la de puntos wifi municipales(porque no necesitábamos más que la posición)

Tarde/noche del sábado #abredatos #t10 #dndzgz

Hay muchas cosas que seguramente se echarán de menos en la aplicación, a bote pronto: favoritos/acceso rápido para ver si hay bizis en mis estaciones habituales, conocer la parada del 30 más cercana a mi posición, la estación de bizi con aparcamientos libres más cercana a mi posición… además de añadir otros servicios ciudadanos.

Se puede pensar que muchas de estas funcionalidades no han sido posibles de añadirse a causa de la limitación de las 48 horas, pero la principal razón de no poder añadir más funcionalidades, fue el tener que perder tiempo haciendo scraping para hacernos con todos los datos que necesitábamos. Y hay que ser consciente que eso habrá pasado en casi todos(por no decir todos) de los 47 equipos que nos presentamos al desafío… con el nivel que se ve en los resultados, ¿que se hubiera conseguido con datos abiertos?

Y nada, sólo quería felicitar a la gente de Pro Bono Publico tras la organización del evento a los equipos por sus resultados, y por supuesto agradecer a todos los que se han presentado su esfuerzo por tratar de crear servicios que nos resulten de utilidad a los ciudadanos.

Ahora la segunda parte, para que haya valido la pena la paliza de este fin de semana, a intentar hacer llegar estos servicios a los ciudadanos! :)

Comida del domingo #abredatos #t10 #dndzgz

PD: Como ha quedado un tocho bastante largo, intentaré escribir durante la semana otro post sobre detalles más técnicos de las tripas de DNDzgz
PD 2: En mi flickr están disponibles las fotos que nos hizo Toño y hay por ahí algún video de @maitrella XD

MacPorts ahorrándome trabajo

Finalmente la historia con el Macbook que compré en navidades, ha acabado con que me lo han sustituído por uno nuevo, entonces todavía lo estoy poniendo a punto para poder trabajar con el y dejar ya de retén a mi viejo Toshiba Satellite, por si las moscas aún tardaré en darle la jubilación…

MacPorts facilita la instalación(compilación, instalación y actualización) de software open source para Mac OS, ya lo tenía oído/leído y la verdad es que me está ayudando bastante a instalar mis herramientas de trabajo.

Por ejemplo para instalar Grails:

  • Ejecutar: sudo port install grails
  • Y ya sólo nos queda añadir la variable de entorno GRAILS_HOME en nuestro
    .profile:
    export GRAILS_HOME="/opt/local/share/java/grails"
    export PATH="$PATH:$GRAILS_HOME/bin"
  • Para comprobar que no han habido problemas, simplemente ejecutamos el comando grails help para comprobar que todo ha ido correcto.

Otro ejemplo podría ser git:

  • Ejecutamos sudo port install git-core
  • Y luego ejecutando git comprobamos que, efectivamente, lo tenemos instalado

Pues eso, que es una gozada que haya herramientas que te faciliten la vida, sobre todo cuando eres novato :)

Apple también la caga

Desde el día 26 de diciembre soy propietario de un flamante Mac Book, que lleva desde el día 12 de enero en el servicio técnico… lo compré por lo bien que me habían ido hablando, y empujado por un poco de presión popular ;).

Tengo que decir que los primeros días estaba encantado con la compra, me gustaron esas pequeñas diferencias que se encuentran respecto a un PC. Pero luego empezó la “pesadilla”, tal y como movía mínimamente el mac se ponía en reposo y no volvía en sí hasta unos minutos más tarde o si reiniciaba, pero luego fué a peor y ni reiniciando conseguía que volviera en sí.

Aquí viene la muestra:

Entonces acabé llamando a Apple Care, que tras probar varias cosas vía teléfono, me dijeron que lo llevara al servicio técnico(K-tuin Zaragoza) y eso hice. A los dos días me llamaron para decirme que para resolver el problema iban a pedir una pieza para sustituirla… pero no resultó ser la solución… y todavía siguen buscando :S. Por esto el viernes(11 días después) volví a llamar a Apple Care para explicarles la situación y ver si se podía sustituir o devolver, con quien hablé me dijo que llamara el lunes para hablar con atención al cliente(a las 18:00 ya está cerrado). El lunes(14 días después y tras 30 minutos al teléfono), por fin encontré a alguien(la segunda persona con la que he hablé) que me explicó que es un defecto grave de fabricación y me remitió al servicio post-venta de Apple Store(resulta que no es lo mismo).

Ayer, ya sin ganas de seguir perdiendo el tiempo contando una y otra vez lo mismo, y empezando a perder las buenas formas(otros 30 minutos de teléfono). La primera persona con la que hablé, al ver mi mosqueo(tras decirme que llamara a Apple Care…), me pasó con otra compañera que finalmente me dijo que no me podía ayudar con la sustitución(con lo que aumenté a cabreo) y al final le pedí(lo más educadamente que pude) que me pasara “con alguien que me pueda ayudar, que es lo que estoy pidiendo…”. Al final me pasaron con una tercera persona con la que me termino de desahogar, que finalmente me dijo que no podía prometer una sustitución, pero que iba a contactar con K-tuin para conocer el caso y que me llamaría en un par de días para contarme.

Resumiendo, me va a llegar una factura de teléfono interesante, en atención al cliente Apple (Care y Store) hay gente que no sabe por dónde le sopla el aire, y sobre K-tuin… puedo aceptar hasta cierto punto que no sepan cuál es el problema, pero tras decirme en dos ocasiones que me llamarían y no hacerlo(al final lo tenía que hacer yo) para mi es falta de seriedad y profesionalidad, deberían ser más atentos con sus clientes y como mínimo mantenerte informado de la situación, a mi se me han ido las ganas de comprar nada allí(cosa que iba a hacer)… Y ya veremos si vuelvo a comprar más productos de apple, para esto habrá que olvidar primero una de las peores experiencias de usuario que he tenido y, como no parece que seamos demasiados los que hemos tenido este tipo de problemas(haberlos haylos), no tengo esperanza de que la atención al cliente de apple cambie.

Veremos como termina la odisea.

Videos navideños… o cosas de resaca

Soy consciente de que no soy demasiado creativo/original para estas cosas de las felicitaciones navideñas, me gusta unvlog y los videos que se comparten allí, y este fin de semana tuve un par de días resacoso-prenavideños. Combinando estas tres variables, acabé montando una web con rails para compartir videos navideños (no se me ha ocurrido ningún dominio que merezca comprarse :P) que me pareciera interesante a mi o a cualquiera que pase por ahí o lo comente.

Al ser una web de temporada, he preferido evitar registros, simplemente usar el plugin recaptcha para tener un mínimo de control al publicar videos o comentarios, el plugin para los videos ha sido acts_as_videoclub por lo que esta web soporta los mismos servicios de video que el plugin :P, acts_as_commentable es el plugin para los comentarios, para la paginación will_paginate, seo_urls para hacerlo un poco más amigable a los buscadores y por último acts_as_taggable_on_steroids para etiquetar los videos; el diseño es de una plantilla con licencia copyleft con pequeñas modificaciones.

Como es de suponer no me supuso mucho tiempo de trabajo, alrededor de 6-7 horas y en días en los que se está lejos del 100% ;), además es una web muy mejorable y no está lo terminada que debería, pero el tiempo es limitado y no quería/podía dedicarle más.

En fin, que si os llegan felicitaciones en forma de video de Google Video, Dailymotion, YouTube o Vimeo; y os llama la atención os animo a compartirlo. Por cierto, feliz navidad :)