Skip to main content

Ralsina.Me — Roberto Alsina's website

Migrating from Haloscan to Disqus (if you can comment on it, it worked ;-)

Introduction

If you are a Haloscan user, and are start­ing to won­der what can you do... this page will ex­plain you a way to take your com­ments to Dis­qus, an­oth­er free com­ment ser­vice.

A few days ago, Haloscan an­nounced they were stop­ping their free com­ment ser­vice for blogs. Guess what ser­vice has in it the com­ments of the last 9 years of this blog? Yes, Haloscan.

They of­fered a sim­ple mi­gra­tion to their Echo plat­for­m, which you have to pay for. While Echo looks like a per­fect­ly nice com­ment plat­for­m, I am not go­ing to spend any mon­ey on this blog if I can help it, since it al­ready eats a lot of my time.

Luck­i­ly, the guys at Haloscan al­low ex­port­ing the com­ments (that used to be on­ly for their pre­mi­um ac­counts), so thanks Haloscan, it has been nice!

So, I start­ed re­search­ing where I could run to. There seems to be two large free com­ment sys­tem­s:

Keep in mind that my main in­ter­est lays in not los­ing al­most ten years of com­ments, not on how great the ser­vice is. That be­ing said, they both seem to of­fer rough­ly the same fea­tures.

Let's con­sid­er how you can im­port com­ments to each ser­vice:

  • Dis­­qus: It can im­­port from blog­ger and some oth­­er host­ed blog ser­vice. Not from Haloscan.

  • In­­tense De­­bate: Can im­­port from some host­ed ser­vices, and from some files. Not from the file Haloscan gave me.

So, what is a guy to do? Write a python pro­gram, of course! Here's where Dis­qus won: they have a pub­lic API for post­ing com­ments.

So, all I have to do then is:

  1. Grok the Dis­­qus API

  2. Grok the Haloscan com­­ments file (it's XM­L)

  3. Cre­ate the nec­es­sary threads and what­ev­er in Dis­­qus

  4. Post the com­­ments from Haloscan to Dis­­qus

  5. Hack the blog so the links to Haloscan now work for Dis­­qus

Piece of cake. It on­ly took me half a day, which at my cur­rent rates is what 3 years of Echo would have cost­ed me, but where's the fun in pay­ing?

So, let's go step by step.

1. Grok the Disqus API

Luck­i­ly, there is a rea­son­able Dis­qus Python Client li­brary and docs for the API so, this was not hard.

Just get the li­brary and in­stall it:

hg clone https://IanLewis@bitbucket.org/IanLewis/disqus-python-client/
cd disqus-python-client
python setup.py install

The API us­age we need is re­al­ly sim­ple, so study the API docs for 15 min­utes if you wan­t. I got al­most all the tips I need­ed from this py­blox­som im­port script

Ba­si­cal­ly:

  1. Get your API Key

  2. You lo­­gin

  3. You get the right "fo­rum" (y­ou can use a dis­­qus ac­­count for more than one blog)

  4. Post to the right thread

2. Grok the Haloscan comments file

Not on­ly is it XM­L, it's pret­ty sim­ple XM­L!

Here's a taste:

<?xml version="1.0" encoding="iso-8859-1" ?>
<comments>
    <thread id="BB546">
      <comment>
        <datetime>2007-04-07T10:21:54-05:00</datetime>
        <name>superstoned</name>
        <email>josje@aaaaaa.nl</email>
        <uri></uri>
        <ip>86.92.111.236</ip>
        <text><![CDATA[that is one hell of a cool website ;-)]]></text>
      </comment>
      <comment>
        <datetime>2007-04-07T16:14:53-05:00</datetime>
        <name>Remi Villatel</name>
        <email>maxilys@aaaaaa.fr</email>
        <uri></uri>
        <ip>77.216.206.65</ip>
        <text><![CDATA[Thank you for these rare minutes of sweetness in this rough world...]]></text>
      </comment>
    </thread>
</comments>

