Ping Technorati from your Django App

There are other articles written about this, but I felt the need to write a better one. Ahem.

Meat and potatoes time.

In your settings.py file, set 2 new variables:


# 'PING' blog indexing sites.
PING_BLOG_INDEX = True

# List of blog index ping URL's
BLOG_INDEX = ['http://rpc.technorati.com/rpc/ping',
'http://blogsearch.google.com/ping/RPC2',
'http://rpc.weblogs.com/RPC2']

PING_BLOG_INDEX is self explanatory. BLOG_INDEX is a list of blog XMLRPC url's that this application is going to use to notify the remote website (blog indexer) that your blog has been updated.

Let's create a new file in your blog application directory and name it ping.py. This file will hold the code that actually pings the blog indexers. Here it is:


from django.conf import settings

def pingSites(entry, blog_name):
for site in settings.BLOG_INDEX:
try:
rpc = xmlrpclib.Server(site)
try:
p = rpc.weblogUpdates.extendedPing(blog_name,
settings.SITE_URL,
entry.get_absolute_url(),
settings.SITE_URL + '/feeds/rss2'
)
except:
# May not support extendedPing()
# Try normal ping
p = rpc.weblogUpdates.ping(blog_name,
settings.SITE_URL)

if p.has_key('flerror') and p['flerror'] == True:
errlog(p['message'])
except:
errlog('pingSites: %s, exception!' % (site))

A few notes on the above code:


  1. errlog() is a function I have that just logs errors via syslog for my review. If you don't want to track the errors then a simple "pass" will do. I am just anal about errors and like to follow them. Heh, I said anal.

  2. This code assumes 2 things. One is that you have a "SITE_URL" option in your settings.py file. It should just be something like "SITE_URL = 'http://www.petersanchez.com'". And two is that your "Entry" model (the model that stores your blog posts) has a "get_absolute_url()" method. If it currently doesn't, I have to ask: What's wrong with you? Add one!

  3. You probably need to change the '/feeds/rss2' line to match the URL for your own RSS feed. Don't have an RSS feed on your blog yet? Write one, its super simple. Doc's are here.

Now lets edit your blogs models.py file be sure to import the pingSites() function that we just created in ping.py.


from your_project.blog.ping import pingSites

In your "Entry" model (mine is named "Entry", your mileage may vary) create a custom save() function.


def save(self):
# Save first, ping second (if configured)
super(Entry, self).save()
if settings.PING_BLOG_INDEX:
blog = Blog.objects.all()[0]
pingSites(self, blog.name)

Notes on above code:


  1. The 'blog' variable used in my example is because the software I wrote supports multiple blogs from a single installation. If you don't have a similar setup, just remove the "blog = Blog...." line and replace "blog.name" with the name of your blog. For example: pingSites(self, 'Joe Blow Blog')

That's it. You should be good to go. Next time you update your blog the blogosphere will immediately know about it via the blog indexers.