De vuelta del Greach 2013

Este viernes 25 y sábado 26 de Enero se ha celebrado en Madrid el segundo Greach, el evento en España centrado exclusivamente en Groovy y su ecosistema, donde nos hemos juntado buena parte de la comunidad gracias al trabajo de Alberto Vilches en su organización.

Asistentes al Greach 2013, foto de @jerolba

Tuve la oportunidad de volver a participar como ponente en esta edición al aceptarme la propuesta de charla que llamé Testing en proyectos Grails del día a día, que como nombre era menos feo que Testing como lo hago yo. En la que pretendía centrarme, más que en las herramientas de testing en sí y en sus posibilidades (acerca de lo que ya se iba a hablar en otras charlas), en como practico yo el testing en mis proyectos y como les saco partido a esas herramientas.

No me veo capaz de hacer un resumen exaustivo de las charlas a las que asistí, además fueron grabadas y las podréis ver en cuanto las publiquen (pronto), pero estas fueron a las que asistí:

Al acabar las sesiones del primer día Escuela de Groovy – Salenda invitaban a cervezas en un bar cercano, y uno es educado y no rechaza una invitación así ;) . Después un poco de tapeo con buena gente de la Zona Norte no muy lejos de Preciados y no muy tarde de vuelta al hotel a descansar.

En el segundo día:

@jorgeuriarte en Greach 2013

Sobre el contenido de las charlas: Aunque en ocasiones algunas me sobrepasaban por la mezcla de mi dificultad para seguir algunas charlas en inglés y el tratamiento de temas en los que no he profundizado, en otras por el contrario me quedé con las ganas de que se profundizara algo más y en unas pocas eché en falta algo más de sentido práctico; salí bastante satisfecho de casi todas a las que asistí. También me quedé con las ganas de haber asistido a otras charlas que pintaban muy bien, tocará verlas en video.

Sobre mi charla: Soy totalmente consciente de que no ha sido ni mucho menos una de las mejores charlas que haya hecho últimamente, tenía claro que mensaje quería dar desde que propuse la charla, pero no cómo hacerlo. Aún tras haberle dado muchas vueltas a la presentación, seguía sin convencerme totalmente, y eso (junto a mi archienemigo en las presentaciones: el micrófono de mano :) ) me hizo empezar con unos nervios y presión que no sentía desde cuando hacía mis primeras charlas. Luego poco a poco me calmé, remonté y empecé a comunicar mejor, pero desde luego que no me quedé para nada satisfecho con el resultado; espero que algunas de ideas hicieran mella y sirviera de utilidad a los que asistieron.

Sobre el lugar: Me pareció un acierto el que fuera en el centro de Madrid, para los que venimos de fuera es mucho más atractivo y facilmente accesible en transporte público, además de la comodidad de comer en el mismo hotel. Por poner un par de pegas, los contras para mi fueron los pequeños atascos en los ascensores para cambiar de sala, aunque había bastante tiempo entre charlas que lo compensaban, y principalmente que en una de las salas, por su disposición, las líneas de abajo de algunas proyecciones no se veía bien desde el fondo (terminé de pie en varias ocasiones por ello) y que su acústica era bastante mejorable.

Algunas pequeñas impresiones que me llevo:

  • Ya hay un buen puñado de proyectos de entidad que utilizan grails en españa, para los que aún creen que no es una herramienta “seria”
  • Seguimos siendo una comunidad muy pequeñita, con 2-3 focos geográficos donde hay más desarrolladores utilizando estas tecnologías, pero muchos estamos un tanto aislados
  • Spock definitivamente está empezando a ser (o está ya siendo) el framework de testing más utilizado, de 5 charlas de testing 4 tocaron (tocamos) este framework
  • Creciente interés por arquitecturas orientadas a eventos/asíncronas (vert.x, el roadmap de grails, algunos plugins…)
  • Me pareció muy interesante que se intentara internacionalizar con la mayoría de charlas en inglés, creo que es un camino a seguir para tratar de atraer a más público europeo

Por cierto, hay un buen puñado de fotos del greach en el evento de google plus, y un resumen del movimiento en twitter, slidesahre y demás en eventifier.

Facilitando en el Global Day of Coderetreat

