Manuel Kaufmann (Humitos): Hotkeys for the win

¿Cuántas aplicaciones utilizás en el día a día? Digamos que nos limitamos a las más comúnes únicamente. En ese caso, mi respuesta sería: 6 (emacs, firefox, terminator, pidgin, thunar y thunderbird)

Esas aplicaciones las tengo abiertas casi todo el día. Además, a medida que voy trabajando comienzo a abrir otras: Google Chrome, LibreOffice, JOSM, gThumb, inkscape, Skype y algunas más. A mitad de la tarde, ¿cuántas aplicaciones tenés abiertas? Y lo más importante: ¿cuántas veces hiciste Alt + TAB? Aunque lo peor de todo es: ¿cuántas veces hiciste Alt + TAB y te pasaste por una ventana y diste toda la vuelta hasta la correcta o bien, te fracturaste un dedo haciendo Alt + Shift + TAB para volver una selección?

Bueno, hace varios años que yo me cansé de eso y decidí buscar una solución. La solución vino exactamente con la primera pregunta que te hice: ¿cuántas aplicaciones utilizás en el día a día?. Básicamente quería poder acceder a cualquiera de esas 6 aplicaciones sin que importara en qué orden las había abierto o había estando navegando por ellas. Digamos, que si fui a firefox, luego a pidgin y luego a thunderbird; quería poder saltar en un solo hotkey a terminator -que si usamos Alt + TAB tendríamos que presionarlo 3 veces consecutivas.

Primero me puse a investigar cómo se puede hacer para cambiar de ventanas utilizando la línea de comandos. Ahí llegué a wmctrl, que te permite listar las ventanas activas y también cambiar entre cada una de ellas mediante una interfaz de línea de comandos.

$ wmctrl -l -x
0x01600003  0 Thunar.Thunar         victoria humitos - Administrador de archivos
0x040000a3  0 emacs.Emacs           victoria emacs-victoria: ~/bin/change-window [-]
0x024000ab  0 Navigator.Firefox     victoria Inbox (0) - someone@gmail.com - Gmail - Mozilla Firefox
0x04200db8  0 Pidgin.Pidgin         victoria (someone@gmail.com)
0x0420006a  0 Pidgin.Pidgin         victoria Lista de amigos
0x03e00001  0 Google-chrome.Google-chrome  victoria Nueva pestana - Google Chrome

Ahora bien, con esa información de WINDOW_ID, NAME y WINDOW_TITLE ya puedo cambiar de una ventana a la otra utilizando su WINDOW_ID así -por ejemplo para ir a la lista de amigos de Pidgin:

$ wmctrl -i -a 0x0420006a

Ahora necesitaba presionar un hotkey y que ejecute algo que parsee esa salida y cambie a la ventana que quiero utilizando wmctrl. La ventana que "quiero" dependerá del hotkey presionado.

Entonces, ¡escribí un script en Python, por supuesto!

listings/hotkeys-for-the-win/change-window

#!/usr/bin/env python

import os
import sys
import commands

LIST_WINDOWS = 'wmctrl -l -x | grep -i {} | grep -v grep | tail -n {}'
CHANGE_WINDOW = 'wmctrl -i -a {}'
COMMANDS_TO_WMCMD = {
    'pidgin': 'Pidgin.Pidgin',
    'emacs': 'emacs.Emacs',
    'thunar': 'Thunar.Thunar',
    'firefox': 'Navigator.Firefox',
    'terminator': 'terminator.Terminator',
}


def get_window_id(command):
    # This function is horrible but it's late at night and I just want
    # this shit working :)
    if command == 'pidgin':
        n = 2
    else:
        n = 1
    output = commands.getoutput(
        LIST_WINDOWS.format(COMMANDS_TO_WMCMD[command], n))
    if n > 1:
        if command == 'pidgin':
            lines = output.splitlines()
            for l in lines:
                if 'Lista de amigos' not in l:
                    output = l
                    break
    print(output)
    win_id = output.split(' ')[0]
    return win_id


def main():
    program = sys.argv[1]
    win_id = get_window_id(program)
    if win_id != '':
        os.system(CHANGE_WINDOW.format(win_id))
    else:
        os.system(program)


if __name__ == '__main__':
    main()

