July 13th, 2009

Exporting del.icio.us blog links to OPML

I manage my bookmarks in del.icio.us, and tag the ones that are blogs with the blog tag (in addition to subject-related tags). When I want to try out a new blog reader, I can easily export my bookmarked blogs to OPML, using the additional tags as first-level subcategories. If the RSS feed for a given blog isn’t discoverable with a <link> tag on the blog URL, I add it as a line in the notes section: RSS=http://someblog.com/rssfeed.

Here’s the Perl script, delicious_blogs_opml.pl, that exports blog links in del.icio.us to OPML format:

#! /usr/bin/perl
# delicious_blogs_opml.pl - Export OPML blogs feed from del.icio.us
use Net::Delicious;
use XML::Feed;
# use XML::OPML;
# XML::OPML doesn't work as expected
use strict;
my $debug;
$ARGV[0] eq '-d' and $debug = 1, shift;
@ARGV > 0 or die "usage: $0 [-d] delicious_username:password\n";
my %tags;
my ($delusername, $delpasswd) = split(/:/, $ARGV[0], 2);
my $del = Net::Delicious->new(
    {user => $delusername, pswd => $delpasswd, debug => $debug});
# Workaround for Net::Delicious:all_posts() not supporting a tags argument:
# $del->all_posts({tag => 'blog'}) 
$del->config('delicious_posts_all.tag' => '');
# Get all blog links from del.icio.us
my $res = $del->_execute_method("delicious.posts.all", {tag => 'blog'})
    or die "Error calling posts/all\n";
my $posts = $del->_getresults($res, 'post');
foreach my $post ($del->_buildresults('Post', $posts)) {
    my $title = $post->description;
    foreach my $tag (split(' ', $post->tags)) { 
        $tags{$tag}{$title} = $post unless $tag eq 'blog';
print <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<opml version="1.0">
foreach my $tag (sort keys %tags) {
    print qq(<outline title="$tag" text="$tag">\n);
    foreach my $blogname (sort keys %{$tags{$tag}}) {
        my $url = $tags{$tag}{$blogname}->{href};
        my ($feedurl) = XML::Feed->find_feeds($url);
        if (!$feedurl) {
            my $extended = $tags{$tag}{$blogname}->{extended};
            ($feedurl) = $extended =~ /^RSS\s*=\s*(\S+)/im;
        $feedurl or die "Could not find RSS feed for $url\n";
        print qq(\t<outline title="$blogname" text="$blogname" type="rss" xmlUrl="$feedurl"/>\n);
    print "</outline>\n";
print <<EOF;

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>