Git branch & Subversion detection en el prompt de Bash

Simple, agregar en el .bashrc lo siguiente :

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* (.*)/(1)/'
}

function detect_svn {
  test -d .svn && echo "(svn)"
}

function proml {
  local         RED="[33[0;31m]"
  local   LIGHT_RED="[33[1;31m]"
  local      YELLOW="[33[0;33m]"
  local LIGHT_GREEN="[33[1;32m]"
  local       WHITE="[33[1;37m]"
  local  LIGHT_GRAY="[33[0;37m]"
  local LIGHT_PURPLE="[33[1;34m]"
  case $TERM in
    xterm*)
    TITLEBAR='[33]0;u@h:w07]'
    ;;
    *)
    TITLEBAR=""
    ;;
  esac

PS1="${TITLEBAR}
$LIGHT_PURPLEw$YELLOW$(parse_git_branch)$(detect_svn)
$LIGHT_GRAY$ "
PS2='> '
PS4='+ '
}
proml

Y se ve algo como (sin colores, sorry 🙂 :

~/src/some_git_project(master)$ 
~/src/some_svn_project(svn)$

Audacity en Paranormal Activity

La película es muy mala (no puedo creer que tenga casi 7 puntos en IMDB), pero mientras iba adelantandola a ver si pasaba algo me encontré que el protagonista usa Audacity para filtrar los ruidos de los “espíritus” :

Ahora por lo menos se que con software libre puedo investigar los ruidos misteriosos de una casa :).

Hacia las Jornadas Regionales

Ya falta solo una semana para que me vaya para Chile a las Jornadas Regionales de Software Libre que este año organizó Open Community.

Si bien voy a ir 10 días porque aprovecho para conocer, en las jornadas voy a estar presentando dos charlas

Charla: Liberando Windows
Dia: Miercoles 7 de Octubre

Charla: Introducción a OAuth
Dia: Jueves 8 de Octubre

Hay varios oradores interesantes confirmados, aunque todavía no se publicó qué va a dar cada uno ni el calendario completo de los 3 días.

Regalando cosas por Bluetooth

El año pasado Movistar había lanzado una campaña muy pedorra en el subte, en donde unos carteles en el piso te invitaban a prender tu Bluetooth y te enviaban un file. Lo que te enviaban era una simple imagen, con tanto texto que en mi celular era casi ilegible y no tenía consigna alguna.

Sin embargo esto sirvió para que me encaprichara y quisiera armar algo similar para la oficina, orientado a que un cliente que viene a una reunión se pueda llevar un regalo, que en este caso es un juego J2ME.

Hacerlo realmente es una boludez. El real problema, que no voy a tratar acá, es tener una placa Bluetooth soportada por Linux (creo que esta solución aplica Windows, pero no lo probé), lo que puede resultar complicado. Yo en mi anterior laptop fallé en cada intento. Hoy en día en mi MacBook anda todo out-of-the-box por suerte así que pude jugar un poco.

El protocolo que se utiliza para intercambiar cosas es Object Exchange (OBEX) y tenemos una excelente biblioteca llamada OpenObex. A nosotros nos interesa particularmente ObexFTP que nos da el File Transfer sobre Obex.

El primer problema que tuve es que en Jaunty no está el binding de ruby, por lo que me tuve que bajar el source y diff de Karmic y crear mis libobexftp-ruby_0.22-1_i386.deb y sus dependencias.

Salvando eso, con los ejemplos del wiki sale muy fácil. La biblioteca nos permite descubrir devices, abrir channels y enviar archivos en pocas líneas. Acá un en ruby ejemplo :

#!/usr/bin/env ruby

require 'obexftp'

puts "Scanning BT..."
intfs = Obexftp.discover(Obexftp::BLUETOOTH)
dev = intfs.first # Es un array, podríamos iterar sobre todas las encontradas

channel = Obexftp.browsebt(dev, Obexftp::PUSH)

cli = Obexftp::Client.new(Obexftp::BLUETOOTH)
puts cli.connectpush(dev, channel)
puts cli.put_file('ver.jpg')
puts cli.disconnect

Hacer lo mismo en Python, Perl o cualqueir otro lenguaje soportado es igual de simple.

Obviamente es muy minimalista: agarra el primer device encontrado, abre un channel para hacer un PUSH (si el device no soporta PUSH retorna -1 según creo), luego abre la conexión y le envía el archivo.

Desde el celular vemos un mensaje de que se está abriendo una conexión y luego el detalle de lo que se quiere enviar, nombre del archivo, tipo de archivo, tamaño, etc. Podemos aceptarlo o rechazarlo. De aceptarlo se descarga pero no se guarda ni se instala, es un paso extra que debemos decidir si lo hacemos o no.

Un problema que encontramos para enviar juegos es que algunos celulares están bloqueados para esa función (para así vendértelos por el portal WAP oficial de tu carrier). Ya lo pudimos probar con varios celulares Nokia, Motorola y Samsung y funciona razonablemente bien.

