'Returns the bookmarks of url or user, respectively.
Delicious.com only returns up to 50 bookmarks per URL on its website.
This means that we have to do subsequent queries plus parsing if
we want to retrieve more than 50. Roughly speaking, the processing
time of get_bookmarks() increases linearly with the number of
50-bookmarks-chunks; i.e. it will take 10 times longer to retrieve
500 bookmarks than 50.
@param url: The URL of the web document to be queried for.
Cannot be used together with \'username\'.
@type url: str
@param username: The Delicious.com username to be queried for.
Cannot be used together with \'url\'.
@type username: str
@param max_bookmarks: Optional, default: 50.
Maximum number of bookmarks to retrieve. Set to 0 to disable
this limitation/the maximum and retrieve all available
bookmarks of the given url.
Bookmarks are sorted so that newer bookmarks are first.
Setting max_bookmarks to 50 means that get_bookmarks() will retrieve
the 50 most recent bookmarks of the given url.
In the case of getting bookmarks of a URL (url is set),
get_bookmarks() will take *considerably* longer to run
for pages with lots of bookmarks when setting max_bookmarks
to a high number or when you completely disable the limit.
Delicious returns only up to 50 bookmarks per result page,
so for example retrieving 250 bookmarks requires 5 HTTP
connections and parsing 5 HTML pages plus wait time between
queries (to comply with delicious\' Terms of Use; see
also parameter \'sleep_seconds\').
In the case of getting bookmarks of a user (username is set),
the same restrictions as for a URL apply with the exception
that we can retrieve up to 100 bookmarks per HTTP query
(instead of only up to 50 per HTTP query for a URL).
@type max_bookmarks: int
@param sleep_seconds: Optional, default: 1.
Wait the specified number of seconds between subsequent
queries in case that there are multiple pages of bookmarks
for the given url. sleep_seconds must be >= 1 to comply with
Delicious.com\'s Terms of Use.
See also parameter \'max_bookmarks\'.
@type sleep_seconds: int
@return: Returns the bookmarks of url or user, respectively.
For urls, it returns a list of (user, tags, comment, timestamp)
tuples.
For users, it returns a list of (url, tags, title, comment,
timestamp) tuples.
Bookmarks are sorted "descendingly" by creation time, i.e. newer
bookmarks come first.'

def get_bookmarks(self, url=None, username=None, max_bookmarks=50, sleep_seconds=1):

    assert (sleep_seconds >= 1)
    assert (bool(username) is not bool(url))
    max_html_count = 100
    max_html_pages = 20
    path = None
    if url:
        m = hashlib.md5()
        m.update(url)
        hash = m.hexdigest()
        path = ('/url/%s' % hash)
    elif username:
        path = ('/%s?setcount=%d' % (username, max_html_count))
    else:
        raise Exception('You    must    specify    either    url    or    user.')
    page_index = 1
    bookmarks = []
    while (path and (page_index <= max_html_pages)):
        data = self._query(path)
        path = None
        if data:
            if url:
                bookmarks.extend(self._extract_bookmarks_from_url_history(data))
            else:
                bookmarks.extend(self._extract_bookmarks_from_user_history(data))
            if ((len(bookmarks) >= max_bookmarks) and (max_bookmarks != 0)):
                break
            else:
                soup = BeautifulSoup(data)
                paginations = soup.findAll('div', id='pagination')
                if paginations:
                    nexts = paginations[0].findAll('a', attrs={'class': 'pn    next'})
                    if (nexts and ((max_bookmarks == 0) or (len(bookmarks) < max_bookmarks)) and (len(bookmarks) > 0)):
                        path = nexts[0]['href']
                        if username:
                            path += ('&setcount=%d' % max_html_count)
                        page_index += 1
                        time.sleep(sleep_seconds)
    if (max_bookmarks > 0):
        return bookmarks[:max_bookmarks]
    else:
        return bookmarks
