Mi experiencia con los OpenBadges para PyConES 2013

Ya sabéis que últimamente estoy muy metido con el tema OpenBadges. Por ejemplo, la librería Python OpenBadgesLib. Otra de mis iniciativas interesantes es el Proyecto OpenBadges de la Asociación Python España. Esa web pretende ser el paraguas de la Asociación Python España para que grupos locales Python españoles puedan gestionar sus propios OpenBadges fácilmente.

Hasta ahora la única comunidad que se ha decidido a dar el paso ha sido Python Madrid, aunque varias más han mostrado interés y se lo están pensando. Recientemente la propia Asociación Python España se ha lanzado al asunto emitiendo un OpenBadge para los ponentes de la PyConES 2013, con un criterio simple.

Pero para emitir esos OpenBadges es conveniente que se cumplan un mínimo de condiciones. Por ejemplo que la web sobreviva por siempre. Literalmente.

Dentro de la Asociación Python España creemos que el grupo de personas que se encarga de la organización de la PyConES debe tener libertad para elaborar la web como quiera o pueda, pero también creemos en la permanencia en el tiempo del sitio web. Por eso la URL de la PyConES incluye también el año, como puede verse en 2013 (http://2013.es.pycon.org/) y 2014 (http://2014.es.pycon.org/). Esto impone algunas restricciones como que, se use la tecnología que se use, el resultado final pueda pasarse a estático usando una herramienta como wget.

Los motivos del paso a estático se justifican en mi artículo Soporte de generadores RSS personalizados en Nikola.

La web original de la PyConES 2013 estaba gestionada por Yamila quien, tras actualizarla admirablemente con las ponencias y sus vídeos, añadió el cordón de "evento terminado" para que no hubiese equívocos. No obstante teníamos pendiente el paso a estático. Durante la PyConES 2014 Borja se ofreció voluntario para realizar la conversión y el hospedaje futuro de la web. Yo también tengo una copia, por si las moscas. La web completa mide 208 Megabytes.

El paso a estático fue simple. Se pudo usar wget directamente. El único detalle fue el selector de idioma, pero en la web original no estaba funcionando tampoco, así que solo se ha archivado la web en español y se ha actualizado la página para eliminar el selector en sí.

Para generar los OpenBadges como a mí me gustan, es decir apuntando a una evidencia objetiva, necesitaba poder enlazar cada charla de la PyConES 2013 con una URL individual. Esto no estaba contemplado en el diseño original de la web. El uso [1] de elementos ocultos que se despliegan al pulsar sobre ellos era un problema añadido.

Para hacer frente a ambos problemas escribí el siguiente programa:

 #!/usr/bin/env python3

 import re
 pagina=open('index.html', 'r', encoding='utf-8').read()

 javascript = """
 <script>
 document.getElementById(window.location.hash).style.display="block";
 </script>
 """
 pagina = re.sub('</html>', javascript+'</html>', pagina)

 expr  = r'<li class="(?P<track>track.)">'
 expr += r'\s*?(?P<start><span) class="hour">(?P<hora>[^<]*?)(?P<end></span>)'
 expr += r'\s*?<span class="paper-title">[^<]*?</span>'
 expr += r'.*?((?P<div><div>)|(</li>))'
 grupos = re.finditer(expr, pagina, flags=re.MULTILINE|re.DOTALL)

 domingo = pagina.find('<h2 class="title white">Horario Domingo</h2>')

 for i in reversed(list(grupos)) :
     start, end = i.start('start'), i.end('end')
     start2, end2 = i.span('div')
     dia = 'sabado' if start < domingo else 'domingo'
     name = '%s-%s-%s' %(dia, i.group('track'), i.group('hora'))
     pagina = pagina[:start] + ('<a name="%s">' %name) + \
             pagina[start:end] + '</a>' + \
             (pagina[end:] if start2 == -1 else \
                 pagina[end:start2] + \
                   ('<div id="#%s">' %name) + pagina[end2:])

 open('index.html2', "w", encoding='utf-8').write(pagina)

Este programa, escrito en Python 3 (línea 1), carga la página web de la PyConES 2013 (línea 4) y la modifica para que despliegue [2] la charla indicada en la URL (líneas 6-11) y para que las charlas tengan URLs individuales (líneas 13-30).

Buscamos las charlas en las líneas 13-17 y sabemos si se trata de una charla dada el sábado o el domingo a través de la línea 19. Seguidamente iteramos sobre las charlas así identificadas, en orden inverso. Es decir empezando por la última. El motivo de ello es que al ir hacia atrás cualquier cambio en el código HTML asociado a una charla no afecta a las posiciones de las charlas que aún nos quedan por procesar. La complejidad en las líneas 28-30 es necesaria para gestionar adecuadamente las charlas que no tienen nada que expandir, como la Keynote de Lynn Root.

La página así modificada permite enlaces a cada una de las charlas, y la charla enlazada se despliega automáticamente [2]. Por ejemplo:

Ahora que las charlas tienen URLs individuales podemos emitir OpenBadges con una evidencia fácilmente comprobable. Yamila me envió la lista de ponentes y de sus charlas y ya sólo fue cuestión de localizarlos en el horario, emitir su OpenBadge y enviárselo por correo. En total se emitieron 38 OpenBadges a otros tantos ponentes. Algunas charlas tuvieron varios ponentes y algunos ponentes dieron varias charlas, pero solo se ha emitido un OpenBadge por persona. Al final hicieron falta cosa de 30 segundos por OpenBadge emitido. Como mucho e incluyendo el email que envía el OpenBadge a su receptor.

Hay una persona que no hemos podido localizar, no obstante. Si se pone en contacto con nosotros le enviaremos gustosamente su OpenBadge. La charla en cuestión es Machine learning, de BityVip.

Mi agradecimiento personal a Yamila y a todo su equipo por el excelente trabajo realizado para la PyConES 2013 y la estupenda colaboración con este proyecto de paso a estático y de emisión de OpenBadges, y a Borja por tomarme la palabra, hospedar la versión estática de la PyConES 2013 y aguantar mis pruebas y experimentos :-).

[1]

El empleo de reglas CSS para ocultar la mayoría de los elementos de la página web de la PyConES 2013 produce un resultado visualmente ligero y agradable. No obstante, en mi opinión, tiene algunos problemas importantes:

  1. Ha habido que meter código para que las charlas se puedan enlazar y que se desplieguen cuando entramos en la web con ese enlace.

  2. ¿Cómo afecta ocultar esa información para la accesibilidad de la web?. Por ejemplo, invidentes.

  3. Personalmente pienso que el problema más grave es que podemos llegar a esa página a través de una búsqueda en Google y, una vez en la página, no encontrar lo que estamos buscando porque está oculto hasta que pulsamos en un lugar no evidente.

    Esto resulta confuso, desconcertante y frustrante.

    Un caso fragrante es el aviso legal o el código de conducta, al final de la web de la PyConES 2013.

[2] (1, 2) He querido que el Javascript añadido sea el mínimo imprescindible para la tarea. Por ello la charla se despliega al cargar la página, pero si luego cambiamos la URL para apuntar a otra charla la charla nueva no se despliega. Esto se hubiera podido solucionar empleando mecanismos como el evento Hashchange disponible en todos los navegadores modernos. Pero es overkill para mis necesidades relativas a los OpenBadges.