Blinklist -> del.icio.us

Long ago I migrated from del.icio.us to Blinklist. Why? Blinklist would let me combine tags when trying to find a link, and del.icio.us wouldn’t. For example, with Blinklist I could find a link tagged with both “reference” AND “css”. On del.icio.us, only “reference” OR “css”.

Unfortunately, Blinklist dropped that feature a while back. I just noticed del.icio.us added it, and I’m tired of waiting for Blinklist to add it back in.

But I faced the problem of getting all my bookmarks from Blinklist back to del.icio.us. Probably such a tool exists already, but it was pretty easy to hack together in PHP.

Download your Blinklist bookmarks in XML from http://www.blinklist.com/?Action=User/Export/export.php and save them in blinklist.xml.

Blinklist allowed spaces in tags, del.icio.us does not. The code converts spaces in the tags to hyphens. PEAR HTTP_Request and openssl is required in your PHP install.

Run it from the command line: php blinklist-to-delicious.php blinklist.xml

Here’s the code. Standard disclaimer applies: this is quick n’ dirty(tm):

<?php
/* Take blinklist bookmarks xml
             and add them to del.icio.us via the API.

---------------------------------------------------
del.icio.us API:

https://api.del.icio.us/v1/posts/add?

&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 (format "CCYY-MM-DDThh:mm:ssZ").
&replace=no (optional) - don't replace bookmark if already posted.
&shared=no (optional) - make the item private

---------------------------------------------
Blinklist entry XML:
  <item>
   <title>MrBalky Heavy Industries</title>
   <description></description>
   <link>http://www.mrbalky.com</link>
   <guid></guid>
   <pubDate>1197042355</pubDate>
   <private></private>
   <favourite></favourite>
   <vote>0</vote>
   <category>awesome,cool,stupid</category>
  </item>
*/
require_once "HTTP/Request.php";

$delicious_id = 'mydeliciousid';
$delicious_pass = 'mypassword';

define( "ITEM", "ITEM" );
define( "TITLE", "TITLE" );
define( "LINK", "LINK" );
define( "PUBDATE", "PUBDATE" );
define( "CATEGORY", "CATEGORY" );

$item = array();
$have_item = FALSE;
$in_item = FALSE;

function startElement( $parser, $name, $attrs )
{
  global $current_element, $in_item, $item;

  $current_element = $name;
  if ( $name == ITEM )
  {
    $item = array();
    $in_item = TRUE;
  }
}

function endElement( $parser, $name )
{
  global $current_element, $in_item, $item;

  $current_element = "";
  if ( $name == ITEM )
  {
    $in_item = FALSE;
    addToDelIcioUs();
  }
}

function elementData( $parser, $text )
{
  global $current_element, $in_item, $item;

  if ( $in_item )
  {
    $item[ $current_element ] .= $text;
  }
}

function addToDelIcioUs()
{
  global $item, $delicious_id, $delicious_pass;

  $itemURL = urlencode( $item[LINK] );
  $itemTitle = urlencode( $item[TITLE] );
  $itemDate = strftime( '%Y-%m-%dT%H:%M:%SZ', $item[ PUBDATE ] ); 

  $apiURL = "https://api.del.icio.us/v1/posts/add?url=$itemURL";
  $apiURL .= "&description=$itemTitle";
  $apiURL .= "&dt=$itemDate";
  $apiURL .= '&tags=';
  $sep = "";

  $itemTags = split( ',', $item[ CATEGORY ] );
  foreach( $itemTags as $tag )
  {
    $tag = str_replace( ' ', '-', $tag );
    $apiURL .= "$sep$tag";
    $sep = '+';
  }
  echo "$apiURL\n";

  $req =& new HTTP_Request( $apiURL );
  $req->setBasicAuth( $delicious_id, $delicious_pass );

  $response = $req->sendRequest();

  if ( PEAR::isError($response) )
  {
    echo 'Error: '.$response->getMessage()."\n";
  }
  else
  {
    echo 'Response: '.$req->getResponseBody()."\n";
  }

  echo "\n";

  sleep( 5 );  // be polite to del.icio.us
}

$inputFile = $argv[1];
echo "input: $inputFile\n";
$xml = file_get_contents( $inputFile );
$xml_parser = xml_parser_create();
xml_set_element_handler( $xml_parser, "startElement", "endElement" );
xml_set_character_data_handler( $xml_parser, "elementData" );
xml_parse( $xml_parser, $xml );
xml_parser_free($xml_parser);
?>

Leave a Reply