Sobre este ejemplo nosotros tenés un poco más de trabajo, ya que guardamos los device ID y el contenido enviado, así cuando volvés te damos un contenido diferente :). Si además no podés recibir el juego, te pasamos una imágen simpática :P.

Linux ath9k y beacon loss from AP

Hace unos días finalmente instalé Ubuntu 9.04 nuevamente en mi MacBook y estaba muy contento con el soporte (iRemote, iSight, Suspend e Hibernate, etc) hasta que empezaron los problemas con la placa Wifi.

El síntoma es que a cada rato se desconecta un segundo y vuelve, lo que lo hace insoportable para aplicaciones como Skype (y bue, de alguna forma cómoda hay que comunicarse con la flia) o trabajar por ssh.

El problema al parecer es una mezcla del driver ath9k y NetworkManager. Lo que sucede es que cuando el NM trata de refrescar la lista de APs dispara una operación que en el driver se reduce a ejecutar algunos cambios de frecuencia, reset de registros, etc. y eso si sobrepasa un cierto tiempo (que ahora no recuerdo si eran 2 o 4 segundos y tampoco guarde el link :D) dispara un trigger de “beacon loss from AP” y el NM cree que se desconectó y reinicia la conexión.

Hasta el momento el único workarround que encontré que parece funcionar bien es sacar NM e instalar wicd que no hace auto-scan de APs, por lo que no ocurre el problema (apt-get install wicd automáticamente desinstala NM).

MySQL a CSV remotamente desde el shell

Algo que siempre me molestaba de cuando una campaña deja de correr era la molestia de los día siguientes : “me exportas a,c,b de tal tabla”, “me das mejor b,a,c” y así sigue la molestia.

Más que nada porque tenía que loggearme al DB server, hacer un dump o correr algún script de php para armarlo.

Bueno, hoy buscando otra cosa caí sin querer en este tip que usa el comando myql y sed desde el shell. Así que ahora puedo tirar la query por la VPN (bueno, cuando ande bien voy a poder :D) directo al DB server y mandar por email el CSV :).

mysql -u user -h host -p --execute="SELECT campo1, campo2, campoN FROM  table_name" database_name | sed 's/t/","/g;s/^/"/;s/$/"/;s/n//g'

Esto lo tira al stdout, agregando un “> output.csv” estamos hechos.

Do it right! – Manejo de dependencias

En estos días he tenido varias discusiones sobre algunas prácticas muy acostumbradas en varios proyectos, que a mi parecer están muy lejos de lo útil. Es por eso que decidí escribir un par de artículos denominados “Do it right!” (hazlo bien!, si mi inglés no es tan malo como pienso :D). En esta primer entrega voy a tratar el tema de manejo de dependencias.

Escenario

Muchas veces uno se encuentra con un software que necesita y le es útil. Vamos a suponer de entrada que no tiene paquete para su distribución y/o sistema operativo favorito. En al leer el README vemos que depende de muchas cosas : alguna biblioteca de procesamiento de imágenes, algún captcha system o lo que sea.

Mirando mejor nos encontramos con una realidad muy fea : todas las dependencias están incluidas en el archivo que nos bajamos originalmente, y alguna veces se cargan por métodos poco ortodoxos.

Cualquiera que haya bajado cosas en PHP o Java seguramente se ha encontrado con esto : Clases bajadas de phpclasses.org o miles de archivos JAR en un directorio lib de la aplicación Java que se cargan en el classpath. También lo he visto en varios proyectos Rails últimamente.

La excusa que siempre escucho es “Because it makes the app more self contained“, si, si, BWTF. Pero la pregunta es : ¿es la forma correcta?. Si respondes que si, estás muy lejos de la realidad y seguramente tu sysadmin te odia mucho, pero mucho :).

El Problema

Entonces, ¿cuál es el problema con esto?. En principio parece una maravilla, nos facilita todo, descomprimimos y ya está!, el sysadmin (nosotros) agradecido, pero si el sysdamin es otra persona y se respeta los va a putear mucho, pero muuuuuucho.

Uno de los problemas con empaquetar todas las dependencias es la facilidad de solucionar problemas a futuro. El mejor ejemplo que he vivido es el típico cambio de time zone en nuestro país. PHP, por ejemplo, tiene su propia DB de timezones, y si actualizamos el tzdata de nuestro servidor, maravillosamente PHP ni se entera. Está bien que en este caso como programadores no podemos hacer mucho, es el lenguaje el que está mal, pero el ejemplo ilustra mi punto.

Un software con el que tuve que trabajar, vBulletin, va aún más allá. Tiene su propia DB de timezones por arriba de la que tiene PHP!, hardcodeada en un array!. ¿La excusa? Que la de PHP no anda bien en Windows y es mejor de esta manera.

