2014-12-16

Manejando errores de S3 en boto

Update: No sé porqué, después de usar la solución que puse acá sigo viendo errores de reseteo de conexión (error: [Errno 104] Connection reset by peer)

Estoy manejando archivos grandes (1 GB) en S3 con boto y, aún cuando estoy corriendo en una instancia en EC2, da errores. Si no entendí mal el código de boto, es porque hay algunas excepciones que da en las conexiones que no está reintentando.

Para entrar en el código de retries de boto con estas excepciones hay que registrarlas, al menos en boto 2.20.1.

Para eso, cuando me conecto a S3 hago:

import boto
import httplib
import socket
import ssl

s3 = boto.connect_s3(
    
    settings.s3_access_key_id,
    settings.s3_secret_access_key,
    https_connection_factory=(httplib.HTTPSConnection, (
        ssl.SSLError, socket.error
    ))
)

Eso evita los errores que estoy viendo (error: [Errno 104] Connection reset by peer y SSLError: The read operation timed out).

Espero que les sirva,
Aureliano.

2014-12-04

Mejorando el mirroring

Hace un tiempito hice un post sobre lo que estoy haciendo para sincronizar directorios con rsync en instancias de EC2. Esto funcionó muy bien para directorios chiquitos, pero cuando tenés más de 100 megas y más de 1400 archivos cada iteración se hace un poco lenta y usa mucho bandwidth. Y no creo que Fibertel esté muy contento con eso.

Así que estuve buscando alguna versión que detecte los cambios que se hacen en los archivos, para no estar mirando todo todo el tiempo. Y lo encontré :D. Existe una cosa que se llama lsyncd, que hace eso :D. Si estás en ubuntu, para instalarlo solo hay que hacer sudo apt-get install lsyncd. Y con eso hice un scriptcito que busca el nombre de la instancia de EC2 con la que me interesa sincronizar y lo usa para mantenerlo sincronizado.

#!/usr/bin/env python

import subprocess
import sys
import time
import boto
import getpass
import tempfile

AKI = "AKIVAUNACCESSKEYID"
USER = "unusername"
INAME = "NOMBRE DE LA INSTANCIA"
TARGET = "DIRECTORIO EN EL TARGET"
SOURCE = "."

CONF_TEMPLATE="""\n
settings {
  logfile = "lsyncd.log",
  statusFile = "lsyncd.status",
  nodaemon = true,
  statusInterval = 2,
  maxProcesses = 8,
}

sync {
  default.rsyncssh,
  source=".",
  host='%(host)s',
  targetdir='%(targetdir)s',
  exclude={
    "*.pyc",
    "*.log",
    "*.swp",
    "*.status",
    "*/.hg/*",

  },
  delay=2,
}
"""

def main():
    sak = getpass.getpass("Enter secret access key:")
    ec2 = boto.connect_ec2( AKI, sak )
    dns_name = ec2.get_only_instances(filters={"tag:Name":INAME})[0].dns_name
    host = USER + "@" + dns_name
    targetdir = TARGET   
    with tempfile.NamedTemporaryFile() as t:
        print CONF_TEMPLATE % locals()
        t.write(CONF_TEMPLATE % locals())
        t.flush()
        subprocess.check_call("lsyncd -nodaemon -log Exec".split(" ") + [t.name])

if __name__ == '__main__':
    main()


Happy hacking,
Aureliano

2014-11-23

Cómo hablar en portugués, mal

Update: Agregué regla para 'c' al final de una sílaba en el medio de una palabra.

Hace muchos años hice software para Brasil. Parte de ese desarrollo requirió que pueda hablar con much@s brasileñ@s. Acá les cuento algunos truquitos que hacen mucho más fácil la comunicación.

Aprendé algunas palabras

Sabiendo 50 (o 10) palabras en portugués podés avanzar un montón. Y lo más probable es que algunas ya las conozcas. Te cuento alguna que me acuerdo:
  • obrigado: gracias
  • eu: yo
  • você: vos
  • a gente: nosotros
  • loja: negocio
  • eu te quero: te quiero cojer
  • ficar: estar/ quedarse en
  • batata: papa
  • frango: pollo

Imitá la tonada

Aunque suene increíble, solo imitando la tonada brasileña te entienden mucho más. Para eso podés tener en cuenta algunas cosas:
  • Las "h" al principio generalmente se transforman en "f". Por ejemplo "hacer" es "facer"
  • Las "j" se suelen pronunciar como "ll" (no como yé). Por ejemplo, "muller" (mujer) y "ollos" (ojos)
  • Muchas palabras que terminan en consonante se les agrega una "i" al final. Por ejemplo, Varig se pronuncia "Varigi"
  • Si hay una "c" al final de una sílaba en el medio de la palabra, sacala. Por ejemplo, "correto" (correcto) y "perfeto" (perfecto). En realidad se dice "perfeito", pero solo aplicar la regla nos acerca. 
No hace falta que imites la tonada bien para que sirva para comunicarse. 

Usá palabras largas

Las palabras de 4 o más sílabas casi siempre se corresponden con las palabras en portugués, solo teniendo que cambiar un poquito la pronunciación haciendo las cosas de las que hablé en el punto de arriba. También tienen la ventaja de que al ser muy largas, si pronunciás mal una parte te entiendan igual.

Olvidate de las conjugaciones de los verbos

Las conjugaciones de los verbos son distintas en castellano y portugués y siempre van a salir mal. No te preocupes por eso.

No tengas miedo

Si tratás de hablar en portugués siguiendo estas reglas no vas a estar hablando correctamente. Eso, en mi experiencia, no importa. Es más, se dan cuenta que estás haciendo un esfuerzo para comunicarte con ell@s. Y eso hace que muchas veces estén dispuest@s a hacer lo mismo y tratar de ayudarte en la conversación. Aparte l@s brasileñ@s se caracterizan por la buena onda.

Éxitos,
Aureliano.

2014-11-22

Projecto de ejemplo de sandro

Acabo de hacer público el projecto taleca. Ahí uso sandro para hacer una visualización de algunos datos que se usaron en el Hackatón de agro de la Fundación Sadosky. Es un ejemplo simple pero muestra cómo usar el general update pattern para hacer una visualización de d3 en sandro.

Te propongo que saquemos a sandro de las penumbras,
Aureliano.

2014-11-21

Datos de Fibertel

Hola,

