#!/usr/bin/python
#
# Author: Sameer Ajmani
# Date: 7-Dec-2004
#
# License:
# Anyone if free to use and extend this program.
# Please credit me in derived works.
#
# Description: Converts your delicious posts to an HTML file that you
# can import into your bookmarks (or just use to replace your existing
# bookmarks).  Each tag becomes a bookmark folder, and posts with
# multiple tags are put in multiple folders.  Tags containing a colon
# (:) are split into sub-tags, and each sub-tag becomes a separate
# folder.  So, e.g., a post with the tags "movies cultural:indian"
# will end up in two bookmark folders, "movies" and "indian", the latter
# inside another bookmark folder, "cultural".  Folders are sorted
# alphabetically by name; bookmarks, alphabetically by description.

import re
import sys
from xml.sax import parse
from xml.sax.handler import ContentHandler
from time import strptime, mktime
from urllib import urlretrieve, urlencode

class Tag:
      def __init__(self, name):
          self.name = name
          self.children = {}
          self.bookmarks = {}

class Bookmark:
      def __init__(self, url, add_date, desc):
          self.url = url
          self.add_date = add_date
          self.description = desc

if len(sys.argv) != 4:
   print """
usage: delicious-bookmarks.py <user> <password> <output>
       user: your del.icio.us user name
       password: your del.icio.us password
       output: the output filename (WILL BE OVERWRITTEN)
         (If you set output to your bookmarks.html file, this will
          replace your existing bookmarks.  Alternatively, you can
          set output to some temporary filename and import the
          contents of that file into your bookmarks.)
"""
   sys.exit(1)

(user, password, filename) = sys.argv[1:4]

class Handler(ContentHandler):
    def __init__(self):
        self.roottag = Tag('Delicious')
        self.bookmarks = {}
    def startElement(self, name, attrs):
        if name == 'post':
           url = attrs['href']
           dt = int(mktime(strptime(attrs['time'], '%Y-%m-%dT%H:%M:%SZ')))
           desc = attrs['description']
           tags = attrs['tag'].split()
           for tag in tags:
               t = self.roottag
               names = tag.split(':')
               for name in names:
                   if name not in t.children:
                      t.children[name] = Tag(name)
                   t = t.children[name]
               if url not in self.bookmarks:
                  self.bookmarks[url] = Bookmark(url, dt, desc)
               t.bookmarks[url] = self.bookmarks[url]

# get the user's list of existing delicious posts
all_url = 'http://%s:%s@del.icio.us/api/posts/all' % (user, password)
print "downloading %s's delicious posts" % user
(posts, headers) = urlretrieve(all_url)
handler = Handler()
parse(posts, handler)
print 'got %d bookmarks' % len(handler.bookmarks)

# write the bookmarks to a file
print 'writing bookmarks to', filename
f = file(filename, 'w')

def p(indent, s):
    print >> f, '    '*indent + s

def printBookmark(indent, bookmark):
    p(indent, '<DT><A HREF="%s" ADD_DATE="%s">%s</A></DT>' \
      % (bookmark.url.encode('ascii','xmlcharrefreplace'),
         bookmark.add_date,
         bookmark.description.encode('ascii','xmlcharrefreplace')))

def printTag(indent, tag):
    p(indent, '<DT><H3>%s</H3></DT>' % tag.name)
    p(indent, '<DL><p>')
    bookmarks = tag.bookmarks.values()
    bookmarks.sort(lambda a, b: cmp(a.description, b.description))
    for bookmark in bookmarks:
        printBookmark(indent+1, bookmark)
    children = tag.children.values()
    children.sort(lambda a, b: cmp(a.name, b.name))
    for child in children:
        printTag(indent+1, child)
    p(indent, '</DL>')

p(0, '<DL><p>')
printTag(1, handler.roottag)
p(0, '</DL>')
print 'done'