El 8 de diciembre se celebraba el Global Day of Coderetreat, un evento a nivel mundial en el que en cada ciudad que se une se organiza un coderetreat. En Zaragoza se organizaba desde Agile Aragón, el principal responsable de ello fue Fernando Pérez. Y, de rebote, al final me tocó a mi ejercer como facilitador.

Para mi era un poco marronazo el hacerlo. Aparte de no haber facilitado nunca antes, tan sólo había asistido a uno hace ya un par de años y a 2 coding dojos. Tampoco soy muy dado a hacer katas sin hacerlo junto a otra persona.

Tuve una semana previa apretadilla, pero saqué tiempo para poder volver a practicar un poco la kata del juego de la vida y empaparme de los recursos para facilitadores para ir un poco más preparado. Yo terminé el día relativamente satisfecho (y agotado), quizás porque al final que los asistentes le saquen el máximo partido al día depende de ellos mismos, de sus iteraciones, sus parejas de baile en cada una de ellas y su actitud. Yo me limité a introducir algunas variaciones y restricciones para ir complicándolo y darles otros puntos de vista para tratar de hacerlo más ameno.

Por lo que sabía, en principio habían algo más de 30 personas apuntadas, de las cuales terminaron asistiendo un total de 25 personas (si no conté mal), lo que no está nada mal para un sábado en mitad de un puente ¿no?. Antes de empezar, acumulamos fuerzas con un desayuno patrocinado por la gente de keensoft mientras llegaban todos los asistentes al BSSC.

null

Tras ello mostré rápidamente un par de videos sobre el Global Day of Coderetreat, y posteriormente pedí que cada uno se presentara brevemente para explicar a qué se dedicaba y con qué lenguajes solía trabajar, así cada uno pudiera fichar con quien quería “aparearse” durante el día :) .

Al final hicimos 6 iteraciones de 45 minutos:

  • La primera libre para familiarizarse con el problema, para calentar un poco el cerebro :)
  • En la segunda propuse que se tratara de empezar a practicar Test First, o al menos hacer Tests. En la anterior ya mucha gente empezó al menos haciendo tests, por lo que propuse que todas las parejas lo hicieran ya. Y también que se pensara en empezar a solucionar las reglas una a una y no de golpe.
  • En la tercera insistí en tratar de hacer TDD, que buscaran el hacer antes el test siguiendo el flow de rojo, verde, refactoring. Y prohibí hacer el tablero/grid en los primeros 20-30 minutos de la iteración.
  • Para la cuarta, con la modorra después de comer y viendo que la gente tenía la mecánica de hacer tests antes de la implementación, propuse que se practicara pair programming en ping pong. Eso es que: Foo escribe un test, Bar la implementación, una vez implementado (y refactorizado) Bar escribe el siguente test y Foo la implementación… y así hasta el infinito, o acabar :) .
  • Para la quinta puse la restricción de que los métodos no debían tener más de 4 líneas de código. Además, justo en mitad de la iteración, hice un pequeño experimento haciendo un cambio de parejas. Alguien de la pareja se quedaba con el código la otra persona tenía que incorporarse a lo que hubiera adelantado otra pareja. Fue curioso ver que durante varios minutos las parejas hablaban para saber qué se había hecho y nadie tiraba una línea de código :P .
  • En la sexta y última iteración sólo tenía pensado poner una restricción, que no hubieran flags y así forzar a tener que usar polimorfismo. Al ser la última no quería proponer nada más, que la gente procurara aplicar lo aprendido durante el día pero forzando a darle un enfoque un poco diferente.

Entre medias de las sesiones surgieron temas como los magic numbers, la dificultad de encontrar buenos nombres a métodos o variables, la expresividad del código, las bondades del testing o el pair programming, encapsulación, orientación a objetos…

En cuanto a lenguajes, aunque había predominio de Java y C#, se utilizaron un buen puñado. Si no me dejo ninguno: Python, Groovy, Javascript, Objective-C, C++, PHP y algunos aventureros probaron TypeScript. No fue así, pero esperaba que en algún momento se hubiera animado alguien a alguna iteración con Ruby, o incluso con CoffeeScript :P .

