Introduction
cl-delicious is a Common Lisp interface to the del.icio.us API
licensed under the LLGPL and written by Ryan Moe <ryan.moe@gmail.com>.
It has been tested on:
- Linux/SBCL
- Linux/CMUCL
- Linux/CLISP almost works. I don't know enough about CLISP to get it to work. I don't think it would take much.
API Reference
First we need to create an instance of the delicious user class. This class stores the the username and password used to authenticate with the del.icio.us api.
CL-USER> (in-package :cl-delicious) #<PACKAGE "CL-DELICIOUS"> CL-DELICIOUS> (defparameter *du* (make-instance 'delicious-user :username "user" :password "pass")) *DU*
The rest of the API consists of methods specialized on the delicious-user class.
Update
Returns the last update time for the user. Use this before calling all-posts to see if the data has changed since the last fetch. This method also sets the last-updated slot on the delicious-user object
CL-DELICIOUS> (update *du*) "2007-02-20T21:07:47Z"
Tags
get-tags
Returns a list of tags and number of times used by a user as a list of tag structs.
CL-DELICIOUS> (get-tags *du*) (#S(TAG :TAG "database" :COUNT "1") #S(TAG :TAG "firefox" :COUNT "1") #S(TAG :TAG "implementation" :COUNT "1") #S(TAG :TAG "lisp" :COUNT "2") #S(TAG :TAG "news" :COUNT "2") #S(TAG :TAG "programming" :COUNT "3") #S(TAG :TAG "read" :COUNT "2"))
rename-tag
Rename an existing tag with a new tag name. Takes 2 required arguments, old and new.
CL-DELICIOUS> (rename-tag *du* "news" "news2") "done"
get-posts
Returns posts matching the arguments. If no date or url is given, most recent date will be used. Takes 3 arguments:
- tag (optional). Filter by this tag.
- dt (optional). Filter by this date.
- url (optional). Filter by this url.
CL-DELICIOUS> (get-posts *du*)
(#S(POST
:HREF "http://www.cs.indiana.edu/dfried_celebration.html"
:DESCRIPTION "Daniel P Friedman: A Celebration"
:EXTENDED NIL
:HASH "9821f03f10279cad407aa8b2e5c2bef1"
:OTHERS "74"
:TAG "programming video"
:TIME "2007-02-22T23:06:22Z")
#S(POST
:HREF "http://www.math.gatech.edu/~cain/textbooks/onlinebooks.html"
:DESCRIPTION "Online texts"
:EXTENDED NIL
:HASH "79b0c74c3d2941dbd57ac922b471e781"
:OTHERS "1029"
:TAG "math books"
:TIME "2007-02-22T20:50:26Z"))
You can also specify a date (or a tag, or a url).
CL-DELICIOUS> (get-posts *du* :dt "2007-02-20")
(#S(POST
:HREF "http://roachfiend.com/archives/2004/12/08/how-to-create-firefox-extensions/#hello"
:DESCRIPTION "roachfiend.com » How to create Firefox extensions"
:EXTENDED NIL
:HASH "8019bdffc70ff601dc85e13e9dca2552"
:OTHERS "31"
:TAG "firefox programming"
:TIME "2007-02-20T21:07:47Z")
#S(POST
:HREF "http://c2.com/cgi/wiki?CodeGenerationIsaDesignSmell"
:DESCRIPTION "Code Generation Isa Design Smell"
:EXTENDED NIL
:HASH "e4d5cac5a19360ca3c61f21d1f22652e"
:OTHERS "12"
:TAG "programming"
:TIME "2007-02-20T20:45:26Z"))
recent-posts
Returns a list of the most recent posts, filtered by argument. Maximum 100. Takes 2 arguments.
- tag (optional). Filter by this tag.
- count (optional). Number of items to retrieve (Default:15, Maximum:100).
CL-DELICIOUS> (recent-posts *du* :count "2")
(#S(POST
:HREF "http://www.cs.indiana.edu/dfried_celebration.html"
:DESCRIPTION "Daniel P Friedman: A Celebration"
:EXTENDED NIL
:HASH "9821f03f10279cad407aa8b2e5c2bef1"
:OTHERS NIL
:TAG "programming video"
:TIME "2007-02-22T23:06:22Z")
#S(POST
:HREF "http://www.math.gatech.edu/~cain/textbooks/onlinebooks.html"
:DESCRIPTION "Online texts"
:EXTENDED NIL
:HASH "79b0c74c3d2941dbd57ac922b471e781"
:OTHERS NIL
:TAG "math books"
:TIME "2007-02-22T20:50:26Z"))
all-posts
Returns all posts. Call the update function to see if you need to fetch this at all. Takes 1 argument.
- tag (optional). Filter by this tag.
CL-DELICIOUS> (all-posts *du* :tag "lisp")
returns all bookmarks tagged with "lisp".
get-dates
Returns a list of dates with the number of posts at each date. Takes 1 argument.
- tag (optional). Filter by this tag.
CL-DELICIOUS> (get-dates *du*) (#S(DATE :DATE "2007-02-22" :COUNT "4") #S(DATE :DATE "2007-02-21" :COUNT "8") #S(DATE :DATE "2007-02-20" :COUNT "3") #S(DATE :DATE "2007-02-19" :COUNT "4") #S(DATE :DATE "2007-02-16" :COUNT "2") #S(DATE :DATE "2007-02-14" :COUNT "3"))
add-post
Add a post to del.icio.us Takes 7 arguments.
- url (required) - the url of the item.
- description (required) - the description of the item.
- extended (optional) - notes for the item.
- tags (optional) - tags for the item (space delimited).
- dt (optional) - datestamp of the item (format "CCYY-MM-DDThh:mm:ssZ"). Requires a LITERAL "T" and "Z" like in ISO8601 at http://www.cl.cam.ac.uk/~mgk25/iso-time.html for example: "1984-09-01T14:21:31Z"
- replace=no (optional) - don't replace post if given url has already been posted.
- shared=no (optional) - make the item private.
CL-DELICIOUS> (add-post *du* "http://google.com" "Search engine" :tags "search")
delete-post
Delete a post from del.icio.us Takes 1 argument.
- url (required) - the url of the item.
CL-DELICIOUS> (delete-post *du* "http://google.com")
Bundles
all-bundles
Retrieve all bundles.
CL-DELICIOUS> (all-bundles *du*) (#S(BUNDLE :NAME "programming" :TAGS "lisp programming"))
set-bundle
Assign a set of tags to a single bundle, wipes away previous settings for bundle. Takes 2 arguments:
- bundle (required) - the bundle name.
- tags (required) - list of tags (space seperated).
CL-DELICIOUS> (set-bundle *du* "programming" "lisp programming") "ok"
Returns either "ok" or "you must supply a bundle name and at least one tag" if the bundle could not be created.
delete-bundle
Delete a bundle. Takes 1 argument.
- bundle (required) - the bundle name.
CL-DELICIOUS> (delete-bundle *du* "programming") "ok"
More interesting examples
Because results are returned as lists of stucts you can map the struct functions across the list to retrieve individual elements.
For instance if you just want to retrieve the url of all posts tagged lisp you can do this.
CL-DELICIOUS> (mapcar #'post-href (all-posts *du* :tag "lisp"))
("http://blogs.bl0rg.net/netzstaub/2005/03/09/a-short-practical-overview-of-mop-part-2/"
"http://blogs.bl0rg.net/netzstaub/2005/03/08/a-short-practical-overview-of-the-metaobject-protocol"
"http://c2.com/cgi/wiki?ImplementingLisp" "http://cliki.net/")
You can get a list of tags sorted by count.
CL-DELICIOUS> (sort (get-tags *du*) #'(lambda (x y) (> (parse-integer x) (parse-integer y))) :key #'tag-count) (#S(TAG :TAG "lisp" :COUNT "10") #S(TAG :TAG "programming" :COUNT "6") #S(TAG :TAG "books" :COUNT "3") #S(TAG :TAG "clos" :COUNT "3") #S(TAG :TAG "mop" :COUNT "2") #S(TAG :TAG "news" :COUNT "2") #S(TAG :TAG "read" :COUNT "2") #S(TAG :TAG "database" :COUNT "1") #S(TAG :TAG "firefox" :COUNT "1") #S(TAG :TAG "food" :COUNT "1") #S(TAG :TAG "implementation" :COUNT "1") #S(TAG :TAG "math" :COUNT "1"))
Download
Download ASDF package
My Public Key
Todo
- The del.icio.us api only allows you to retrieve information for your user. I would like to add an interface to the del.icio.us RSS feeds. These feeds can be used to retrieve information about other user's links and similar information.
- Cache the results of all requests.
- Get it working on other CL implementations.