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
}

Agile Manifesto. Camino del AOS

Ayer hubo un evento de introducción a las metodologías ágiles Camino del AOS, donde estuve explicando el manifiesto ágil y sus principios.

Os dejo la presentación:

La verdad que hubo una asistencia más que aceptable para un evento un lunes, además de ver un número de no-desarrolladores interesante :)

Y ya puestos, aprovecho a invitar a cualquier persona a que se venga este fin de semana al AOS 2012 para aprender o profundizar en temas relacionados con las metodologías ágiles. Seguro que nos lo pasamos bien :)