Posting to Google Blogger using newLISP
That's a boring title, and this isn't going to be a very interesting post... It explains how to post entries to Google/Blogger blogs using any text editor and newLISP.
I'd like to run this blog on newLISP, of course, but that means finding another host, and one of the good things about writing on Blogger is that it's free. So for a while I'm going to continue updating this Blogger blog. The new Google API is well documented, but of course it's assumed that you're a .NET, Python, or PHP programmer - strangely no newLISP support? Still, we can help out the billion-dollar company a bit here, as we're feeling generous.
I write these posts using John Gruber's excellent Markdown format, then run it through Markdown using a system service. This means that I can write the text in any application I want (except for a few applications that don't support Services). The hard part, then, is to take the HTML-formatted content and deliver it to Blogger.
Unfortunately, we don't seem to be able to use newLISP's post-url function, because Google's interface uses https. But there's another way. First, specify the blog's details:
#!/usr/bin/newlisp (set 'post-body "" 'post-title "untitled" 'post-author "fred" 'post-email "fred%40fred.com" ; encoded... 'password "secret" 'url "http://www.blogger.com/feeds/whatever/posts/default" ; blog id number 'temp-file "/tmp/blogpost.xml")
Now we're ready to read the HTML input. We want a title, so look for an h1 tag that will be used as the title:
; get title and body of the post from the file in argument 2 (set 'file (open ((main-args) 2) "read")) (while (read-line file) (println (current-line)) (if (regex "(<h1.*>)(.+)(</h1>)" (current-line) 0) ; look for h1 tag for title (set 'post-title $2) (if (!= (current-line) "" ) (push (string (current-line) "\n") post-body -1)))) (close file)
Store the text in a temporary file, enclosed in an XML wrapper:
(set 'content (format [text]<entry xmlns='http://www.w3.org/2005/Atom'> <title type='text'>%s</title> <content type='xhtml'> <div xmlns="http://www.w3.org/1999/xhtml"> %s </div> </content> <author> <name>%s</name> <email>%s</email> </author> </entry>[/text] post-title post-body post-author post-email)) (write-file temp-file content)
We'll need the length, too.
(set 'content-length (string (length content)))
Next, use curl to get some authorization information:
(set 'the-authorization-command (string (format "curl -s -d Email=%s -d Passwd=%s -d service=blogger -d source=newlisp-textwrangler https://www.google.com/accounts/ClientLogin" post-email password))) (set 'authorization (replace "Auth=" (last (exec the-authorization-command)) ""))
The curl command returns some heavy duty hexadecimal strings - we just want the last one. When I use shell commands, I usually build the command string first, then run it in a separate exec call. This allows me to print the command instead of running it, while I'm getting all the escaping and quoting right.
Now we can post that XML file, using the authorization code we got earlier:
(set 'the-post-command (string (format "curl -v -X POST --data-binary @/tmp/blogpost.xml -H \"Content-type: application/atom+xml\" -H \"Content-Length: %s\" -H \"Authorization: GoogleLogin auth=%s\" %s" content-length authorization url))) (set 'post (exec the-post-command)) (exit)
And if you're reading this, it must work!