Al final del día hicimos lo que llaman cerrar el círculo, cada persona tenía que hacerse (en alto) tres preguntas y compartirlo con el grupo: ¿qué has aprendido hoy?, ¿que te ha sorprendido hoy?, ¿que vas a hacer diferente a partir de hoy?. Personalmente, como otros también compartieron cerrando el círculo, me quedó la espinita clavada de quienes no veían posible aplicar en sus trabajos diarios las cosas de practicadas durante el día. No sé, no creo que sea fácil desde abajo imponer según que prácticas a una organización de golpe, pero hay pequeñas cosas que pienso que sí se pueden intentar para que las empresas empiecen a ser más receptivas para hacer las cosas de otra forma; pero esto es otro tema :P .

Como curiosidades, tuvimos una partida en el futbolín del BSSC lista desde primera de la mañana y ni nos acordamos de jugar al menos un par de bolas. Además en Zaragoza teníamos un bonus, Francho trajo un pequeño tirador de cerveza que fue la sensación del día, puro Beer Driven Development de la que final del día no quedó ni gota ;) .

Para terminar el día, antes de recoger la sala e irnos de cañas, conectamos por hangout con el Coderetreat de Madrid; nos saludamos y estuvimos charlando un poco de como habíamos pasado el día. Fue el momento en el que se hizo patente que la estrella del día fue el tirador de cerveza :D .

En definitiva, creo que fue un buen día, yo terminé agotado del fin de semana y con mono de no poder haberme apareado para hacer la kata :P .

SpotyWhere, nuestro proyecto en el Grails48

El segundo fin de semana de Noviembre, se celebró el primer Grails48, un hackathon a nivel mundial en el que se debía desarrollar una aplicación web hecha con Grails en el transcurso de un fin de semana.

Pues bien, yo participé en un equipo junto a Raúl Gracia (desde Londres), Fernando Val (desde Dublín), Rafael Ramos (desde Zaragoza) y Alberto Vilches (desde Madrid); lo que viene siendo un equipazo, que además del evidente handicap de que supone la deslocalización tenía alguno más. Salvo Raúl y yo, el resto no habíamos trabajado nunca juntos (o no más que en proyectos pequeños por amor al arte). También sabíamos que no íbamos a pegarnos todo el fin de semana programando (por ejemplo, yo mismo me fui con Rafa de concierto el sábado, con su posterior resaca :P ) y que la dedicación de algunos iba a ser bastante limitada por tener otro tipo de obligaciones. Pero, con el equipo que montamos, tenía claro que del fin de semana saldría un resultado interesante de todas formas.

La idea a desarrollar era de Raúl, una aplicación web donde localizar canciones en un mapa, que era la idea que más nos convenció de las que barajamos. Terminamos decidiendo centrarnos únicamente en Spotify y su API, y a partir de ahí empezó la gestación de SpotyWhere.

Spotywhere

El día antes hicimos algunos bocetos y wireframes, para intentar tener todos una idea lo más común posible de lo que iba a ser lo que íbamos a hacer y ponernos más o menos de acuerdo. Aunque al final las decisiones de la interfaz eran principalmente criterio de Fernando.

Para organizarnos y comunicarnos usamos varias herramientas: en una sala de HipChat procurábamos llevar el grueso de la comunicación, un poco de Skype para aclarar algunos puntos, Trello para gestionar nuestras historias de usuario y tareas, y un repositorio git privado en GitHub que ponía la organización.

La aplicación está desplegada en AppFog, que proponía de nuevo la organización, y decidimos utilizar MongoDB (en MongoHQ) como base de datos. Una base de datos documental encajaba bien con nuestras necesidades, además de permitir hacer búsquedas geo-espaciales (aunque ahora no las usamos) y el plugin de MongoDB GORM que lo deja muy facilón.

Decidimos habilitar el login/registro de usuarios con Facebook y Twitter, así dejábamos el registro más fácil a los usuarios y no teníamos que preocuparnos de montar todo el sistema de gestión de usuarios. Para esto y para la integración con la búsqueda de canciones de Spotify tiramos del plugin REST client facilities y HTTPBuilder.

Mientras que para la parte de front se usa Foundation, Google Maps junto a MarkerClusterer en los mapas y jQuery para algunos detalles de interacción.

