Sincronizando comentarios con Disqus

Al cambiar el software de gestión del blog también he cambiado los comentarios, me parecía un engorro volver a programarlo, con el hándicap de que todo lo que tenga que ver con captchas me parece una chapuza que no acaba de convencerme. Así que tomé la decisión de dejar que otros lo gestionen por mi.

Esos otros se llaman Disqus y son uno de los showcase más grandes que se mencionan y relacionan directamente con Django. Con hacer registrarnos en su portal y agregar un poco de javascript a la página en la que queramos tener comentarios ya tendríamos el tinglado funcionando.

Al ser javascript tenemos algún que otro inconveniente, el Señor Google (que se sepa hasta el momento) no es capaz de interpretarlo y, por lo tanto, los comentarios se quedan fuera del contenido indexable por el spiderman de los bits. Que tampoco es que sea un gran problema en este caso, pero es solucionable y parece divertido :P.

¿Solución?

Hacer un script de sincronización, en la propia ayuda de Disqus nos echan una mano con algo de pseudocódigo sobre cómo debería efectuarse esta tarea:

  1. Preparamos dónde guardar esos comentarios (una tabla en base de datos en mi caso) con ciertos campos requeridos.
  2. Ejecutamos un script que compruebe la fecha del último comentario que tenemos en local y le pida a Disqus x elementos a partir de esa fecha (x=100 como máximo en cada petición).
  3. Guardamos la respuesta y asociamos por id de post o por id de thread de Disqus, las tablas de Comentarios con Posts. Por último renderizamos los comentarios en el html resultante.

Implementación

Leyendo la solución parece sencillo - y lo es - pero necesitamos al menos un interfaz para interactuar con el API de esta gente, y como era de esperar, tienen librerías para Python y PHP disponibles (habiéndose currado tremenda plataforma de gestión de comentarios en Django, ¡qué menos que una librería para Python!).

He decidido hacerlo a través de una tarea programada así que tampoco le he dado demasiadas vueltas a la cabeza, el código es el siguiente (en una vista cualquiera - views.py):

from disqusapi import DisqusAPI
from disqusapi import Paginator
from django.http import HttpResponse

def cronUpdateDisqus(request, id=''):
    if conf.DISQUS_SYNC:
        last_comment = mymodels.Comments.objects.all().order_by('-date')
        last_date_imported='1900-01-01 00:00:00'
        if last_comment:
            last_date_imported=str(last_comment[0].date).replace('+00:00','')
        try:
            api = DisqusAPI(conf.DISQUS_API_SECRET, conf.DISQUS_API_PUBLIC)
            for result in api.forums.listPosts(forum=conf.DISQUS_WEBSITE_SHORTNAME, limit='100', order='asc', since=last_date_imported):
                if not mymodels.Comments.objects.filter(comment_id=result['id']):
                    newcomment = mymodels.Comments.objects.create(comment_id=result['id'], date=result['createdAt'].replace('T',' '))
                    newcomment.thread_id = result['thread']
                    newcomment.forum_id = conf.DISQUS_WEBSITE_SHORTNAME
                    newcomment.body = result['message']
                    newcomment.author_name = result['author']['name']
                    newcomment.author_url = result['author']['url']
                    newcomment.author_email = result['author']['emailHash']
                    newcomment.save()
        except:
            pass

    output = "done"
    return HttpResponse(output)

La implementación no es muy allá la verdad, ha sido más quick & dirty para salir del paso que otra cosa, sin embargo sería interesante aprovechar estas cuatro líneas de código para hacer algo open source e importable que se pudiera aprovechar en cualquier proyecto Django.

Ejecución

La llamada al script es un simple cron que, en este caso, ejecutaré cada minuto en un principio hasta tener todos los comentarios importados, luego creo que una vez al día será más que suficiente, no tengo expectativas de crear más de 100 comentarios al día:

*/1    *       *       *       *       /usr/bin/wget -q -O- http://www.dominio.com/cron-update-disqus/ > /dev/null 

Teniendo en cuenta que este sitio tiene cerca de 7000 comentarios, que en cada petición responden un máximo de 100 elementos y que el límite de peticiones por hora es de 1000, en poco más de 1h (y con bastantes menos peticiones del ratio) tengo todos los comentarios sincronizados.

Por cierto que la librería para Python antes mencionada es instalable vía pip así que también se podría hacer algo en plan script sencillo según nos cuenta David Cramer en el README de la misma.

Código fuente

Y así me las he ingeniado para tener comentarios molones, por duplicado, con backup propio y en el html resultante (incrédulos pueden ver código fuente y/o desactivar javascript). ¡Y vaya que si me he divertido!.

django code

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.