Otro ejemplo que puedo dar es el otro día cuando migré unos sitios en el trabajo. Uno de los admines se quejó que dejó de andar porque usaba la función “dl” de PHP para cargar extensiones en tiempo de ejecución! (es decir, cualquier script PHP puede cargar un .so que extiende PHP de cualquier manera, incluso para saltearse otras medidas de seguridad), lo que no solo es una chanchada, sino que es un potencial problema de seguridad.

Tener el manejo de dependencias con la aplicación además nos prohíbe actualizar fácilmente un bug de seguridad, usabilidad o lo que sea de esa dependencia. No podemos en muchos casos hacer un upgrade de ese paquete que está embebido dentro de un todo llamado “aplicación”.

En rails he visto ya muchos que acostumbran a usar “rake gems:unpack” para meter las gemas de las que dependen en el directorio vendors/gems, así no las tienen que instalar aparte. Rubygems disgusta en muchos ambientes, no voy a entrar en eso hoy :). Si uno depende  de una versión específica la forma correcta sería especificar en el environment.rb la versión, y luego que el que hace el deploy haga un “rake gems:install” para asegurar que se cumplan las dependencias. Con Capistrano es una papa hacer esta tarea automáticamente ;).

Entonces, ¿nunca más lo hago?

No me gustan los extremos y creo que estas malas prácticas que se ven hoy tiene usos muy específicos.

Supongamos que el proyecto X usa la lib Y, pero tal cual la provee upstreem no me sirve. Lo lógico es hacer un patch para upstream solucionando el problema o agregando la característica.

Mientras upstream acepta el patch y realiza un nuevo release, ahí si tiene sentido tal vez, y de forma temporal tener esa dependencia embebida.

Un ejemplo donde yo lo estoy haciendo es con el uso de la gema contacts, que depende de la gema json. En una aplicación con Rails 1.2.6 no hay ningún problema, pero en otra que usa Rails 2.1 si, porque este último integra un parser de JSON y conflictua con la gema del mismo nombre. La opción lógica sería migrar la aplicación 1.2.6 a una nueva versión de Rails, cosa que no siempre es fácil y se necesita el tiempo. Como no se pudo, es más fácil meter en uno de los proyectos la gema de manera que no moleste al resto de los proyectos en el transcurso de la actualzación.

Seguro hay algún otro caso, ahora no se me ocurre alguno que realmente lo justifique.

Jornadas Regionales 2008 – Día 1

Día agotador, como hace mucho que no sufría :D.

Como todos los años arrancaron las Jornadas Regionales cuyo organizador en esta oportunidad es Cafelug. Los chicos arrancaron a pleno, super organizados, aunque como siempre sobre el final se olvidan de algunos detalles en la marea de gente consultando cosas.

Yo arranqué temprano dando una charla de Software Libre para Windows orientado a home/office user, sin tocar siquiera temas más de coding. No es una charla que me super guste pero fue “por encargo” y no me costaba nada sumar.

A la tarde fui a dar la segunda (y espero nunca repetir el error de dar dos charlas el mismo día, a mi garganta no le hace gracia :P) : SocialApps con Ruby On Rails. Fue un poco rara esta, porque iba a ser un taller pero no pude al final, así que hice un lindo cookbook y creo que a la gente le gustó. Estoy filmado en dos ángulos distintos, después tengo que conseguir los videos, y obviamente, destruirlos :D.

Como asistenmte estuve en muy pocas la verdad, más que nada porque me colgaba charlando con gente que hace mucho que no veo.

Vi un poco de Introduction to building RPM packages, a un amigo que debutaba en las jornadas con Desarrollo de aplicaciones Sociales. y la mitad de Mozilla and Browsers over the last 10 years. porque me tenía que ir a dar clases.

Este año el regalo por dar charlas me vino barbaro : un mate!. Si, el mío ya tenía que jubilarse por lo que me viene al pelo. Es lindo ver como estos eventos crecen año a año.

Aprendiendo a Dibujar

O más bien, intentando aprender a dibujar :D. La semana pasada decidí que quería aprender a dibujar, así que me puse a investigar donde ir a estudiar. Encontré un par de lugares que parecen copados, pero hasta julio/agosto no empiezan, tengo que esperar.

Este finde largo, en casa y aburrido, sin cacerola extra para golpear, empecé a buscar online, como dios manda 🙂 y me contré con Draw Space. El sitio tiene muuuucha data, tutoriales, step-by-steps, técnicas, etc. muy copadas y re simples. Obviamente no tenía lapices en casa, mucho menos hojas en blanco, así que improvisé y me pasé el finde haciendo ejercicios, dibujando cosas y mirando TV.

Algunas de las obras de arte a continuación

Katy Coala

Leon, primer intento Leon, segundo intento

En orden de aparición tenemos : Caty, Coala, Leon deforme, Leon no-tan-deforme :). Por suerte mirando las últimas dos se ve que “algo” progresé 😀

Ahora el paso B, es tomar alguna de estas y vectorizarlas con Inkscape, darle shades, etc. y ver si queda algo pasable.