Yo creo que nos quedó un resultado más que presentable, pero algunas mejoras y funcionalidades se tuvieron que quedar fuera. Cosas como un mapa en los perfiles de usuario o que pueda funcionar bien en terminales móviles son cosas bastante evidentes. También a nivel de código hay parches nada elegantes, como controladores con más código de la cuenta, no hay un miserable test, bastante javascript guarro y mezclado con el html… Lo típico en un hackathon de estas características, vamos :D .

En fin, el tema es que el domingo conseguimos terminar (no sin nervios en las últimas horas) y hicimos el despliegue, otro entregable era un video donde se explicara el proyecto. No había un tipo de video establecido, y el marrón recayó en Raúl, os lo dejo aquí :P .

Al final resultó que en el podio terminaron 3 equipos hispanos (2 españoles y 1 mexicano). Mientras que nosotros nos llevamos una de las 3 menciones especiales, cosa que no ha estado nada mal :) .

Una cosa que también me llamó la atención es que, al parecer, la organización contaba (¿cuenta?) con mentores y partners que en su momento podrían ayudar de algún modo a evolucionar a algo más serio a los proyectos participantes.
Veremos si alguno de los proyectos lo hace, en nuestro caso no creo que tuviera sentido. No deja de ser un proyecto bonito y que puede ir creciendo, pero muy complicado de hacer algo monetizable alrededor, o ganar dinero con él, que decimos los de pueblo.

Bueno… siempre nos podría comprar spotify XD.

Git tip: Aumentar el postBuffer para push con cambios grandes

Ayer me surgió un problema al hacer push a un repositorio remoto de git (en bitbucket). El tema es que el repositorio, además de para las gestión de versiones del código en sí; se va a empezar a utilizar para mantener versiones del .war de una aplicación Grails, donde se va a usar también un hook para actualizar y desplegar la aplicación a un entorno de preproducción.

Como resulta que git por defecto tiene un postBuffer de 1MB, y los .war pesan algo más de 40MB, me daba el siguiente error:

Error: RPC failed; result=22, HTTP code = 411

Para aumentar el postBuffer es tan sencillo como cambiar la configuración en el repositorio local:

git config http.postBuffer bytes

Donde bytes será el tamaño máximo de los que se permitirá hacer push.

VandalArt, ¿arte o vandalismo?

Los últimos meses he andado trabajando en proyectos de esos en los que no se luce, que bien son más empresariales, que se ha retrasado su salida al público y/o es trabajo alejado de la interfaz de usuario.

Quizás sea por eso que desde este verano ande un tanto disperso entre proyectos personales, tanto arreglando pequeñas cosas de algunos existentes, como trabajando en algunos nuevos. Tema aparte es el auto-enmarronamiento de la coordinación del grupo de trabajo de CachiruloHub, pero ese es otro tema.

Pues bien, uno de los pequeños experimentos a los que le he ido dedicando algunas horas es VandalArt.org. Una aplicación web que extrae referencias a fotos en instagram que se hayan etiquetado con ciertos hashtags (en este caso varios relacionados con arte urbano).

¿Por qué?

Por un lado porque instagram es uno de esos servicios que consulto y uso a diario, me gusta. Por otro, porque me gusta caminar por la calle y sorprenderme encontrando graffitis u otro tipo de obras que no conocía, o quedarme mirando de vez en cuando alguna que ya conozco.

Y al final se me pasó por la cabeza mezclar ambas cosas para poder ver arte urbano de cualquier parte del mundo.

¿Cómo?

La verdad que es una aplicación bastante simple. Desarrollada con Grails (el look and feel de la web lo delata ;) ), utilizando el plugin de Quartz para hacer peticiones al API de instagram cada 30 minutos, de donde extrae la información de la foto y sus enlaces, pero las fotos siguen estando en instagram, por supuesto.

Como una cosa que me parecía muy curiosa era ver fotos sobre un mapa, implementé esa funcionalidad para las últimas 50 fotos subidas (y geolocalizadas). Se muestran usando la librería leaflet para interactuar con mapas, y los tiles son de cloudmade. Realmente no es gran cosa, pero creo que queda resultón.

El código está publicado en github con licencia MIT.

Be like a panda

¿Roadmap?