Básicamente hace eso que dijimos. Sin embargo, le agregué una cosita más. A veces pasa que tengo abierta la "Lista de amigos" y una "Ventana de conversación" en Pidgin y necesitaba poder decirle que vaya a la ventana de conversación de alguna forma. Esto es porque cuando estás chateando con alguien querés poder presionar el hotkey, contestarle, presionar el hotkey del emacs y seguir codeando; sin necesidad de pasar por la lista de amigos. Entonces, hace eso: si hay una ventana con "Lista de amigos" en su WINDOW_TITLE, elije la otra que sea de Pidgin :)

Nota

No te olvides de asignarle permisos de ejecución a tu programa python con:

chmod +x change-window

Perfecto, lo único que queda es decirle a nuestro entorno gráfico que cuando presionemos nuestro hotkey maravilla ejecute nuestro programa. Yo uso xfce por lo tanto, tengo que modificar el archivo xml de mi directorio personal ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml y agregar estas líneas en la sección <property name="custom" type="empty">:

<property name="&lt;Super&gt;t" type="string" value="/home/humitos/bin/change-window terminator"/>
<property name="&lt;Super&gt;e" type="string" value="/home/humitos/bin/change-window emacs"/>
<property name="&lt;Super&gt;f" type="string" value="/home/humitos/bin/change-window firefox"/>
<property name="&lt;Super&gt;a" type="string" value="/home/humitos/bin/change-window thunar"/>
<property name="&lt;Super&gt;c" type="string" value="/home/humitos/bin/change-window pidgin"/>

Ahora sí, con Super+t voy a la terminal de Terminator sin importar dónde esté en ese momento. Lo mismo para Super+f, Super+c y demás. Antes de que pestañés, yo ya cambié 5 veces de ventana y siempre exactamente a la que quería ;)

Te aseguro que te vas a ahorar milisegundos con esto. Luego segundos, luego minutos y finalmente unas cuantas horas y puteadas de haberte pasado por uno con el Alt + TAB y tener que dar toda la vuelta cuando tenés 15 ventanas abiertas.

¡Ah! Y una cosa que me olvidaba: si el programa del cual presionamos el hotkey no está abierto, lo abre ;)

Vos, ¿cómo resolvés este problema?

Manuel Kaufmann (Humitos): Aplicando rock a mi Emacs

Hace tiempo que uso Emacs. Hace no tanto tiempo que lo tengo configurado como me gusta y eso es porque nunca entendí la lógica de elisp, que es lo que se necesita saber para poder configurar algunas variables y hacer unos hook. Sin embargo, con el tiempo le fui agarrando la mano y fui pudiendo instalar a mano un montón de plugins que cada tanto, los actualizaba y alguno de ellos explotaba. Por eso, con el tiempo, se me fueron pasando las ganas de ir buscando nuevas cosas para enchular mi emacs y me dedicaba a utilizarlo como lo había dejado hace algunos años (por lo menos 2).

Anoche me dije: "voy a volver a ver qué cosas nuevas hay para Emacs y actualizar mi entorno de desarrollo". Así fue que llegué a elpy y a un blogpost de realpython.com que está genial.

Aunque no uses Emacs ni te guste, te recomiendo pegarle una mirada a ese post de Real Python ya que te puede dar algunas ideas.

Mucho de lo que cuentan ahí yo ya lo tenía configurado, pero a lo bestia: utilizando hooks y cosas raras para que funcionen y -como no sabía casi nada de elisp, estaba todo atado con alambre y a veces crasheaba como loco. No hay nada peor que estar codeando esa idea que te llevó días poder llegar a tener y que no te funcione tu editor de código como vos querés. En esos momentos, iba deshabilitando los diferentes plugins y así me fui quedando con muy pocos.

Hotkeys

Emacs es un mundo, posta. No estoy seguro si estos hotkeys son específicos de elpy, pero son los que me llamaron la atención y que voy a empezar a usar:

M-down:
M-up: desplaza la región seleccionada una línea hacia arriba o hacia abajo
M-left:
M-right: deplazan la región seleccionada un nivel en la identación hacia la izquierda o la derecha
M-z <char>: borra hasta la primera aparición de <char>
C-c C-f: busca un archivo dentro del proyecto actual (lo adivina con heurística) utilizando un poco de fuzzy
C-c C-s: hace un grep -r en el proyecto actual con lo seleccionado
M-.: va hacia la definición de la función / método / clase sobre la que tenemos el cursor
M-*: vuelve a donde estábamos antes de presionar M-.
C-c C-z: abre un intérprete de Python en un buffer o bien recupera el existente
C-c C-c: manda el buffer actual al intérprete de Python para que lo ejecute
C-c C-d: abre la documentación de Python de la función / método / clase sobre la que tenemos posicionado el cursor
C-c C-t: ejecuta los tests del proyecto
C-c C-r f: formatea el código utilizando yapf o autopep8
C-c C-r i: autoimporta módulos que falten y ordena los que ya están importados