Recientemente instalé Fibertel 6 megas en mi hogar. Acá les dejo algunas cosas que hubiera querido saber y que no me contaron.

  • Para ver la calidad de la conexión tienen que conectarse a http://provisioning.fibertel.com.ar/asp/nivelesPrima.asp. Los valores que tienen que mirar son Tx, Rx y Mer. Tx tiene que estar entre 30 y 50 dB (40 es lo mejor), Rx tiene que estar entre -10 y 10 dB (0 es lo mejor) y Mer tiene que ser mayor a 30 dB (los rangos los saqué de este post de Taringa).
  • Tengo un MODEM Arris Touchstone, para mirar/tocar la configuración me conecté con mi navegador a http://192.168.0.1 y me loguié con usuario "admin" y password "motorola". Raro, pero funcó, ¿me estaré conectando al MODEM del vecino?
Update: Me traté de conectar de nuevo a http://192.168.0.1 y no anda. Le tiré un nmap y tiene todos los puertos cerrados, aparentemente lo abren y cierran cuando hay técnicos trabajando en tu casa desde la central. El primer link sí anda.

Espero que les sirva,
Aureliano.

2014-11-14

Discriminación de género hacia los hombres en la Argentina

El discurso de violencia de género centrado en la violencia ejercida por los hombres hacia las mujeres, ignorando completamente la violencia que va para el otro lado, es violencia de género. Acá muestro algunas cosas en las que los hombres somos discriminados, y respaldado por estadísticas oficiales (ver los links para más detalles):

  • Expectativa de vida en Argentina (fuente): 
    • Hombres: 72,44 años
    • Mujeres: 79,76 años
  • Edad jubilatoria en Argentina:
    • Hombres: 65 años
    • Mujeres: 60 años
  • Población carcelaria en Argentina (fuente):
    • Hombres: 92%
    • Mujeres: 8%
  • Secretarías en Argentina:
    • del Hombre: no
    • de la Mujer: sí
  • Licencia por descendencia en la Argentina, incluye adopciones (fuente):
    • Mujeres: 12 semanas
    • Hombres: 2 días
  • Tenencia de l@s hij@s en la Argentina:
    • Queda con la madre 9 de cada 10 veces (fuente)
    • Esto es abusado sistemáticamente y ese abuso es escondido por el poder judicial (fuente)
  • Víctimas de asesinatos (fuente):
    • Hombres: 90%
    • Mujeres: 10%
¿Siguen pensando que el género discriminado en la sociedad es el femenino?
¿Por qué?

Aureliano.

PD: No estoy diciendo que esté bien la violencia en contra de las mujeres, digo que está mal la violencia en contra de los hombres.

2014-11-13

Dependencias con nombre en sandro

En requirejs cuando un módulo tiene muchas dependencias a veces se complica saber qué variable corresponde a qué módulo. Para simplificar esto, ahora en sandro se pueden definir módulos así:

define({name1:"./dependency1", name2: "app/dependency2"}, function(m) {
   // m.name1 refers to ./dependency1 and m.name2 refers to app/dependency2
})

Podés usarlo en define y require, tanto en el cliente como el server.
Happy hacking,
Aureliano.

2014-11-11

mosh en AWS