Tengo varias funcionalidades en mente, que supongo que haré poco a poco, principalmente:

  • Que te puedas registrar para guardar fotos como favoritas, simplemente porque te gusten o te puedan servir como forma de inspiración o por lo que sea…
  • Que funcione en tiempo real. Para este caso pienso que quedaría muy molón ver como aparecen nuevas fotos, y me apetece bastante jugar con el API Real-Time.

Y por cierto, que el proyecto ya tiene su primer fork. Para la Semana del Cine y de la Imagen de Fuentes de Ebro estaban organizando un concurso de instagram, tomando unas cervezas les comenté que posiblemente podrían aprovechar el código para hacer la web del concurso.

Y vaya si lo han hecho! Me encanta como les ha quedado la web del concurso de instagram de SCIFE :)

Grails tip: Importar direcciones de email de LaunchRock

Sigo trabajando en minchador, no al ritmo que hubiera querido (espero escribir sobre ello), pero sigo dándole.

Estoy ya preparando el lanzamiento de la beta cerrada arreglando detalles: mejorando textos, ajustando cositas de la UI, dándole vueltas al email de bienvenida, importando los mails de los que se han ido registrando en la landing hecha con LaunchRock

Pues bien, para sacar las direcciones de LaunchRock dejan a tu disposición la posibilidad de descargar los datos en un fichero en formato CSV con la siguiente estructura:

“timestamp”,”email”,”domain”,”user_clicks”,”user_signups”,”referred_by”,”ref_url”

Entonces lo que hice fue prepararme un sencillo Service de grails para importar tan sólo las direcciones, el código es el siguiente:
 

class LaunchRockService {
def emails
    def getEmailsFromCSV(csv) {
     def emails = []
     def lines = csv.split(‘\n’)
     lines.each{
     def email = it.split(‘,’)[1]
     emails << email.replaceAll(‘”‘,”)
     }
     return emails
    }
    def getEmailsFromFile(file){
     def lines = file.text.split(‘\n’)
     def total = lines.size()-1
     lines = lines[1..total]
     emails = getEmailsFromCSV(lines.join(‘\n’))
    }
    def emailIsForBeta(email){
     return emails.contains(email)
    }
}

 

Lo que hago es pasarle una instancia de File del csv de LaunchRock a getEmailsFromFile y recuperar todas las direcciones de email. En mi caso ejecuto ese método en el BootStrap de grails para tenerlas cargadas en memoria y acceder a launchRockService.emails desde otras partes de mi aplicación.

Ya puestos dejo el código junto a los tests los hice con especificaciones de Spock en un gist, por si a alguien le interesa.

Grails tip: Manejar uploads múltiples con mismo nombre de parámetro.

Una cosilla que he tenido que volver a hacer últimamente es tener que implementar un upload múltiple sencillito. En esta ocasión, sin necesidad de utilizar flash-javascript de por medio, gracias a la capacidad de selección multiple que viene con Html5:

<input name="images" type="file" accept="image/*" multiple="multiple">

El problema es que así todos los archivos que queremos subir vienen con el mismo nombre de parámetro, y el código habitual no se puede más que recuperar los ficheros subidos con distinto nombre.

request.fileNames.each { fileName ->
   def file = request.getFile(fileName)
   //hacer cosas
}

Pues bien, tras un par de búsquedas encontré una de esas pequeñas cosas que (por desgracia) no eres capaz de encontrar fácilmente en la documentación de grails: getMultiFileMap, que viene implementado desde Spring 3.

En fin, su uso en un controller de grails es el siguiente, es un map que contiene la colección de elementos que representa a cada fichero. Colección que recorreremos normalmente, o trataremos para lo que queramos hacer.

request.multiFileMap.images.each { file ->
   //hacer cosas
}

Reutilizar un custom validator en Grails

En estos momentos ando colaborando con Sergio del Amo en un producto propio para su empresa Softamo, un producto que estamos desarrollando con Grails.

El tema es que teníamos un puñado de clases de dominio que están relacionadas con un propietario, una clase User. Cada instancia de esa clase de dominio debía tener un nombre único por propietario, por lo que debíamos usar un custom validator. Al final, tras varias refactorizaciones llegamos a una solución que creo que quedó bastante elegante.

Las clases de dominio heredan de una clase padre con varios métodos comunes, además de una clausura estática que contiene la lógica de la validación uniqueByUser, que es lo que nos interesa para esto.

