Friday, February 01, 2008

Post to instapaper (AppleScript)

Update (26-Jun-09): This script doesn't handle more recent versions of InstaPaper very nicely. Another NNW-to-InstaPaper script, "NNWInstaPost", has appeared in the meantime and I suggest that you give that one a try ...


Here's a little script to post the currently selected headline in NetNewsWire (my favourite Mac OS X newsfeed reader) to your instapaper account.

You need to create an instapaper account before using this the first time. The script is not very good about errors, so just correct the issue and retry the script. It creates a short summary by "un-HTML'ing" the description, but it does this naively (using a long sed invocation), so it's restricted to a subset of HTML entities -- basically common Western ones.

To install this, select and copy the script from the box, paste it into the AppleScript Script Editor and drop it into NNW's script folder.

(*
* Submit NetNewsWire headines to instapaper for later reading. See http://www.instapaper.com/
* Create an instapaper account first, select a news item in NNW, then run this script.
* Assumes you're using Safari. Doesn't handle all html entities; works best on English feeds.
* Doesn't check if the submission succeeded, so you need to keep your eyes open. :-)
* -- Bruce Walker <bruce.walker@gmail.com> -- Feb 1, 2008
*)

on unhtml(html)
-- remove markup, convert common entities to ascii (the rest to "?"), nuke blank lines & restrict length
return do shell script "echo " & quoted form of html & "| sed -e 's/<[^>]*>//g' -e 's/&nbsp;/ /g' -e 's/&mdash;/--/g' -e 's/&lsquo;/`/g' -e 's/&ldquo;/``/g' -e 's/&#8220;/``/g' -e \"s/&rdquo;/''/g\" -e \"s/&#8221;/''/g\" -e \"s/&#8217;/'/g\" -e \"s/&rsquo;/'/g\" -e \"s/&#39;/'/g\" -e 's/&[^;][^;][^;]*;/?/g' -e \"s/'/\\\\\\'/g\" | tr '\\r\\n' ' ' | dd ibs=1 count=192"
end unhtml

tell application "NetNewsWire"
set NNWURL to URL of selectedHeadline
set NNWTitle to my unhtml(get title of selectedHeadline)
set NNWSummary to my unhtml(get description of selectedHeadline) & " …"
end tell

tell application "Safari"
-- submit to instapaper using Safari's saved session/account cookies
set foo to do JavaScript "window.open('http://www.instapaper.com/b?v=3&u='+encodeURIComponent('" & NNWURL & "')+'&t='+encodeURIComponent('" & NNWTitle & "')+'&s='+encodeURIComponent('" & NNWSummary & "'),'t','toolbar=0,resizable=0,status=1,width=250,height=150')" in document 1
end tell

Enjoy!

11 comments:

Fjord said...

Were you reading my mind? I've been looking for this solution for a couple days now, and almost gave up. Works like a charm. Thanks for sharing this!

Pp Nunez said...

How do I install this? I'm new to nnw.

Bruce Walker said...

@Pp Nunez: to install this:

1) select all the text in the box above and Copy it
2) open Applications -> AppleScript -> Script Editor
3) paste the text into a new script edit window
4) Compile
5) Save As ... onto your Desktop; call it Post to instapaper (File Format: Script)
6) in NetNewsWire choose Open Scripts Folder from the scripting menu
7) drag the newly-saved script from the desktop to the NNW scripts folder

You can run the script directly from NNW's script menu now.

Cheers!

David said...

Thanks, Bruce!

Now, if there were a way to put this into the toolbar or tie it to a simple keystroke, my happiness would be complete.

-- David Singer (http://readthisblog.net)

Bruce Walker said...

I just noticed that the script got mangled by Blogger while I was creating the HTML. I have reposted it corrected, so if you grabbed it before 7:00 PM EST, then you might want to resnarf and recreate it.

The mangled HTML will affect translating HTML entities (basically I didn't properly escape ampersands -- d'oh!).

Enjoy!

John said...

Works great, thanks, but have noticed that it fails if Safari is open with no windows.

wm said...

Bruce - THANKS!!!!!! Like several of the others, I've been wishing for this for several days too.

To David - I've snapped this into QuickSilver with a trigger, and now just one keystroke sends to Instapaper.

I can indeed verify that it's not happy unless a Safari window is open. Of course the workaround is easy enough - make sure a Safari window is open. :-)

Mike Cosentino said...

Thanks for the AppleScript. I was about to create my own and then I found yours.

Instapaper made a few changes recently and thus your script needs to be changed a little.

In your Instapaper Read Later bookmarklet there is a part that says "v=4&k=[NUMBERS]&u. . . "
Copy the v= part until the &u and paste that into this script replacing your v3=.

A basic work around for the required Safari window is to paste the following before set foo to do. . .

set allWindows to (every window where visible is true)
set n to count of allWindows
if n = 0 then
tell application "Safari"
make new document with properties {URL:"about:blank"}
end tell
end if

It's a little rough around the edges since it creates a Safari window and then another one gets created for Instapaper, but it's the best I could do in 5 minutes.

Bruce Walker said...

@mike cosentino: thanks for the comments!

Yeah, I was aware of the Instapaper security change right after he enabled it. I really hoped I could figure out a simple way to change my script so it would easily adapt to the new protocol, but so far it has eluded me.

The problem with trying to explain how to inspect the new bookmarklet and extracting the hash code from it, then editing the AppleScript to insert it is that it will throw most casual Mac users for a loop! Developers don't mind of course.

When I get a chance I'm going to fiddle with it some more. If I produce Post-to-Instapaper Mark II, I'll incorporate your suggestion as well.

Thanks!

UCTLand said...

Those of us using Firefox can use the below... You just have to change the javascript portion....

at tell application "Safari", remove everything but end tell and replace it with:

"
tell application "Firefox"
display dialog (get «class curl» of window 1)
Get URL "window.open('http://www.instapaper.com/b?v=3&u='+encodeURIComponent('" & NNWURL & "')+'&t='+encodeURIComponent('" & NNWTitle & "')+'&s='+encodeURIComponent('" & NNWSummary & "'),'t','toolbar=0,resizable=0,status=1,width=250,height=150')"
"

Kevin said...

Thanks a lot !

That's exactly what I needed !