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.

Reiniciando...

Últimamente estoy dándole vuelta a muchas cosas sobre mi situación profesional, sobre lo mucho que me he equivocado alrededor del último año y medio. Yo lo que quiero es dedicarme a producto propio y a ir participando en proyectos de terceros. Pero como he cometido demasiados errores en mis decisiones, estoy en un punto donde jamás quise estar

Pienso que mis principales errores han sido no haber acertado eligiendo a mis clientes, no haber gestionado bien nuestra relación, no ser tan exigente con ellos como procuro serlo conmigo y/o no haber sabido cortar con ellos a su debido momento. Y es que hay algo que tengo más que asumido, si tengo problemas con un cliente el principal responsable soy yo.

Esto me ha llevado a situaciones que a uno le apetecen poco a estas alturas del partido:

  • Haber palmado pasta en un proyecto a un nivel indecente. Eso que tengo una sensación de que casi he invertido más dinero en el proyecto yo que el propio cliente.
  • Cobrar por debajo de mi precio (que de por sí era excesivamente barato) como apuesta y compromiso personal en un par proyectos. Para que luego se terminasen desvaneciendo todas las promesas de futuro, por supuesto.
  • Desarrollar un proyecto que ha acumulado una deuda técnica enorme por andar con prisas, debería haberme impuesto y parado el desarrollo hasta no haberlo renegociado y solucionado.
  • Tener retrasos en pagos, cosa que además en una ocasión acepté en como mal aceptable durante una colaboración y finalmente tuve que asumir un impago durante varios meses.

Siendo un desarrollador que trabaja para sí mismo y que quiere ganarse bien la vida, haciendo las cosas lo mejor posible, trabajar en proyectos bonitos y colaborar con grandes profesionales; cosas como esas no me han dejado avanzar en proyectos propios y colaboraciones, además de hacerme pasar momentos duros y situaciones poco agradables.

Ahora es momento de recuperar esos pasos e ir más allá, estoy procurando retomar un camino que quiero que me lleve hacia donde realmente quiero. Para eso estoy procurando elegir mejor a mis clientes, empezar a gestionar mejor nuestra relación, ser más exigente con ellos a todos los niveles y, si es necesario, cortar mi colaboración si no se cumplen unos mínimos de respeto y entendimiento profesional.

En fin, espero que no se perciba simplemente como un post de lloriqueo o un pataleo, nada más lejos. Que también he trabajado en algunos proyectos chulos; además ahora tengo cositas interesantes entre manos y espero ir compartiendo evoluciones :)

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.