Conclusión

Hay mucha información sobre cómo instalar estas cosas, blog posts y documentación oficial. Yo tengo hecho algo que no recomiendo porque es oldschool y ahora es mucho mejor utilizar paquetes de META.

Les recomiendo que cada tanto le peguen una mirada a la configuración que tienen de su editor de código y vean configuraciones de otros, pero no las copien así nomás, ya que de esa forma van a tener un montón de cosas configuradas que no van a saber usar. Sino que la idea es ir configurando de a poco las cosas que vamos viendo interesante y tratar de sacarle el jugo.

Mi configuración de emacs

Tengo un repositorio en Github con toda la configuración de mi emacs, por si te interesa ver algo en particular: https://github.com/humitos/emacs-configuration

Manuel Kaufmann (Humitos): Aplicando rock a mi Emacs

Hace tiempo que uso Emacs. Hace no tanto tiempo que lo tengo configurado como me gusta y eso es porque nunca entendí la lógica de elisp, que es lo que se necesita saber para poder configurar algunas variables y hacer unos hook. Sin embargo, con el tiempo le fui agarrando la mano y fui pudiendo instalar a mano un montón de plugins que cada tanto, los actualizaba y alguno de ellos explotaba. Por eso, con el tiempo, se me fueron pasando las ganas de ir buscando nuevas cosas para enchular mi emacs y me dedicaba a utilizarlo como lo había dejado hace algunos años (por lo menos 2).

Anoche me dije: "voy a volver a ver qué cosas nuevas hay para Emacs y actualizar mi entorno de desarrollo". Así fue que llegué a elpy y a un blogpost de realpython.com que está genial.

Aunque no uses Emacs ni te guste, te recomiendo pegarle una mirada a ese post de Real Python ya que te puede dar algunas ideas.

Mucho de lo que cuentan ahí yo ya lo tenía configurado, pero a lo bestia: utilizando hooks y cosas raras para que funcionen y -como no sabía casi nada de elisp, estaba todo atado con alambre y a veces crasheaba como loco. No hay nada peor que estar codeando esa idea que te llevó días poder llegar a tener y que no te funcione tu editor de código como vos querés. En esos momentos, iba deshabilitando los diferentes plugins y así me fui quedando con muy pocos.

Hotkeys

Emacs es un mundo, posta. No estoy seguro si estos hotkeys son específicos de elpy, pero son los que me llamaron la atención y que voy a empezar a usar:

M-down:
M-up: desplaza la región seleccionada una línea hacia arriba o hacia abajo
M-left:
M-right: deplazan la región seleccionada un nivel en la identación hacia la izquierda o la derecha
M-z <char>: borra hasta la primera aparición de <char>
C-c C-f: busca un archivo dentro del proyecto actual (lo adivina con heurística) utilizando un poco de fuzzy
C-c C-s: hace un grep -r en el proyecto actual con lo seleccionado
M-.: va hacia la definición de la función / método / clase sobre la que tenemos el cursor
M-*: vuelve a donde estábamos antes de presionar M-.
C-c C-z: abre un intérprete de Python en un buffer o bien recupera el existente
C-c C-c: manda el buffer actual al intérprete de Python para que lo ejecute
C-c C-d: abre la documentación de Python de la función / método / clase sobre la que tenemos posicionado el cursor
C-c C-t: ejecuta los tests del proyecto
C-c C-r f: formatea el código utilizando yapf o autopep8
C-c C-r i: autoimporta módulos que falten y ordena los que ya están importados

Conclusión

Hay mucha información sobre cómo instalar estas cosas, blog posts y documentación oficial. Yo tengo hecho algo que no recomiendo porque es oldschool y ahora es mucho mejor utilizar paquetes de META.

