(archive 'newLISPer)

June 16, 2007

Posting to Google Blogger using newLISP

Filed under: newLISP — newlisper @ 17:15

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:

  '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">
</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
    (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
    (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))

And if you’re reading this, it must work!


June 15, 2007

map frenzy

Filed under: newLISP — newlisper @ 21:47

Faced with the task of getting the integer values out of this list of strings returned by a shell command:

("/Users/me/Pictures/image1.jpg" " pixelWidth: 450" " pixelHeight: 375"))

I ended up writing this:

(map 'set '( width height) (map int (map last (map parse (rest image-data)))))

It looks a bit odd, repeating the map four times. But I think it’s nice, too.

Yes, it’s a short post. I’m just testing the new Google/Blogger (Bloogle? Goggle?) API.

June 10, 2007

A passing phase

Filed under: newLISP — newlisper @ 17:42

I know enough newLISP to be dangerous. I’ve got to the stage where I’m not thinking about the language too much, but concentrating on the problem in front of me. This is probably as close as I’ll get to ‘programming’, although I wish there was a more suitable verb than that to describe it. It’s not ‘hacking’, which implies (to me) a bit of serious skill. Perhaps ‘kludging’ is a better word.

Whatever it’s called, it’s good to be able to solve practical programming problems with relative ease. When I was writing AppleScripts, I was always hitting restrictions: “Now we’ll just sort the list. Oh, there’s no sort function. I’ll have to write my own.” Or “Finally we’ll replace all those spaces with a – oh, there’s no search and replace function either.” Using newLISP, the only restriction I regularly encounter is my own limited skill as a programmer. There are very few basic tasks that you can’t do with newLISP’s built-in library.

To give an example, I recently ran off some printed calendars showing the moon phase for each day of the year. This is June’s page:

This isn’t a task that taxes newLISP of course. But it took a few hours of kludging to get the equations to generate the correct answers, and another hour or so of kludging to figure out the PostScript required to do the drawing. The script(s) started off being quite well organized, but in the rush towards the deadline I confess that the quality control went out the window. As I inserted more and more adjustments and fixes, it looked like it was going to end in a mess of spaghetti. Eventually it got to the stage where I didn’t want to touch certain bits of code in case it fell apart! I don’t want to look at some parts of it…

Probably not production code, then. :-)

Now that I’ve finished, I should, of course, go back and rewrite it all from scratch, and design it in a more structured function before coding it. But I suspect that’s not going to happen.

This function, at least, doesn’t look too bad. It draws a moon, given a radius (pixels), phase (degrees), declination, and angle:

(define (draw-moon radius ph decl (angle 0))
    ; draw moon at current x-pos and y-pos
          (add x-pos  (div box-half-width 2)))
          (add y-pos  (div decl 10) (div box-half-height 2)))
        (phase (mod (int ph 0 10) 360))) 
; start (ps (format {gsave})) (ps (format {%f %f translate} moon-centre-x moon-centre-y)) (ps (format {%f rotate } angle))

; draw dark coloured background (set-backgroundcolour) (ps (format {%f %f %f %f rectfill } (mul -1 *box-half-width*) (mul -1 *box-half-height*) (mul 2 *box-half-width*) (mul 2 *box-half-height*))) ; draw phase (cond ((or (= phase 0) (= phase 360)) ; new moon (set-mask-colour) (ps (format {newpath %f %f %f 360 0 arcn fill} 0 0 radius))) ((and (> phase 0) (<= phase 90)) ; waxing to first quarter (set-moon-colour) (ps (format {newpath %f %f %f 90 270 arcn fill} 0 0 radius)) (set-mask-colour) (set 'moon-width (mul radius (div (sub 90 phase) 90))) (ps (format {newpath %f %f %f %f %f %f ellipse fill} 0 0 moon-width radius 0 360))) ((and (> phase 90) (< phase 180)) ; half to full (set-moon-colour) (ps (format {newpath %f %f %f 90 270 arcn fill} 0 0 radius)) (set 'moon-width (mul radius (div (sub 90 phase) 90))) (ps (format {newpath %f %f %f %f %f %f ellipse fill} 0 0 moon-width radius 0 360))) ((= phase 180) (set-moon-colour) (ps (format {newpath %f %f %f 270 90 arcn fill} 0 0 radius)) (set 'moon-width (mul radius 2 (div phase 360))) (ps (format {newpath %f %f %f %f %f %f ellipse fill} 0 0 moon-width radius 0 360))) ((and (> phase 180) (<= phase 270)) ; waning full to half (set-moon-colour) (ps (format {newpath %f %f %f 270 90 arcn fill} 0 0 radius)) (set 'moon-width (mul radius (div (sub 90 (mod phase 180)) 90))) (ps (format {newpath %f %f %f %f %f %f ellipse fill} 0 0 moon-width radius 0 360))) ((and (> phase 270) (< phase 360)) ; waning to new (set-moon-colour) (ps (format {newpath %f %f %f 270 90 arcn fill} 0 0 radius)) (set 'moon-width (mul radius (div (sub 90 (mod phase 180)) 90))) (set-mask-colour) (ps (format {newpath %f %f %f %f %f %f ellipse fill} 0 0 moon-width radius 0 360)))) (ps {grestore})))

This function draws the moon’s phase using circular arcs and ellipses – this is probably not scientifically accurate, but sufficient, at least graphically for my purposes. I was struggling to find a way to draw crescents and bulging moons, but then I realised that I could just draw ellipses and circles on top of each other to get shapes which looked OK.

At first, each square had more astronomical data in it, and the moon was drawn at an angle, because the “position angle of the bright limb”, as it’s called, can be calculated with reasonable accuracy. Unfortunately, I had trouble getting accurate results, and couldn’t make it work graphically in time for my deadline.

The thing that occurs to me, though, is that I’m not being distracted by the language I’m using (even though I’m not using it that wisely), but thinking solely about the task in hand.

Blog at WordPress.com.