Desplegando a diferentes instancias de heroku

Lo iba a apuntar en un documento para no olvidarlo, no es gran cosa, pero ya puestos lo hago en el blog por si a alguien le sirve también.

En uno de los proyectos que estoy trabajando es una aplicación rails que está montada en heroku, por lo típico que no quiero andar preocupándome de sistemas y de poder que aumentar de máquinas en caso de ir creciendo. Además del entorno de producción, tenía que montar uno de staging, por lo que tenía que configurar dos instancias/aplicaciones de heroku para la misma base de código.

Para ello el primer paso es añadir el remote al git, en mi caso lo llamo staging.

git remote add staging git@heroku.com:my-app-staging.git

Lo siguiente es hacer el despliegue haciendo push, en este caso trabajo sobre una rama dev que es desde la que hago el despliegue al entorno de staging.

git push staging dev:master

Quede dicho que el manejo de ramas es master para producción y dev para desarrollo/staging, al trabajar sólo (salvo para cosas puntuales de maquetación) por el momento me resulta más que suficiente.

Una de las cosas que pasa es que necesitaremos pasarle el parámetro –app para decirle sobre que instancia queremos hacerlo. Algo así:


heroku rollback --app my-app
heroku run rake db:migrate --app my-app-staging
heroku logs --app my-app

Y ya, en un pispas está todo listo.

Selenium y Web Scraping en Zaragoza Python Days

La semana pasada fui vilmente engañado para que preparara una charla en el retorno a la actividad del grupo de usuarios de Python en Zaragoza, a sus reuniones las han bautizado como Zaragoza Python Days y la primera fue ayer lunes en Dlabs.

No es que sea yo muy pythonista, pero he hecho mis cositas, y desde hace un tiempo es mi lenguaje por defecto cuando estamos hablando de Web Scraping, por la cantidad y diversidad de librerías que existen. Como voy publicando en mis retros semanales, llevo bastante tiempo trabajando con Selenium para estos menesteres, por lo que tenía de cajón el tema que iba a tratar. Aproveché a comentar también el porqué para el caso de ShuttleCloud se había optado por esta solución y comentar, a vista de pájaro, algunas cosas de su arquitectura.

También preparé una sencilla demo, sacar los cumpleaños de los contactos de una cuenta de facebook. No me maté mucho: creé una cuenta “fake” de facebook y pedí a algunos amigos que me aceptaran esa cuenta, habría que hacer modificaciones para sacar los de una cuenta real (empezando por soportar paginación)… pero como ejemplo de como hacer un scraping sencillito con selenium creo que estuvo bien.

Empezando la charla (Foto de David Lechón)

La verdad que el número de asistentes, sin ser ni masivo ni mucho menos, estuvo bastante bien y el feedback recibido de la charla ha sido mucho mejor de lo que esperaba. También salieron algunas preguntas interesantes que me ayudaron a aclarar algunas cosas que durante la charla pasé por alto o a las que no les había dado demasiada importancia.

Por cierto, que me encanta ver gente más joven que viene empujando fuerte estén liándose también a organizar grupos y saraos. Hay buena cantera :).

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
}