Les recomiendo que cada tanto le peguen una mirada a la configuración que tienen de su editor de código y vean configuraciones de otros, pero no las copien así nomás, ya que de esa forma van a tener un montón de cosas configuradas que no van a saber usar. Sino que la idea es ir configurando de a poco las cosas que vamos viendo interesante y tratar de sacarle el jugo.

Mi configuración de emacs

Tengo un repositorio en Github con toda la configuración de mi emacs, por si te interesa ver algo en particular: https://github.com/humitos/emacs-configuration

Manuel Kaufmann (Humitos): Audio en RaspberryPi

La RaspberryPi se convirtió en esa cosa super poderosa que está prendida todo el tiempo y que brinda un montón de servicios. Sí, ¿para qué tener prendida mi notebook para ver un video? Para eso está kodi. ¿Para qué voy a tener un router y configurarlo extensivamente y así y todo que no sirva todo lo que quiero? Para eso está pyfispot. Y, finalmente, ¿para qué voy a tener la pc prendida solo para escuchar música? Para eso está mplayer y mps-youtube.

IMG_20160208_144255.thumbnail.jpg

La RaspberryPi colgada, como siempre...

Cuando utilizo kodi siempre lo hago conectado a un TV con entrada de HDMI, así el video y el audio se configuran solo sin ningún problema. Luego manejo todo desde el celular con yatse. Sin embargo, a veces -como ahora- no tenemos un televisor pero sí queremos escuchar música como si estuviésemos con kodi: nuestras notebooks apagadas pero la raspi reproduciendo música. Ok, instalé mplayer para eso y pude reproducir la música que tengo localmente en la raspi sin problemas. Lo único que tuve que hacer fue decirle a la raspi que quiero utilizar el Audio Jack Analógico y no el HDMI:

sudo amixer cset numid=3 1

Luego le doy permisos para usar el audio a mi usuario:

sudo usermod -G audio -a alarm

Sin embargo, como dije antes, esto me permite escuchar sólo la música que tengo localmente y con kodi nosotros escuchábamos música de YouTube también. Ahí es que llegué a mps-youtube, lo instalé y ya lo estoy usando:

~/fades/bin/fades -d mps-youtube -x mpsyt

No hace falta que diga nada más. Es muy fácil de usar y tiene una ayuda integrada.

Versión obsoleta en Ubuntu 14.04

Si estás utilizando la versión LTS de Ubuntu, es probable que tengas una version obsoleta de mplayer, por lo que debes actualizarla. Sin embargo, en mi máquina no actualiza a una versión capaz de funciona correctamente con mpsyt por lo tanto instalé mpv y lo configué en mpsyt con este comando:

set player mpv

Manuel Kaufmann (Humitos): Audio en RaspberryPi

La RaspberryPi se convirtió en esa cosa super poderosa que está prendida todo el tiempo y que brinda un montón de servicios. Sí, ¿para qué tener prendida mi notebook para ver un video? Para eso está kodi. ¿Para qué voy a tener un router y configurarlo extensivamente y así y todo que no sirva todo lo que quiero? Para eso está pyfispot. Y, finalmente, ¿para qué voy a tener la pc prendida solo para escuchar música? Para eso está mplayer y mps-youtube.

IMG_20160208_144255.thumbnail.jpg

La RaspberryPi colgada, como siempre...

Cuando utilizo kodi siempre lo hago conectado a un TV con entrada de HDMI, así el video y el audio se configuran solo sin ningún problema. Luego manejo todo desde el celular con yatse. Sin embargo, a veces -como ahora- no tenemos un televisor pero sí queremos escuchar música como si estuviésemos con kodi: nuestras notebooks apagadas pero la raspi reproduciendo música. Ok, instalé mplayer para eso y pude reproducir la música que tengo localmente en la raspi sin problemas. Lo único que tuve que hacer fue decirle a la raspi que quiero utilizar el Audio Jack Analógico y no el HDMI:

sudo amixer cset numid=3 1

Luego le doy permisos para usar el audio a mi usuario:

sudo usermod -G audio -a alarm

Sin embargo, como dije antes, esto me permite escuchar sólo la música que tengo localmente y con kodi nosotros escuchábamos música de YouTube también. Ahí es que llegué a mps-youtube, lo instalé y ya lo estoy usando:

~/fades/bin/fades -d mps-youtube -x mpsyt

No hace falta que diga nada más. Es muy fácil de usar y tiene una ayuda integrada.

