Blogger Hacks, Categories, Tips & Tricks

Monday, August 07, 2006
Blogger Migration for Delicious and FreshTags
Last weekend, my capacity to spew forth vitriol exceeded my ISP's ability to host it: I'd used up all ten of megabytes allocated to me! So, I set about on a reverse blog migration project, from self-hosting to Blogger's Blog*Spot (where else to get free unlimited blog hosting?). Naturally, my bookmarks on delicious would no longer point to the right place, breaking my blog categories solution (FreshTags). This post explores some of the issues I encountered along the way, plus tips and working code to smooth the transition.

*** UPDATE ***

Please note the methods and code discussed here have been superseded by the Scripted Re-Mark batch editing tool.

First off, the transition on Blogger's end was surprisingly easy: change the settings on the Publish page, nominate a new blog address and re-publish. Easy-peasy. (OK, there was a slight hitch with the baffling failure to re-publish initially when Blogger informed me 004 Login incorrect.. A spot of googling turned up the explanation and very simple fix.)

Next, I needed to ensure my delicious bookmarks pointed at my shiny new Blog*Spot domain. "Why", I thought to myself, "delicious is the premiere bookmark manager - surely updating several hundred links will be a hassle-free pleasure". Hardly. Maybe it's just that I'm an idiot, maybe I just had too big a weekend but, darn it, I couldn't for the life of me figure out how I could effect such a change!

The solution I came up with was to export my bookmarks (as an HTML file), make the simple changes to the URLs of bookmark posts (including archives) via the search-and-replace feature of my text editor (no regular expressions required) and finally re-import them back into my account.

Not bad, I guess. Clumsy, but feasible. I'd give it a C. Then I hit the first hitch.

Hitch #1. Delicious does not support batch delete.

Before I re-import the updated bookmarks, I thought I should delete the old ones. (Delicious can't overwrite them, since it uses the URL - which would have changed - to identify the bookmarks. I would have ended up with both sets, making my job even harder!) I googled around, checked out the API (which needed URLs) and looked at third-party libraries without joy. I resigned myself to clicking the delete button (plus confirmation) several hundred times.

Hitch #2. Delicious will block you if you generate requests too quickly.

Using my patented whirlwind mouse techniques, I was deleting posts off the page at a rate of one or two a second. Delicious does not like this. It will cut you off and lock you out for some ten or fifteen minutes. Apparently, you need to use a delay of ten seconds or more. OK, I could accept five minutes of furious clicking, but counting "one cat-and-dog, two cat-and-dog ... ten cat-and-dog" between clicks would take ages. Not cool.

Peering into the delicious page, I thought I could automate the whole painful process with a bit of javascript (see Code #1 at the end of this post). The idea is to grab all the "delete" links on the page and open them (with a suitable delay) in new windows. Sure, it coud be nicer (perhaps removing the popups), but it works. Just paste the code into your browser bar and press enter. Be warned: it will delete every post on the page, so make sure you are looking only at posts you want to have disappear. (Tip: make sure your browser allows popups on this page!)

Moving along now, I began the import process. Strangely, this takes up to half an hour after you upload the file. Goodness knows why. But, it worked as advertised, retaining tags, notes, dates and even my bundles. Except ...

Hitch #3. Delicious imports are compulsorily marked "not shared".

This means that no one else can see them - and presumably you can't use them to categorise your blog! Again, I couldn't see any mechanism to turn them all off in one hit (and yes, I don't "allow private saves" in my options). This time, I had to have a closer peek at the Ajaxy goodness in the delicious page and, after butchering one of their functions, managed to figure it out. (Please check out Code #2 below.) Paste this code into your browser bar and it will go through the current page, systematically triggering the "shared" option for each post (waiting politely in between).

Finally, it all worked. I was able to get away with a delay of as little as five seconds in both scripts, but I suggest you try it yourself. Even still, allowing for pagination and the various steps, the whole thing took an hour to process some 200+ posts and 40 archive pages, albeit mostly not requiring my attention.

And, yes, if I'd known what was involved I probably would have knocked together a variant on Code #2 to use the post edit function to sequentially edit the URL of each post on the page ... ahhh, the wisdom of hindsight.

So, at the end of this arduous task, I'm left in some doubts as to delicious' claim to be a bookmark manager (as opposed to repository) given the lack of support for basic batch-mode updating, deleting and reloading functions.

Does anyone have some pointers to share on this topic? Is there a secret batch-mode facility available? Has someone knocked together a web-app for doing this? It'd be great to save others the pain of doing this.

Code #1. For deleting (via popups) your delicious posts.

javascript:var delay=10000; var l=new Array(); var a=document.links; for(var i=0; i<a.length; i++) if(a[i]'delete')>0) l.push(a[i].href); alert(l.length); count=0; doPopDel(); function doPopDel(){[count],count,''); count++; if(count<=l.length) setTimeout(doPopDel, delay);}

Code #2. For sharing (via AJAX) your delicious posts.

javascript:var delay=10000; var l=new Array(); var a=document.links; for (var i=0; i<a.length; i++) if(a[i]"share")==0) l.push(a[i]); alert(l.length); count=0; doShareDel(); function doShareDel(){ sharePostYes(l[count].parentNode); count++; if (count<l.length) setTimeout(doShareDel, delay);} function sharePostYes(confirm){ commands = nextElement(confirm), post = confirm.parentNode, share = $('.share', post)[0]; remove(share.previousSibling, share, confirm, $('.private', post)[0]); = 'inline'; var data = getPostData(post); var postBody = 'jump=no&format=none&private=0'; var fields = { description: data.desc, url: data.url, oldurl: data.url, date: data.isoDate, notes: data.notes, tags: data.tags, key: data.key}; for(var i in fields) postBody += '&' + i + '=' + encodeURIComponent(fields[i]); var url = 'http://' + + '/' + Delicious.cuser; new Ajax({url: url, method: 'post', postBody: postBody });}

