kelvinluck.com

a stroke of luck

Source for tag complete in del.icio.us example


Update:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

When I released my tool for Tag autocompletion when posting to del.icio.us it didn’t occur to me that people might not be comfortable posting their username and password to my server. But thinking about it this is a reasonable concern. Rather than just ask you to take my word for it that I’m not harvesting usernames and passwords I decided to release the source for the app and make it so that you can host it on your own server…

First up, the PHP. When you log into the app it connects to a PHP script for two reasons:

  • It checks that del.icio.us is contactable and that your login details are correct.
  • It retrieves a list of your tags for use in the autocomplete

This script is called get_tags.php and looks like this:

/**
 * get_tags.php
 *
 * Connects to the del.icio.us server and retrieves a list of tags for a given user
 * and returns this or a sensible error code.
 *
 * Kelvin Luck < kelvin at kelvinluck dot com >
 * This code is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike License
 * <http ://creativecommons.org/licenses/by-nc-sa/2.0/>
 */


define("_URL_GET_TAGS", "http://del.icio.us/api/tags/get?");

$username = isset($_POST["username"]) ? $_POST["username"] : "nobody";
$password = isset($_POST["password"]) ? $_POST["password"] : "thisiswrong";

$cu = curl_init(_URL_GET_TAGS);
curl_setopt($cu, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cu, CURLOPT_USERPWD, "$username:$password");
curl_setopt($cu, CURLOPT_USERAGENT, "kelvinluck.com del.icio.us poster (PHP-" . phpversion() . ")");

$method_result = curl_exec($cu);
$result_info = curl_getinfo($cu);
curl_close($cu);

switch ($result_info["http_code"]) {
    case 200:
        $p = strpos($method_result, "< ", 1);
        $content = substr($method_result, 0, $p)."<result status=\"1\">\n".substr($method_result, $p)."";
        break;
    case 401:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP401 - Bad login details.\" />";
        break;
    case 503:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP503 -  Gateway timeout.\" />";
        break;
    default:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP".$result_info["http_code"]." -  Unknown.\" />";
        trigger_error("I don't know what to do with http code:".$result_info["http_code"], E_USER_ERROR);
        break;
}

header("Content-Type: text/xml");
echo $content;

Then when you actually post your page the app connects to another PHP script called post_page.php which looks like this:

/**
 * post_page.php
 *
 * Connects to the del.icio.us server and posts a given page to the given
 * user's account.
 *
 * Kelvin Luck < kelvin at kelvinluck dot com >
 * This code is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike License
 * <http ://creativecommons.org/licenses/by-nc-sa/2.0/>
 */


define("_URL_POST", "http://del.icio.us/api/posts/add?");

$username = isset($_POST["username"]) ? $_POST["username"] : "nobody";
$password = isset($_POST["password"]) ? $_POST["password"] : "thisiswrong";

$post_data = array();
$post_data["url"] = isset($_POST["url"]) ? $_POST["url"] : "";
$post_data["description"] = isset($_POST["description"]) ? $_POST["description"] : "";
$post_data["extended"] = isset($_POST["extended"]) ? $_POST["extended"] : "";
$post_data["tags"] = isset($_POST["tags"]) ? $_POST["tags"] : "";

$ch = curl_init(_URL_POST);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_USERAGENT, "kelvinluck.com del.icio.us poster (PHP-" . phpversion() . ")");
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

$method_result = curl_exec($ch);
$result_info = curl_getinfo($ch);
curl_close($ch);

switch ($result_info["http_code"]) {
    case 200:
        $p = strpos($method_result, "< ", 1);
        $content = substr($method_result, 0, $p)."<result status=\"1\">\n".substr($method_result, $p)."";
        break;
    case 401:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP401 - Bad login details.\" />";
        break;
    case 503:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP503 -  Gateway timeout.\" />";
        break;
    default:
        $content = "< ?xml version='1.0' standalone='yes'?><result status=\"0\" message=\"HTTP".$result_info["http_code"]." -  Unknown.\" />";
        trigger_error("I don't know what to do with http code:".$result_info["http_code"], E_USER_ERROR);
        break;
}

header("Content-Type: text/xml");
echo $content;

As you can see, the scripts use the CURL libraries to connect to the del.icio.us server with the relevant access details. They then return some valid XML to the calling flash file.

Now for the Flash file… Since I used components from a commercial library (the BJC Bit Component Set) I can’t actually post the fla file. But you can download the swf in the zip file below and can use it from your own server.

It also accepts an additional parameter: serverPath via FlashVars. This tells it which server to connect to.

If you leave this parameter out or set it to “” then the app will look in the same directory as itself for the get_tags.php and post_page.php pages. If you provide a value for this parameter then the app will prepend this path to it’s requests for the php files.

Here are the files for you to download:

kelvinluck_delicious_poster.zip

You will need one more thing to make the files in the zip work. I use Geoff Stern’s standards compliant JavaScript method of embedding Flash in the page. You will need to download the flashobject.js file from him and place it in /includes/flashobject.js on your web server or else edit line 15 of post.php.

And of course you will need to edit the bookmarklet to point to your server rather than mine.

Good luck and please leave comments with any ideas for improvement or bugs you find.