Versión obsoleta en Ubuntu 14.04

Si estás utilizando la versión LTS de Ubuntu, es probable que tengas una version obsoleta de mplayer, por lo que debes actualizarla. Sin embargo, en mi máquina no actualiza a una versión capaz de funciona correctamente con mpsyt por lo tanto instalé mpv y lo configué en mpsyt con este comando:

set player mpv

Juanjo Conti: Goodreads review: Ladrilleros (Selva Almada)

Es un libro que se termina rápido. No solo es ágil en su escritura (lectura?) sino que invita a seguir leyendo, uno quiere saber qué mas pasa. ¡Pero cuidado! Hay una trampa, los capítulos no siguen un orden cronológico por lo que si quedamos enganchados con el final de uno, tal vez poco pague leer el siguiente :)

La contratapa no da pistas de la trama, aunque en varios artículos o reseñas lo vi promocionado como (música de telenovela paraguaya): "Una historia de amor homosexual en una sociedad bastante machista" (?). Para mí, esa historia no fue la central: la novela narra la historia de años de la pelea entre dos padres de familia, ladrilleros, en un pueblito del norte. Pinta sus costumbres, su naturaleza, sus rituales. La enemistad la heredan dos de los hijos, aunque para otro par acontece todo lo contrario.

Creo que hubiese preferido otro final, pero eso ya es problema mío.

Rating: 4/5

Original: https://www.goodreads.com/review/show/1538185454

Juanjo Conti: Agroecología

La Agroecología plantea que la mejor opción es compartir la tierra con la naturaleza ya que la aseveración de los bajos rendimientos por parte de la mirada convencional está basado en un cultivo y no tiene en cuenta que los sistemas agroecológicos producen gran diversidad de productos y servicios ecosistémicos además de poder mantener la biodiversidad y la resiliencia de los ecosistemas.

Manuel Kaufmann (Humitos): pilas-engine: curso colaborativo

En Santa Cruz, Bolivia empecé a pensar en una idea de hacer un curso/workshop de pilas-engine colaborativo. Sí, una especie de taller como los de Django Girls que venimos haciendo, pero en el que desarrollemos un juego entre todos.

Lo que me gustaría trabajar acá es el concepto de auto-aprendizaje, trabajo en equipo y organización de un proyecto. La idea para lograr esto sería realizar un taller de un día entero de duración donde empezamos presentando pilas-engine y sus conceptos básicos, hablamos un poco de Trello para gestionar las tareas que discutiremos entre todos y finalmente github para compartir nuestro código con los demás.

Los asistentes trabajarían en pequeños grupos (estratégicamente seleccionados) en las tareas que les correspondan, teniendo en cuenta que todos estamos haciendo el mismo juego y no que cada grupo está haciendo el suyo. Lo importante de esto es que luego debemos juntar el código de todos los grupos y poder jugar todos juntos (de modo multijugador) al mismo juego que escribimos entre todos.

Como todo, esa es la idea inicial, luego habrá que ir puliéndola para que quede algo realmente hacible.

Entonces, lo primero que me puse a investigar era qué juego podíamos implementar entre todos. De nuevo, teniendo en mente que debemos programarlo en un sólo día. Ahí encontré Circle Game, que cumple con casi todas mis necesidades.

circle-game.thumbnail.jpg

Circle Game

Este juego es una versión circular de la viborita, en donde uno es un círculo y solo puede comer círculos más pequeños que uno mismo. Cada vez que come un círculo, crece un poquito más. Si un círculo más grande te toca, perdiste.

El problema es que necesitaba una forma de hacer que eso sea multijugador y que todos puedan jugar sin depender de la máquina que tengan o incluso de que tengan computadora. Es probable que haya personas que asistan sin computadoras y trabajen juntos con otros. Creo que hasta 1 computadora por grupo de 3 personas sería suficiente, e incluso, interesante para poner en práctica.

Empecé a pensar que deberían poder jugar con su tablet, smartphone o computadora. ¿Qué tienen todas esas cosas en común? ¡Un browser! La solución tenía que venir por ese lado entonces.

Empecé a buscar cosas y caí en este artículo sobre Touch Events en Javascript. Luego para conectar esos eventos con algún servidor pequeño en Flask pensé en utilizar WebSockets y llegué a jquery-websockets.