Acabo de instanciar una VM en EC2, usando la AMI estándar de Ubuntu-Server de 64bits. Hago
$ sudo apt-get install mosh
en un shell de la nueva instancia (por ssh) pero no me puedo conectar usando mosh. ¿Por qué? Tengo algún quilombo con los locales
The locale requested by LANG=en_US.UTF-8 isn't available here.
Running `locale-gen en_US.UTF-8' may be necessary.
¿Cómo lo arreglo? Siguiendo las instrucciones de acá, genero los 2 locales que necesito y los registro:
$ sudo locale-gen en_US.UTF-8
$ sudo locale-gen es_AR.UTF-8
$ sudo dpkg-reconfigure locales
Y ahora me puedo conectar :D.

Happy hacking,
Aureliano.

2014-11-10

Mi propia autoridad certificante y mi ELB

En esta respuesta de StackOverflow dice como armar tu propia autoridad certificante en 1 minuto, y en esta página cómo darle a AWS las cosas que necesita para setupear un load-balancer con SSL. Entre esas 2 cosas es fácil armar tu propia página que use tu autoridad certificante. Es medio difícil convencer a la gente que hace los browsers de que te acepte, pero probablemente sirva para intranets o aplicaciones que se conecten a la nube.
Happy hacking,
Aureliano.

2014-11-06

Utilidades para d3 en sandro

Estoy trabajando en sandro, y surgen cosas interesantes. Ahora empecé a hacer utilidades para d3. Lo más interesante es que hice un método que encapsula y da entidad al General Update Pattern de d3 e hice que los nodos updateados tengan que sí o sí ser hijos del nodo referenciado (en vez de cualquier descendiente), para evitar un montón de bugs que se dan eligiendo nodos.

Para usarlo en sandro es así:
define(["sandro/nadaMas/d3", function(d3h) {
  // Acá hay código tuyo, que hace aSelection
  aSelection.call( d3h.gupChildren, {
    tag: "line", // nombre del tag de la entidad a insertar (obligatorio)
    klass: "aClass", // nombre de la clase de las entidades insertadas (optional, sin clase si no está escrita)
    values: [1,2,3,4], // datos para la visualización (función o array, igual que en d3)
    key: function(d,i) {.....}, // key para los datos, opcional. Funciona igual que en d3
    onEnter: function(s, defaultOnEnter) {....}, // acciones a tomar con la selección de los nodos nuevos. Opcional. Si no es seteada solo hace append de los nodos y les setea la clase si querés hacer eso y algo más defaultOnEnter(s) hace eso y devuelve la selección para seguir operando.
    onUpdate: function(s, defaultOnUpdate) {.....}, // acciones a tomar sobre la selección de los nodos modificados (tanto agregados, como cambiados). Opcional.
    onExit: function(s, defaultOnExit) {.....}, // acciones a tomar con la selección de los nodos que no matchean con los nuevos datos. Opcional. Si no es seteada solo hace remove. Si querés hacer eso y algo más defaultOnExit(s) hace eso y devuelve la selección para seguir operando.
    onUpdateOld: function(s, defaultOnUpdateOld) {.....} // Igual que onUpdate pero solo aplica a los nodos viejos
  })
  // Y acá más código
}
Si quieren, pueden usar el código as-is si usan requirejs, o adaptarlo un toque y usarlo en el browser como más les plazca. Pero, si quieren usarlo en el server también, la mejor forma que conozco es que usen sandro.

Espero que les guste!

2014-11-01

Como lo hice yo

Estuve avanzando y empecé un módulo nuevo en sandro. Se llama comoLoHiceYo en honor a la canción de Sandro con el mismo nombre y tiene las configuraciones "opinionated" que hacen falta para unir cosas y que sea fácil compartir código entre cliente y server. Antes era posible, ahora es una pavada.
Éste es el código de una página de ejemplo que corre un pedacito en el cliente y otro en el server. Primero en el server, app/endpoint/clientCode.js es así:
define([], function() {
  return function(params) {
    var d3 = params.d3
    var startClientJs = params.startClientJs
   
    d3.select("body").append("div").text("Generated on the server")
    startClientJs("app/shared/clientCode")
  }
})

Y para el cliente está app/shared/clientCode.js:
define(["external/d3"], function(d3) {
  d3.select("body").append("div").text("Generated on the client")
})

Ya se empieza a ver que hay un montón de cosas que se pueden hacer en los dos lados. En este ejemplo, uso d3 tanto en el cliente como en el server para manipular el DOM.
¿Querés usar sandro? Decime y te ayudo.

2014-10-26

Novedades en sandro

Tengo varias novedades de sandro. La primera es que separé el desarrollo del site de la biblioteca. Para eso hice el proyecto sandro-lib, donde tiene el proyecto sandro y sus tests. Por lo tanto, el proyecto queda así:

  • sandro: Site principal. Corre los tests. En un futuro va a tener toda la documentación. Es el primer site hecho en sandro y siempre va a usar la última versión. Si tenés alguna duda sobre cómo hacer algo, podés mirar el código acá.
  • sandro-lib: Biblioteca de base para hacer sites con sandro
  • domino: Port del proyecto domino para correr en sandro
La segunda es que hice mi primer visualización en d3 corriendo en el server, como parte de las cosas que hice en el Hackaton de la fundación Sadosky sobre agro. Lo siento, no tengo commit de esto por ahora.

La tercera es que cambié la forma de exponer los scripts que se ejecutan en el cliente. Ahora hay una acción del módulo alFinal que expone los scripts, tomando por parámetro una función que decide si un módulo puede ser expuesto dado el nombre de su recurso. Acá el ejemplo de cómo anda:
      router = c.camino()
      router.register(c.prefixPath("/js"), alFinal.jsCode({
        published: function(resource) {
          resource = "" + resource
          return (
            resource.startsWith("/sandro/") ||
            resource.startsWith("/app/shared/") ||
            resource.startsWith("/external/")
          )
        },
        prefix: "/js"
      }))

Muchos avances en muy poco tiempo. Espero poder seguir así,
Aureliano

2014-10-24

Financiación de sandro

Como ya conté en este blog, hace un tiempo que estoy trabajando en hacer un framework para hacer páginas web que permita compartir fácilmente código entre cliente y server. A este trabajo lo denominé sandro, en analogía a los ya existentes sinatra y dyango.
Sandro, ya tiene bastante esfuerzo dedicado, pero necesita mucho más. Por lo tanto, está llegando el momento en que tengo que encontrar alternativas que me permitan financiar el proyecto, porque tengo que seguir comiendo pero quiero seguir haciendolo, y aparte en cualquier momento va a empezar a generar gastos (por ejemplo, hosting).
Estas son mis ideas, si se les ocurre algo más soy todo oídos:

  • Donaciones
    • gratipay
    • vía Paypal
    • ¿se les ocurren otros mecanismos fáciles de implementar?
  • Features requests/bug fixes con recompensa o donación.
    • Estos tendrían prioridad ("put your money where your mouth is")
  • Consultoría, capacitación, etc sobre sandro
    • Incluye dar cursos, desarrollar sites, dar charlas.
  • Libro sobre sandro (¿alguien gana plata escribiendo un libro sobre su propio proyecto?)
  • Venta de discos/canciones de sandro a través del site, cobrando una comisión.
    • Creo que Amazon, iTunes y MercadoLibre ofrecen algo así en sus programas de afiliados.
  • Inversión de venture capital en sandro
Si se les ocurre algo más, o quieren poner plata con alguno de los mecanismos arriba mencionados (o algún otro) no duden en escribir.

Happy hacking,
Aureliano.

2014-10-20

D3 en sandro

Basándome en la integración a sandro de domino, y el módulo comoTeDire, ¡hice andar d3 en el server en sandro! Con esto espero que podamos generar SVGs y visualizaciones indistintamente en cliente y server, y también quiero basar el sistema de templating de sandro en eso.
¿Alguien quiere financiar el proyecto? ¡Ya sandro hace cosas que ningún otro framework hace!

2014-10-17

Domino en sandro!

Acabo de hacer el primer POC de manejo del DOM en el server con el mismo API que en el cliente. Para eso, porté domino a mi sistema de módulos e hice un POC.
¡Esto está tomando forma! ¿Cuántos frameworks web hay que puedas hacer código de presentación que corra tanto en el cliente o en el server?

¿Quién quiere ser early adopter?

2014-10-15

Módulos AMD en sandro

Ayer implementé en sandro módulos AMD, como los de requirejs. Esto debería hacer más fácil el uso de bibliotecas que usen commonjs. Acá les dejo el changeset donde está la implementación (con tests!).

Happy hacking,
Aureliano.

Un buen regalo

Dentro de poco es mi cumpleaños, así que hay personas que están pensando en qué regalo hacerme (espero!). Para ayudar o quizás complicar a ell@s, voy a escribir lo que creo que es un buen regalo.
Un buen regalo es aquel que l@ agasajad@ no compra pero querría tener.
Esto tiene dos corolarios:

  • Generalmente un juguete es un buen regalo para un@ niñ@, ya que no tienen plata y generalmente les gustaría tener juguetes.
  • Salvo que seas millonari@, es muy raro que tu presupuesto para un regalo exceda la cantidad de plata que una persona adulta puede gastar en sí misma.
Entonces, ¿cómo se hace un buen regalo a un@ adult@? Encontrando algo que l@ agasajad@ querría tener pero no compraría. Voy a dar ejemplos:
  • Cosas que no se consiguen en la ciudad donde vive l@ agasajad@.
  • Cosas que es ilegal comprar.
  • Cosas que son imposibles de comprar.
  • Cosas que no se permite comprarse pero pensás que querría tener.
    • Incluye cosas que l@ agasajad@ dice que no quiere pero pensás que le gustaría hacer/tener.
  • Cosas que no conoce, pero vos sí, y que pensás que querría tener.
  • Cosas que vos sabés dónde comprar y l@ agasajad@ no.
Cosas es en sentido amplio, o sea, pueden ser también servicios y actividades. Por ejemplo, a una amiga le regalaron un día en un spa para su cumpleaños hace poco.
Estas reglas descartan rápidamente la mayoría de los libros y discos. En mi caso solo regalame uno de ellos solamente si pensás que me interesaría particularmente.

Y si no encontrás nada, un buen abrazo y un "feliz cumpleaños" es mucho mejor que un regalo de compromiso ;). Ya que es algo que no puedo comprar pero quiero tener.

¿Qué es un buen regalo para vos?

Abrazo,
Aureliano.

2014-09-24

Billetera, galán, pedazo

Rebranding del piedra, papel o tijera.

Hay 3 elecciones posibles: "billetera", "galán" o "pedazo".

Billetera mata galán.
Galán mata pedazo.
Pedazo mata billetera.

Igual que en el piedra papel o tijera, hay que hacer un gesto con la mano para simbolizar la elección

Billetera
Galán
Pedazo  
Mecánica de juego:
L@s dos jugador@s, simultáneamente, gritan "billetera, galán, pedazo" y justo cuando terminan de decirlo elijen una de las 3 opciones (igual que el "piedra, papel o tijera"). Gana l@ jugador@ que mata a l@ otr@, si elijen la misma opción es empate. Al igual que en el piedra papel o tijera, se puede jugar muchas veces seguidas.

Diviértanse,
Aureliano.

2014-09-21

Mejoras en sandro

Hice varias mejoras en sandro. Ahora se puede definir módulos que son endpoints y se cargan dinámicamente, definir rutas estáticas y ¡debuggear desde eclipse! Estos features llevaron sorprendentemente poco código.

Y ¡sigue pudiéndose compartir fácilmente código entre cliente y server! Ya está tomando forma y tiene cosas que no tienen la mayoría de los frameworks para hacer páginas web.

¿Cuándo hacés tu proyecto en sandro?,
Aureliano.

2014-09-18

Ssh port forwarding con reconexión automática

Ayer mostré cómo forwardear puertos usando ssh. Hoy lo mejoro. Usando autossh se mantiene el tunel levantado cuando la conexión de ssh se cae haciendo una nueva. Pueden correr en el shell así:

autossh -N -L bind_cliente:port_cliente:host_server:port_server usuario@host

Happy hacking, Aureliano.

Rsync iterado, integración con EC2

Ayer hice un script para coordinar directorios con rsync. Hoy lo integré con EC2, usando boto. Así no tengo que andar buscando el nombre de dns de la instancia cada vez. Cambien las constantes que aparecen arriba y úsenlo a piaccere. Para que sea usable tienen que poner la clave para loguearse en la instancia en su agente de SSH.

#!/usr/bin/env python

import subprocess
import sys
import time
import boto
import getpass

AKI = "AKIVAUNACCESSKEY"
USER = "ubuntu"
INAME = "INSTANCENAME"
TARGET = "TARGET_DIR"
SOURCE = "SOURCE_DIR"

def main():
    sak = getpass.getpass("Enter secret access key:")
    ec2 = boto.connect_ec2( AKI, sak )
    dns_name = ec2.get_only_instances(filters={"tag:Name":INAME})[0].dns_name
    while True:
        try:
            subprocess.check_call([
                "rsync",
                "-z",
                "-r",
                "--delete",
                "--exclude=*.pyc",
                "--exclude=*.log",
                SOURCE,
                "%s@%s:%s" % (USER, dns_name, TARGET)
            ])
            print ".",
            sys.stdout.flush()
            time.sleep(1)
        except subprocess.CalledProcessError, e:
            if e.returncode in [10,11,12,14,22,23,24,30,35]: # See http://wpkg.org/Rsync_exit_codes
                print "R",
                sys.stdout.flush()
            else:
                raise

if __name__ == '__main__':
    main()


Espero que les sirva,
Aureliano.

2014-09-17

Ssh port forwarding

Cada día que uso ssh me gusta más. Acá dejo anotado como forwardear un puerto al que me puedo conectar desde el server, para poder conectarme desde el cliente:

ssh -L bind_cliente:port_cliente:host_server:port_server usuario@host

Happy hacking,
Aureliano.

rsync iterado

Hice un scriptcito en python que corre rsync muchas veces para mantener actualizado un directorio. Lo pongo acá por si le sirve a alguien más (o a mi mismo más tarde).

#!/usr/bin/env python

import subprocess
import sys
import time

def main():
    while True:
        try:
            subprocess.check_call([
                "rsync",
                "-z",
                "-r",
                "--delete",
                "--exclude=*.pyc",
                "--exclude=*.log"
            ] + sys.argv[1:])
            print ".",
            sys.stdout.flush()
            time.sleep(1)
        except subprocess.CalledProcessError, e:
            if e.returncode in [10,11,12,14,22,23,24,30,35]: # See http://wpkg.org/Rsync_exit_codes
                print "R",
                sys.stdout.flush()
            else:
                raise

if __name__ == '__main__':
    main()


Happy hacking,
Aureliano.

2014-09-15

¿Por qué ignora esto?

Encontré la extensión hg-isignored que sirve para saber qué regla del .hgignore matchea con un archivo. Podés ver cómo configurarla en esta respuesta de StackOverflow.

Happy hacking,
Aureliano.

Colgadas de pydev

Pydev me colgaba el eclipse cuando abría un archivo con muchos errores. Para que no se cuelgue más tuve que editar el eclipse.ini y agregarle al final
-Djava.net.preferIPv4Stack=true
Más detalles en http://stackoverflow.com/questions/7463691/eclipse-pydev-completion-hangs-yet-again.

2014-09-13

Viejos nuevos proyectos

Estoy con ganas de encarar algún proyecto más o menos grande y tengo varias cosas en la cabeza, así que quería pedirles su opinión sobre qué piensan que estaría bueno hacer. Y si algun@ de ustedes tiene ganas, capacidad y tiempo de hacerlos conmigo, o tiene alguna idea que piense que estaría buena y quiera compartir, también estaría bueno. Las opciones que se me ocurren por ahora son:

  • Seguir con mi framework web homenaje a sandro.
  • Hacer un software para optimizar cortes de tela, haciendo una heurística para resolver 2D packing. La idea sería comercializarlo.
  • Aprender coreano, para poder leer un montón de cosas sobre como jugar al go. L@s mejores jugador@s y la mayoría de la bibliografía, son coreanos, chinos y japoneses. Y el coreano parece el lenguaje más fácil de los 3.
  • Hacer todos los cursos de Easy y dejar de ser un inútil para arreglar cosas en mi casa.
  • Seguir el desarrollo de mi notación de tango y hacer un animador en 3D de los pasos anotados.
Escucho ideas y busco compinches,
Aureliano.

2014-09-04

Manejando el output de Pulse Audio

Encontré cómo hacer para manejar de línea de comando a qué salida de audio (sink) va cada programa. Miren acá http://askubuntu.com/questions/71863/how-to-change-pulseaudio-sink-with-pacmd-set-default-sink-during-playback.

Happy hacking,
Aureliano.

2014-08-19

Mi opinión sobre poner ; por todos lados en JavaScript

var betterWithSemicolons = function() {
    return
        true;
}

alert( betterWithSemicolons() ? "it is better with semicolons" : "semicolons can be quite misleading. Only use with care!" )

Yo programo en inglés :p.

2014-07-28

Libs para python 64 bits en Windows

Laburar en Linux es fácil, pero cuándo querés programar en python en un Windows y usar toda la memoria se complica porque es difícil conseguir las libs empaquetadas para la plataforma. En esta página hay un montonazo de bibliotecas para python en 64 bits, que puede que les sirvan.


Happy hacking,
Aureliano.

2014-07-12

Maschefacts

Mascherano puede decir si cualquier programa termina o no

Mascherano resuelve el camino del viajante antes del almuerzo.
Mascherano encuentra la preimagen de un SHA-256.
Mascherano factoriza números primos y encuentra muchos factores.
Mascherano escribió todos los dígitos de pi.
Mascherano hackea a Bruce Schenier
Mascherano escribe GOTO y no lo consideran perjudicial.
Mascherano sabe el estado de un q-bit antes de que colapse.
Mascherano paseó por Königsberg, pasó una vez por cada puente y volvió al punto del que salió.
Mascherano hizo una máquina de estados que encuentra números primos.
Mascherano resolvio todos los problemas NP en O(1) (Éste es de Gabriel Benmergui)

2014-07-09

Restaurando el agua caliente

El lunes hubo una gran bajante en el Río de la Plata, que hizo que no haya presión de agua y se vaciara el tanque de mi casa. Cuando volvió el agua ayer a la noche, empezó a andar el agua fría, pero no el agua caliente. Mi diagnóstico fue que quedó alguna burbuja de aire en un codo de una cañería, así que llené las cañerías de agua caliente con agua fría. ¿Cómo hice eso? Fui al baño, abrí el agua caliente (no salió nada), tapé la canilla con la mano y abrí el agua fría. Eso hizo que circulara el agua fría para el otro lado. Estuve un minuto así y cerré todo. Abrí de nuevo el agua caliente, dejé circular un poco de agua y ¡empezó a salir el agua caliente! ¡Felicidad! Me puedo volver a bañar en mi casa.
Happy hacking,
Aureliano.

2014-07-07

Notación de tango. Objetivos

Recientemente, empecé la búsqueda de una o varias formas de anotar los pasos que bailamos en tango salón y sus danzas aledañas, milonga, vals y canyengue. Ahora quiero explicar cuáles son las ideas que tengo atrás de esto.
En primer lugar, yo creo que hay algo de cierto en la hipótesis de Sapir-Whorf, y creo que las cosas que podemos concebir están fuertemente limitadas por las cosas que podemos expresar en los lenguajes que manejamos. También creo que la notación musical es muestra de ello y hace que la música sea mucho más rica, inclusive cuando no se la usa directamente. Hace más de 10 años que estoy incluído en el mundo del tango y noto que no hay acuerdo sobre cómo nombrar las cosas que hacemos cuando bailamos. Esta fragmentación hace que no podamos compartir conocimientos eficientemente y, por lo tanto, no evolucionemos. Esto se nota particularmente cuando tomamos clases. Todo hay que mostrarlo y aprenderlo kineticamente. Las clases avanzadas solo tienen secuencias más largas pero, por no existir los elementos del lenguaje que lo permitan, no avanzan en otros aspectos del baile que quedan relegados a lo que la intuición de cada quién pueda hacer. El primer objetivo de la notación es dar un lenguaje que permita destrabar esto.
En segundo lugar, una notación sensata debería habilitar otras cosas. Si hubiera una notación buena y completa, sería posible hacer algo equivalente a un MIDI player de tango. Y mostrar animaciones de baile en 3D y con robots.
Una tercera cosa que se me ocurre es un sistema de reconocimiento de video en 3D que corrija los pasos de tango, como si fuera un@ profesor@ human@.
Happy hacking,
Aureliano.

2014-07-04

Complicando la notación de tango

Hace unos días propuse una notación de pasos de tango, que consiste en una partitura en clave de 2 en tercera línea y asignar notas a los cambios de peso que hacen los bailarines. Hoy voy a extender la notación, para anotar dirección de los pasos. Como necesito más notas, voy a desdoblar los pasos conductor y conducido, cada uno en su partitura como las partituras para piano. Respetando como anoté antes, arriba van los pasos del conductor y abajo los del conducido, y arriba van los cambios de peso con la pierna izquierda y abajo los cambios de peso con la pierna derecha. Esto, si se mantienen las costumbres heteronormativas de baile, le da la clave de sol al hombre y la clave de fa a la mujer; al revés de lo que pasa cuando se escriben partituras para el canto.
La línea central de cada pentagrama nunca se usa. El espacio inmediatamente arriba o abajo es un cambio de peso en el lugar, la siguiente línea representa un cambio de peso desplazándose hacia atrás, el espacio siguiente un cambio de peso hacia adelante y la línea de afuera es una apertura.
El pentagrama representa un balanceo en el lugar, pisando primero con la derecha, después 2 pasos para atrás, dos pasos para adelante y una apertura para cada lado. ¿Se animan a hacer esto manteniendo cerrado el abrazo?

Siguiendo la tradición del post anterior, voy a poner en esta notación extendida el básico. Noten que sigo sin mostrar el cruce de la mujer en el paso 5.
Y acá está en esta notación el básico cruzado con contratiempo. También se nota que toma un compás menos.

En otros posts espero seguir desarrollando la notación del baile del tango.

Me voy a ver el mundial,
Aureliano.

2014-07-02

Post 256

Cuando empecé con este blog en agosto del 2006, nunca pensé que iba a escribir tantas cosas ni que iba a mantener la constancia de escribir acá por tanto tiempo. Mirando estos casi 8 años en retrospectiva, muchas cosas cambiaron, pero sigo disfrutando escribir por acá.Escribir cosas acá también me trajo algunas satisfacciones inesperadas. La más grosa creo que fue reencontrarme con mis compañer@s de la escuela primaria, ¡que encontraron este blog googleandome!
Desde que empecé a chequear tráfico en Google Analytics hubo 39,672 sesiones, con una mediana de aproximadamente 500 por mes y un pico en febrero de 2010 de 1855. Es un número extraño. Es muchísimo para ser muy poco y muy poco para ser muchísimo.
Una de las cosas que más me gusta de mirar las estadísticas del blog es mirar de dónde se conectan. Por supuesto que mi principal audiencia está en Argentina (más del 40% de las sesiones). Pero a veces aparece gente de lugares extraños como Corea, Mozambique o Nueva Caledonia. ¡Tengo visitas desde todos los continentes salvo Antártida!
Otra cosa que me gusta de este blog es que si quiero hacer una publicación, lo ve mucha más gente que si publicara en una revista especializada o los proceedings de una conferencia.
En definitiva, estoy muy contento de haber tenido la constancia de haber llegado hasta acá y ¡ojalá nos leamos en el post 65536!
Happy hacking,
Aureliano.

2014-06-30

Pensando una notación para el tango

La música tiene una forma de anotarse, con partituras, que hace más fácil pensar sobre ella, aprender y autocorregirse. Lamentablemente no conozco nada parecido para el mundo del tango, aunque en la danza en general algo existe.
Hace años que vengo pensando en cómo hacer para tener las ventajas de una partitura. Mi idea es tratar de adaptar las partituras para anotar pasos. Hacer esto tiene como ventaja que una parte del esfuerzo de notación, la rítmica, ya viene resuelto.
Lo que propongo es anotar los pasos armando una clave de do en tercera línea. La mitad de arriba del pentagrama representa los pies del conductor y la mitad de abajo los pies del conducido. En particular, fa es el pie izquierdo del conductor, re es el pie derecho del conductor, si es el pie izquierdo del conducido y sol el pie derecho del conducido. Para acordarse, imagen una pareja tomada por el lado cerrado del abrazo de tango, pero un al lado del otro, caminando por los espacios que quedan entre las líneas del pentagrama.
Si alguna de esas notas está presente, quiere decir que ese pie tiene peso en el piso durante el tiempo de la nota.
Por ejemplo, así se representa la pareja parada sobre ambos pies durante un compás (en un tango en 2x4):

Teniendo esto, podemos empezar a anotar cosas como el básico. Solo están los cambios de peso, no hay cambios de dirección ni el cruce del conducido en el paso 5:
O el básico con base cruzada. Noten como se toma un compás menos por los contratiempos en los compases 2 y 4.
En futuros posts voy a ir desarrollando la notación, siguiendo otros movimientos comunes en el tango salón. Mientras tanto espero ideas y críticas constructivas.

Nos vemos en la milonga y happy hacking,
Aureliano.

2014-06-19

TDA en VLC

Como puse en este post, me compré una sintonizadora de tele digital (TDA). El programa que viene con la placa para ver la tele es una bosta. Así que me las arreglé para mirar usando VLC, basándome en esto. Para hacerles la vida fácil, armé el archivo que hace falta. Bájenselo y ábranlo con el VLC.

Feliz mundial,
Aureliano.

2014-06-12

Lockeando LXDE

Recién me instalé un LXDE para usarlo como manejador de ventanas en un Ubuntu 14.04, y una de las cosas que le faltaba es la posibilidad de lockear la terminal con una combinación de teclas. Googleando un toque encontré esta pregunta donde explican como hacerlo para Lubuntu, así que básandome en eso inferí cómo hacer lo mismo en LXDE y parece que le pegué. Lo dejo acá por si me olvido o alguien necesita hacerlo.
Para hacer que la combinación de teclas lockee el desktop, hay que editar el archivo .config/openbox/lxde-rc.xml y agregarle, dentro del tag keyboard, lo siguiente:

  <keybind key="W-l">
     <action name="Execute">
       <command>xscreensaver-command -lock</command>
     </action>
  </keybind>



Una vez esto hecho, te deslogueás y relogueas y listo el pollo.
Happy hacking,
Aureliano

2014-06-10

Conectandome a mi VM nateada

Para laburar, me gusta tener los ambientes de los proyectos en los que laburo separados en VMs. Eso hace que pueda desarrollar simultáneamente proyectos con requerimientos incompatibles (un caso clásico es ver una versión vieja del mismo proyecto). Setupear todo suele no ser fácil. En particular, manejar el networking entre host y guest puede ser complicado. Por default, en VirtualBox, no es posible conectarse por tcp al guest si el mismo tiene la red configurada como NAT.
Después de googlear un rato, descubrí como hacer para poner reglas del tipo "el puerto 2222 del host es el 22 de mi_vm, y solo es accesible desde el host". Es así:

$ VBoxManage modifyvm "mi_vm" --natpf1 "ssh,tcp,127.0.0.1,2222,,22"

Si quisieran sacar la regla hay que hacer:

$ VBoxManage modifyvm "mi_vm" --natpf1 delete "ssh"

Si quieren ver que reglas de forwarding tiene su VM, pueden hacer:

$ VBoxManage showvminfo "mi_vm" | grep NIC

Para más detalles pueden mirar en la sección 6.3.1 del manual de VirtualBox.

Happy hacking!

2014-06-08

Agua destilada

Hola a todos,

Estoy feliz de anunciarles que está en YouTube la edición en calidad HD del corto que filmamos con varios amigos durante 2012 y 2013, y que me tiene como protagonista. Acá les dejo el link:
http://youtu.be/pAUmaNOTJs0.

Y si quieren verlo directamente, también una ventanita:

Espero que les guste!

2014-06-01

cgoban y java 1.7

Si tratan de correr cgoban con Java Web Start, como dice en gokgs.com, puede ser que les de un error en la firma del jnlp (como a mi). Para workaroundear el problema, lo que yo hice es bajarme el .jar de http://files.gokgs.com/javaBin/cgoban.jar y correrlo localmente.

Espero que les sirva, y si quieren jugarse una partidita de go conmigo pueden buscarme en Dragon Go Server, mi usuario es aurelianito y, al momento de escribir este post, soy 11k.

2014-05-31

Drivers para PlayTV USB SBTVD en Windows 7 64 bits

Ayer me compré un sintonizador para la televisión digital abierta (TDA). El modelo exacto es PV-231U(RN)-F. Y el CD con el que vino tiene los drivers para Windows 7 pero no te da la opción de instalarlos :-/.

Así que tuve que instalarlos a mano. Lo que encontré es como hacerlo desde la línea de comando. Corriendo cmd como "Administrador", fui al directorio donde están los drivers (e:\driver\vista64) y corrí pnputil -a *.inf. Le dije que sí a los 2 drivers (tienen problemas en las firmas :-/) y ahora puedo ver los partidos del mundial en la compu :).

Espero que les haya servido,
Aureliano.

2014-05-27

Scl, gnu-screen, flask y python 2.7

Update (2014-05-28): Quiero aclarar que si sólo instalo python y screen me muestra la versión de python 2.7 en el shell corriendo adentro del screen.

Arranco en AWS desde 0 con un AMI de un RHEL 6.5, RHEL-6.5_GA-x86_64-7-Hourly2 (ami-aa8bfe9a). Instalo python 2.7, screen, pip y flask usando pip.

$ sudo yum -y install python27
$ sudo yum -y install screen
$ sudo scl enable python27 "easy_install pip"
$ sudo scl enable python27 "pip install flask"

Activo un shell con python27 y corro python

$ scl enable python27 bash
$ python --version
Python 2.7.5

Y veo que configuró la carga de bibliotecas para cargar las libs de python 2.7.

$ echo $LD_LIBRARY_PATH

/opt/rh/python27/root/usr/lib64


Pero, si hago lo mismo en un screen:

$ scl enable python27 bash
$ python --version

python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

Y no tiene configurada la carga de bibliotecas para cargar las libs de python 2.7.

$ echo $LD_LIBRARY_PATH


(no aparece nada :-( )

¿Alguien sabe que está pasando? ¿Qué hice mal?

Happy hacking, 
Aureliano.

2014-04-28

Bindings extraños en python

El comportamiento de locals() en python es extraño. ¿Por qué no me muestra siempre todas las variables por las que clausura? (pero sí muestra algunas :-/). ¿Como hago para obtenerlas todas?

Abajo pongo el POC que muestra que no anda como quiero:

>>> def foo():
...   a = 1
...   def bar():
...     print locals()
...   bar()
... 
>>> foo()
{}

Como ven, no muestra a como posible variable.

En cambio, en este ejemplo, que debería tener el mismo comportamiento, sí muestra a como variable.

>>> def foo():
...   a = 1
...   def bar():
...     a
...     print locals()
...   bar()
... 
>>> foo()
{'a': 1}


¿Cómo hago para armar el diccionario de las variables que se pueden usar en una función en python?

Todo esto lo probé en una consola corriendo python 2.7.6.

Happy hacking,
Aureliano.

2014-04-15

Recuperando mi mongo en debian

Update: La máquina en la que hice esto es un debian. De todas maneras en ubuntu seguramente es muy parecido.

Chequeo el estado de mi server mongo en mi debian y me dice:
$ sudo service mongodb status
[FAIL] Checking status of database: mongodb apparently not running failed!


Entonces miro en /var/log/mongodb/mongodb.log y encuentro esta línea:
Unclean shutdown detected.
Please visit http://dochub.mongodb.org/core/repair for recovery instructions.

¿Hago lo que dice ahí de una? No. Porque el mongo en ubuntu corre con un usuario específico. Mejor hago
$ sudo -u mongodb mongod -f /etc/mongodb.conf  --repair

Espero un rato, y termina de correr el script. Después hago:

$ sudo service mongodb start
[ ok ] Starting database: mongodb.

Happy hacking,
Aureliano.

2014-04-11

Pipeando procesos en python

A veces uno quiere correr varios procesos en python y enchufar el standard output de un proceso con el stdin del siguiente. Esto sería equivalente a hacer en el shell:
$ prog1 param1 | prog2 param21 param22 | prog3

Para poder hacer algo así en python hice este método:
import subprocess
def pipe(*args):
    last_proc = None
    for command in args:
        in_file = last_proc.stdout if last_proc else tempfile.TemporaryFile()
        proc = subprocess.Popen(command, stdin=in_file, stdout=subprocess.PIPE)
        if last_proc:
            last_proc.stdout.close()
        last_proc = proc
        

    last_proc.communicate()

Para hacer lo mismo que el comando de arriba hay que hacer:
pipe(
  ("prog1", "param1"),
  ("prog2", "param21", "param22"),
  ("prog3",)
)

La única limitación es que no puedo procesar la salida de standard output del último proceso. 

Happy hacking,
Aureliano.

2014-04-08

scl y screen

En RedHat existe un mecanismo para tener en el mismo host diferentes versiones del mismo software que se activa corriendo desde línea de comando. Por ejemplo, para activar python27 (en vez del 2.7, default de la distro) hay que correr scl enable python27 bash.

El problema es que si después corrés screen, ese seteo no pasa en forma limpia al shell que corre adentro del screen. Por lo tanto, lo que hay que hacer es hacer el enable "adentro" del screen. Por ejemplo, para correr un bash en screen con soporte para python 2.7 hay que correr screen scl enable python27 bash

La idea de cómo hacer esto la saqué de la documentación de CentOS. Busquen "coreutils component" dentro de la página para ver el detalle.

Happy hacking,
Aureliano.

Hacer un pem con clave a partir de uno sin clave

Tengo un .pem sin clave que me sirve para acceder a un server y me parece demasiado inseguro. Entonces corro:

openssl rsa -des -in orig.pem -out con-clave.pem 

Me pide la clave y en con-clave.pem tengo el .pem con clave, así que puedo borrar el otro (pero lo pruebo antes por las dudas).

Happy hacking,
Aureliano

2014-04-07

Nombres para sandro

Estoy pensando los nombres para los subcomponentes de sandro. Voy a seguir la línea del primer intento y usar nombres de canciones de Sandro (compuestas o interpretadas por él) para nombrarlos.
Acá les tiro mis ideas:

  • rosa: sistema de templating.
  • tengo: persistencia.
  • ya: sistema de caché.
  • asi: unit-testing framework.
  • penumbras: el sistema de base. Carga módulos, integra con la JVM.
  • maniqui: mock objects.
  • aveDePaso: lib de promises.
  • camino: routing (la canción es "Por algún camino").
  • nadaMas: colección de helpers.
  • comoTeDire: adapter para poder correr cosas que no están hechas para sandro como, por ejemplo, libs hechas para el browser. 
  • alFinal: utilidades para hacer endpoints (la canción es "Al final, Corazón") 
  • comoLoHiceYo: Utilidad para armar la estructura estandarizada de un site. 
  • palabrasSinSentido: Utilidades para escribir documentación. 
  • heyhey: Logging
Voy a ir agregando cosas a la lista a medida que se me ocurran o me las sugieran.

Espero sus sugerencias, 
Aureliano.

2014-03-30

sandro reboot

Hace ya casi 4 años empecé un proyecto para hacer más fácil hacer páginas web seguras al que llamé sandro. Ahora estoy empezando el mismo proyecto de nuevo, siguiendo con mismas ideas rectoras:

  • Un solo lenguaje en todos lados, JavaScript.
  • Templating client-side y server side compartiendo código.
  • Validación de datos en el cliente y server compartiendo código.
  • Seguro por defecto. El diseño del framework debería hacer que sea más fácil hacer aplicaciones seguras que inseguras.
La primera versión va a estar basada en rhino, igual que la vez anterior, pero va a haber algunos cambios que creo que son importantes:
  • No va a estar enfocado a correr en app-engine.
  • Para mantener la idea de que haya JavaScript en todos lados, el motor de base de datos elegido va a ser mongodb.
  • Para reconciliarme con la naturaleza asíncrona y mono-thread del browser, voy a cambiar el manejo de módulos de commonjs por requirejs en el cliente y una API compatible con requirejs en el server.
Si quieren ir viendo el avance del proyecto, está en un proyecto público de bitbucket.

Espero feedback y, sobre todo, pull requests.

Happy hacking,
Aureliano.

2014-03-16

Cabeceo, técnica y táctica

En muchas milongas es de mala educación acercarse directamente a una persona y preguntarle si quiere bailar. Yo entiendo que es porque si no quiere, la forzás a elegir entre 2 opciones que son una cagada. La primera es bailar con vos de todas maneras y la segunda es exponerlos a ambos a que quede claro que no quiso bailar con vos.
Para evitar esto, existe un procedimiento que se llama cabeceo y es así (en su forma heteronormativa):

  1. Hombre y mujer establecen contacto visual.
  2. El hombre, sin romper el contacto visual, inclina su cabeza levemente hacia la pista.
  3. La mujer, sin romper el contacto visual, asiente con la cabeza.
  4. El hombre, sin romper el contacto visual, se acerca a donde la mujer esté sentada.
  5. Ambos van juntos hacia la pista.
Aunque parezca bastante machista, en realidad no lo es. El secreto está en el contacto visual. Si alguno de los 2 no quiere bailar con el otro, todo lo que tiene que hacer es romper el contacto visual. Así la otra parte sabrá que no quiere bailar y evita el escarnio público del rechazo (el rechazo en sí me parece que es inevitable).
Ahora la táctica. Si sos mujer y querés bailar, lo que tenés que hacer es:
  1. Estar bien sentada, tu postura corporal es lo que nos dice si querés bailar o no.
  2. Prestá atención a los bailarines con los que querés bailar, y tratá de establecer contacto visual con ellos. Si estás hablando con la chica que está sentada al lado tuyo, sin prestar atención a tu alrededor, es mucho más difícil invitarte a bailar. Esto es especialmente importante durante el primer tango de la tanda. 
Si sos hombre, 
  1. Tenés que hacer que te vean. Para eso en muchas milongas es normal circular por el pasillo (o borde de la pista)
  2. Salvo que tenga mucha confianza con la bailarina, o estés en una milonga que el cabeceo no se use, no invites a bailar a alguien sin seguir el procedimiento de arriba.
El procedimiento de arriba sirve para evitar malos entendidos. Si 2 bailarines invitan a la misma bailarina. La bailarina va a mantener contacto visual con el que haya elegido, y el otro podrá retirarse sin que nadie se de cuenta lo que pasó. Lo mismo si 2 bailarinas piensan que las invitó el mismo bailarín.

Nos vemos en las milongas,
Aureliano.

2014-03-14

Selección de los hijos

En este post no estoy proponiendo al hijo del Kun para la selección de fútbol sino que quiero mostrar una solución a un problema puntual en d3. Hace un tiempito postié cómo hacer para hacer un selector de CSS que busque solo en los hijos de un nodo. El objetivo era hacer más robustas las selecciones de nodos en los gráficos que hago con d3. Lamentablemente ese truco no anda con un montón de browsers, pero encontré otro mucho más simple. Si queremos una selección con todos los nodos hijos de la selección actual, lo más fácil es hacer:

my_selection.selectAll(function() { return this.childNodes })

Al final era bastante fácil. No entiendo porqué esto no está en ningún lado. Casi siempre cuando uso selectAll quiero obtener los hijos de los nodos de la selección actual.

Happy hacking,
Aureliano.

2014-03-10

Como esto pero distinto, no en CSS

Quiero poder decir, esta clase es como tal otra, pero el font es de tamaño x; y no puedo.

Acá está el detalle: http://stackoverflow.com/questions/1065435/can-a-css-class-inherit-one-or-more-other-classes.

Otro motivo más que muestra porqué habría que tener un lenguaje de programación y una lib estándar en vez del hack horrible de CSS.

Happy hacking,
Aureliano.

2014-02-20

Word wrap en SVG

El elemento text de svg no tiene forma de decirle que corte el texto en líneas respetando un ancho, ni como cambiar el font de una parte del texto, etc. Por suerte existe otro elemento que se llama foreignobject y sirve, entre otras cosas para embeber html. Y obvio que el html embebido puede hacer word wrap (como siempre en html). Cuando pueda lo voy a probar bien, por ahora pueden ver en este artículo como usarlo.

Happy hacking,
Aureliano

2014-02-13

CSS selector, hijo de un nodo

Update: Lo probé en Firefox 24 y no anda. La funcionalidad está implementada pero no está habilitado en la configuración por defecto (https://developer.mozilla.org/en-US/docs/Web/CSS/:scope).

En un montón de bibliotecas para el browser, como d3 o jquery podemos usar selectores de CSS para elegir nodos que son descendientes de un conjunto de nodos dado. Esta funcionalidad, casi siempre está basada en el método elem.querySelectorAll(css_selector). Hoy descubrí algo muy interesante de este método. Hay una pseudo-clase de css que se llama :scope y cuando es usada en el selector del método de arriba refiere al elem sobre el que se hizo la consulta.
Ésta pseudo-clase, la podemos usar para elegir a los hijos de un elemento que cumplan cierta condición. Por ejemplo, elem.querySelectorAll(":scope > .klass") busca todos los elementos hijos (y solo hijos, no nietos) de elem que tienen klass como clase.
Como las bibliotecas que mencioné al principio usan esto en sus entrañas, también se puede usar en las mismas cuando buscás nodos. Por ejemplo, en d3 sería algo así: my_selection.selectAll(":scope > g").
Happy hacking,
Aureliano.
PD: La información original sobre cómo hacer esto la saqué de acá.
PD2: Lo probé con d3 en mi Chrome y anda. La documentación de Firefox también dice que anda, pero no lo probé. El resto de los browsers son un misterio para mi. Si lo prueban en otros contextos, avisen.