So, a com­ments tag that con­tains one or more thread tags, which con­tain one or more com­ment tags. Piece of cake to tra­verse us­ing El­e­ment­Tree!

There is an ob­vi­ous match be­tween com­ments and threads in Haloscan and Dis­qus. Good.

3. Create the necessary threads and whatever in Disqus

This is the tricky part, re­al­ly, be­cause it re­quires some things from your blog.

  • You must have a per­ma­link for each post

  • Each per­ma­link should be a sep­a­rate page. You can't have per­ma­links with # in the URL

  • You need to know what haloscan id you used for each post's com­­ments, and what the per­ma­link for each post is.

For ex­am­ple, sup­pose you have a post at //ralsi­na.me/we­blog/­post­s/AD­V0.html and it has a Haloscan com­ments link like this:

<a hre­f="javascrip­t:HaloScan('AD­V0');" tar­get="_­self"> <script type­="­tex­t/­javascrip­t">­post­Coun­t('AD­V0');</scrip­t></a>

You know where else that 'AD­V0' ap­pears? In Haloscan's XML file, of course! It's the "id" at­tribute of a thread.

Al­so, the ti­tle of this post is "Ad­voga­to post for 2000-01-17 17:19:57" (hey, it's my blog ;-)

Got that?

Then we want to cre­ate a thread in Dis­qus with that ex­act same da­ta:

  • URL

  • Thread ID

  • Ti­­tle

The bad news is... you need to gath­er this in­for­ma­tion for your en­tire blog and store it some­where. If you are luck­y, you may be able to get it from a database, as I did. If not... well, it's go­ing to be a lot of work :-(

For the pur­pose of this ex­pla­na­tion, I will as­sume you got that da­ta nice­ly in a dic­tio­nary in­dexed by thread id:

{
  id1: (url, title),
  id2: (url, title)
}

4. Post the comments from Haloscan to Disqus

Here's the code. It's not re­al­ly test­ed, be­cause I had to do sev­er­al at­tempts and fix­es, but it should be close to ok (down­load).

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Read all comments from a CAIF file, the XML haloscan exports

from disqus import DisqusService
from xml.etree import ElementTree
from datetime import datetime
import time


# Obviously these should be YOUR comment threads ;-)
threads={
    'ADV0': ('//ralsina.me/weblog/posts/ADV0.html','My first post'),
    'ADV1': ('//ralsina.me/weblog/posts/ADV1.html','My second post'),
    }

key='USE YOUR API KEY HERE'
ds=DisqusService()
ds.login(key)
forum=ds.get_forum_list()[0]

def importThread(node):
    t_id=node.attrib['id']

    # Your haloscan thread data
    thr_data=threads[t_id]

    # A Disqus thread: it will be created if needed
    thread=ds.thread_by_identifier(forum,t_id,t_id)['thread']

    # Set the disqus thread data to match your blog
    ds.update_thread(forum, thread, url=thr_data[0], title=thr_data[1])


    # Now post all the comments in this thread
    for node in node.findall('comment'):
        dt=datetime.strptime(node.find('datetime').text[:19],'%Y-%m-%dT%H:%M:%S')
        name=node.find('name').text or 'Anonymous'
        email=node.find('email').text or ''
        uri=node.find('uri').text or ''
        text=node.find('text').text or 'No text'

        print '-'*80
        print 'Name:', name
        print 'Email:', email
        print 'Date:', dt
        print 'URL:', uri
        print
        print 'Text:'
        print text

        print ds.create_post(forum, thread, text, name, email,
                                   created_at=dt, author_url=uri)
        time.sleep(1)

def importComments(fname):
    tree=ElementTree.parse(fname)
    for node in tree.findall('thread'):
        importThread(node)


# Replace comments.xml with the file you downloaded from Haloscan
importComments('comments.xml')

Now, if we are luck­y, you al­ready have a nice and ful­ly func­tion­ing col­lec­tion of com­ments in your Dis­qus ac­coun­t, and you should be calm know­ing you have not lost your da­ta. Ready for the fi­nal step?

Comments

Comments powered by Disqus