Lo único que me faltaba era comunicar nuestro servidor Flask que estaba recibiendo toda la información de la posición del jugador con el jugador en sí que iba a estar siendo renderizado por pilas-engine. Y aquí es donde más problemas tuve y creo que la solución que encontré no es del todo buena -aunque funciona-: Redis. Básicamente tengo una cola donde el server Flask carga los datos de las posiciones y el método actualizar(self), del actor que quiero mover desde pilas-engine, va tomando los valores en orden cada vez que se llama.

De esa forma logré mover el Mono que está en la pantalla de pilas-engine utilizando un teléfono SmartPhone sin grandes prestaciones con un browser cualquiera.

El código que realiza toda esta magia está en un repositorio de GitHub: humitos/ballsgame.

Ahora me queda probarlo un poco más, ver como se comporta con 10~15 usuarios e ir pensando en cambiar Redis por algo que haga esa comunicación de una forma mas rápida. ¿Tienen alguna sugerencia?

Manuel Kaufmann (Humitos): pilas-engine: curso colaborativo

En Santa Cruz, Bolivia empecé a pensar en una idea de hacer un curso/workshop de pilas-engine colaborativo. Sí, una especie de taller como los de Django Girls que venimos haciendo, pero en el que desarrollemos un juego entre todos.

Lo que me gustaría trabajar acá es el concepto de auto-aprendizaje, trabajo en equipo y organización de un proyecto. La idea para lograr esto sería realizar un taller de un día entero de duración donde empezamos presentando pilas-engine y sus conceptos básicos, hablamos un poco de Trello para gestionar las tareas que discutiremos entre todos y finalmente github para compartir nuestro código con los demás.

Los asistentes trabajarían en pequeños grupos (estratégicamente seleccionados) en las tareas que les correspondan, teniendo en cuenta que todos estamos haciendo el mismo juego y no que cada grupo está haciendo el suyo. Lo importante de esto es que luego debemos juntar el código de todos los grupos y poder jugar todos juntos (de modo multijugador) al mismo juego que escribimos entre todos.

Como todo, esa es la idea inicial, luego habrá que ir puliéndola para que quede algo realmente hacible.

Entonces, lo primero que me puse a investigar era qué juego podíamos implementar entre todos. De nuevo, teniendo en mente que debemos programarlo en un sólo día. Ahí encontré Circle Game, que cumple con casi todas mis necesidades.

circle-game.thumbnail.jpg

Circle Game

Este juego es una versión circular de la viborita, en donde uno es un círculo y solo puede comer círculos más pequeños que uno mismo. Cada vez que come un círculo, crece un poquito más. Si un círculo más grande te toca, perdiste.

El problema es que necesitaba una forma de hacer que eso sea multijugador y que todos puedan jugar sin depender de la máquina que tengan o incluso de que tengan computadora. Es probable que haya personas que asistan sin computadoras y trabajen juntos con otros. Creo que hasta 1 computadora por grupo de 3 personas sería suficiente, e incluso, interesante para poner en práctica.

Empecé a pensar que deberían poder jugar con su tablet, smartphone o computadora. ¿Qué tienen todas esas cosas en común? ¡Un browser! La solución tenía que venir por ese lado entonces.

Empecé a buscar cosas y caí en este artículo sobre Touch Events en Javascript. Luego para conectar esos eventos con algún servidor pequeño en Flask pensé en utilizar WebSockets y llegué a jquery-websockets.

Lo único que me faltaba era comunicar nuestro servidor Flask que estaba recibiendo toda la información de la posición del jugador con el jugador en sí que iba a estar siendo renderizado por pilas-engine. Y aquí es donde más problemas tuve y creo que la solución que encontré no es del todo buena -aunque funciona-: Redis. Básicamente tengo una cola donde el server Flask carga los datos de las posiciones y el método actualizar(self), del actor que quiero mover desde pilas-engine, va tomando los valores en orden cada vez que se llama.

De esa forma logré mover el Mono que está en la pantalla de pilas-engine utilizando un teléfono SmartPhone sin grandes prestaciones con un browser cualquiera.

El código que realiza toda esta magia está en un repositorio de GitHub: humitos/ballsgame.

Ahora me queda probarlo un poco más, ver como se comporta con 10~15 usuarios e ir pensando en cambiar Redis por algo que haga esa comunicación de una forma mas rápida. ¿Tienen alguna sugerencia?