In both cases, copy and paste the code into the address bar of your browser when you have loaded the appropriate delicious page. Set "delay" to be the duration (in milliseconds) to wait between requests (5-15 seconds should do it). The first alert box is the number of posts it's found. Good luck!

Filed in: , , , ,
Posted at 10:34 AM by Greg.
<    >
Blogger Tor said...
I can only point out that with hitch #3, freedomslut will ask you whether you want to set all of the imported bookmarks as private, public, or shared with watchlist. But that's the only advantage it would have in this process.

<    >
Anonymous Jason said...
THANK YOU for code #2. Months after import was introduced on, and they still haven't made a "make all public" function. I'm too impatient to wait. :)

<    >
Anonymous holy said...
U r the guru of gurus
man of men
u have released my bookmarks from the prison of loneliness
a salute and a hat tip to u

<    >
Blogger Greg said...

Have you checked out Scripted Re-Mark? It has support for setting your bookmarks free, plus other stuff.


<    >
Anonymous Paul Irish said...
thaaaaaaaaaaaank you. this script made my day SOOO much better. :)

<    >
Anonymous Paul Irish said...
I added else alert('done!'); after if (count<l.length) setTimeout(doShareDel, delay); .
This way the script notifies you when it's done with the page.

<    >
Anonymous Adam Pieniazek said...
You just saved me
x =
if(delicious = not shared, +1;otherwise:exit;) hours

Thank you!

<    >
Blogger Gordon said...
Yes! Yes! Batch upload and share".
That's just what I needed! More! should be proud!

<    >
Anonymous Fabian said...
Thanks a lot... this was very, very helpful.

<    >
Anonymous James said...
Thanks for #2! However, it doesn't seem to work for me. Perhaps they have changed delicious to not allow your code? I want to share all of my ~400 bookmarks, Thanks

<    >
Anonymous James said...
My bad, it takes some time and I wasn't waiting for it. THANKS!!!!!!!!!!

<    >
Anonymous General Bordeaux said...
you rock man !!!!
hats off !!!

<    >
Anonymous compwoman said...
Scripted Re-Mark - Batch Editor for Bookmarks:

<    >
Blogger Psychictoad said...
Sweet God, thank you. I just imported years worth of bookmarks and was dreading having to do this.

You rule.

<    >
Anonymous Anonymous said...
WOW, thanks for the code tips. Made delicious bookmarking a lot easier to share all my 200+ bookmarks

<    >
Blogger jerjer said...
I just want to say thanks.

<    >
Anonymous Anonymous said...
Thanks a lot!! I converted all my 900+ bookmarks to public.

Hey! I think I brought delicious down!! I get 999 Yahoo Page..

hhehe.. Thanks

<    >
Anonymous Melissa M. said...
Thanks for #1. I imported my bookmarks from the now-defunct some time ago and needed to clean up a bit (deleting 175+ bookmarks). With no batch delete function this promised to be a painstaking process but thanks to your genius script, all is well now.

<    >
Anonymous Anonymous said...
using code #1 (both in Firefox & Safari), not one but THREE windows popped up for each bookmark in Delicious. After I had consented to deleting the link on the first of the three, the next two would read:
"Problem deleting item: No such item for deletion. Try to delete this item again? Yes No"
but from the address bar I could see it was the same item I had just selected to delete.
this actually made it more time-consuming than using the one at a time deletion on the Delicious page. I was so hopeful for your code.

eXTReMe Tracker