I had the idea that I might photo blog more if there was an easy way to get photos off my iPhone and into a blog post. The easiest way would be to e-mail the photo someplace for WordPress to get it. Unfortunately, most of the e-mail to blog post plugins (and the built-in stuff) just sucks for my need.
I decided to look at the XML-RPC API to see if I could get it done that way, and then write a script to be called out of procmail to create the mail. There is a function there that will do what I want, wp.uploadFile aka metaWeblog.newMediaObject. The specification for that call says that the file being uploaded must be Base64 encoded. No problem, a few line of ruby later and I have everything ready to test an upload. The file goes up, but its unviewable in a browser. A quick check of the file on the server and its revealed to be a text file filled with Baes64 looking data. Somewhere along the line it wasn’t being decoded.
After about an hour of screwing around, I determined it wasn’t anything obvious in my code, so I thought I’d look at the code for WordPress 2.5.1 to see if I missed anything obvious. In reading their code, I found that the WordPress folks forgot something obvious, their code never Base64 decodes it before it writes it to a file. A quick one-line change later, and *boom* I’m off.
Here’s the patch in case its useful to anyone else. I’ll have the script up when I’m done with it.
(Also, in a small bit of embarrassment, I must admit fixing this took me 10 minutes longer than it should because I forgot ; is end of statement in PHP.)
Index: xmlrpc.php
===================================================================
--- xmlrpc.php (revision 7840)
+++ xmlrpc.php (working copy)
@@ -1880,6 +1880,10 @@
$name = "wpid{$old_file->ID}-{$filename}";
}
+ # The specification says that this is base64 encoded,
+ # we should really decode it.
+ $bits = base64_decode($bits);
+
$upload = wp_upload_bits($name, $type, $bits);
if ( ! empty($upload['error']) ) {
$errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);