static uniqueByUser = { value, object ->
   propertyName = propertyName[0].toUpperCase() + propertyName[1..propertyName.size()-1]
   def methodName = "findByUserAnd${propertyName}"
   def obj = object.class."$methodName"(object.user, value)
   if(obj && (obj.id != object.id)) {
     return 'unique'
   }
}

Vale, por si no queda del todo claro, intento detallar que hace el código:

  • propertyName, es el nombre de la propiedad/atributo sobre la que se ejecutará la validación, variable que está implícita en la clausura.
  • propertyName[0].toUpperCase() + propertyName[1..propertyName.size()-1], ponemos en mayúscula el primer carácter del nombre del atributo (por ejemplo “name” pasa a “Name”).
  • def methodName = “findByUserAnd${propertyName}”, ponemos el método al que vamos a llamar para saber si ya existe un valor con mismo usuario y atributo buscado (por ej: findByUserAndName).
  • def obj = object.class.”$methodName”(object.user, value), ejecutamos ese findBy* estático sobre la clase del objeto instanciado que se está validando, pasándole el usuario relacionado y el valor del atributo (algo que podría ser equivalente por ejemplo a Drink.findByUserAndName(drink.user, “vodka”)).
  • if(obj && (obj.id != object.id)), comprobamos que si se devuelve un valor, no sea el mismo que la instancia del actual.
  • return ‘unique’, en este caso devolvemos el código de mensaje de validación como unique, por lo que aprovecharemos los mismos mensajes i18n del unique estándar de grails.

Entonces, en nuestras clases de domino que hereden de ahí, para el atributo donde queramos utilizar ese constraint simplemente deberemos indicar validator: uniqueByUser. Algo como:

static constraints = {
   name blank: false, validator: uniqueByUser
   description blank: false
}

Lo único que no contempla ahora mismo esta solución es tener más de un custom validator, principalmente porque no nos ha hecho falta. Si lo llegamos a necesitar, veremos como lo hacemos, claro :P .

Mejoras y propuestas bienvenidas.

ACTUALIZACIÓN: Mejor que darle tantas vueltas como hicimos nosotros, es utilizar el soporte multi-column de la constraint unique (Nota mental: No dar por supuestas según que cosas, e ir a verlo a la documentación). Gracias al comentario de @jneira.

Open Space. Código como Expresión.

Este fin de semana estuve en Valencia en el open space convocado por agilismo.es, que llevaba por nombre Código como Expresión. La verdad que hacía tiempo que me apetecía asistir a un open space exclusivo sobre código, además de volver a visitar Valencia, conocer un poco la escena de desarrolladores y ver las oficinas de beCode (aún tengo pendiente pasar unos días con ellos).

Finalmente fui desde Zaragoza con Miguel Ángel Baztan y Fernando Pérez, 2 de los habituales del grupo Agile Aragón. En el evento también había gente llegada desde Castellón, Madrid, Segovia… incluso Pepe que se pegó una auténtica paliza de viajes desde Santiago de Compostela. Entre unos y otros, estuvimos algo más de 30 personas.

A niveles generales, me gustó bastante el evento, salvo un par de detalles/sensaciones que tuve durante algunos debates. He intentado hacer un pequeño resumen de cada sesión, pero por el formato del evento y mi torpeza, no he sido capaz.

Tablón. Open Space Código como Expresión

¿De qué se habló?, en las conversaciones y debates que estuve yo:

  • De la (poca) expresividad de las APIs REST, aunque para exponer e integrar sistemas diferentes, hasta el momento, es habitualmente la mejor alternativa.
  • Del spaghetti code relacionado con el uso de javascript asíncrono y algunas buenas prácticas para mejorar ese código.
  • De lenguajes y paradigmas de programación (orientado a objetos, funcional, procedimental); y como conocer varias opciones nos hacen enfocar soluciones desde más puntos de vista.
  • De la nomenclatura y expresividad en los tests. De frameworks de testing tipo BDD para diferentes lenguajes.
  • De identación y comentarios en el código.
  • De herramientas: IDEs, editores, tableros tipo kanban, software para hacer pair programming…

Os dejo las fotos que ha publicado Emma del evento.