Wednesday, January 28, 2009

Ruby Script to Inline JavaScript and CSS

MySpace requires that OpenSocial applications don’t reference external JavaScript and CSS files in the profile view. Of course from a “I’m a spiffy developer that neatly separates all his files” point of view inlining JavaScript and CSS is a Bad Thing®. From a performance point of view, inlining stuff often makes a lot of sense.

So what are we to do?

Well, I just wrote a small Ruby script that understands inline markers like ###inline=somefile.js in your HTML/OpenSocial/XML/Whatever file. Yes, I could have used ERB or something else, but I felt like writing my own ;-). You just put code like this into your file:

<script type="text/javascript">
###inline=scripts.js
</script>
<style type="text/css">
###inline=styles.css
</style>

Then, assuming that your file is called “template.xml”, running it through inliner.rb like this…

ruby inliner.rb template.xml inlined_output.xml

…will result in one file with both your JavaScript and your CSS files inlined.

Here’s the code:

Oh, and with this little snippet you can even inline binary images:

Enjoy!

Monday, January 26, 2009

"item" is a Reserved Word in Internet Explorer 6 and 7

Arg! I know every web developer hates the IE. But sometimes the reasons why we hate it so much become so painfully obvious again. Like today. I've been working on an OpenSocial application and while testing it in IE, I got this strange message:

"Object doesn't support this action"

Then a line number, no script name and just an unselectable, unclickable, uncopiable (I know, I just made all those words up) URL. How helpful.

So first I needed some sort of JS debugging in IE. I went with Companion.JS. It's pretty useful, but of course no comparison with Firebug. I first tried using Firebug Lite, which is really cool, but it didn't work on MySpace (where I had to test my OpenSocial app). By the way, the Microsoft Script Debugger - which is needed by Companion.JS - doesn't install on Vista, of course. It did work on Windows XP, though.

So equipped with a JavaScript debugger, I investigated the error again and actually got a filename and a line number that was useful. This was the offending code:

for (var i = 0; i < json.items.length; i++) {
item = json.items[i]; // more code...
}
It turns out that "item" is a reserved keyword in Internet Explorer. Entering
javascript:alert(item);
in the IE address bar greets you with an [object] alert. This blog post by Sandro confirms this. So all I had to do was rename all instances of "item" to something else.

Thursday, January 15, 2009

Barcode Recognition with Google's ZXing on the Mac with TIFF Support

Have you checked out Google's great open source barcode recognition library called ZXing ("zebra crossing")? It's really powerful, free and (halfway) platform independent since it's written in Java. If you're a Mac user, it might be a little tricky to get the JavaSE version to run, though. The core part of the library has a WTK (wireless toolkit) dependency, but there's no WTK for the Mac. The good news is: you don't need the _wireless_ toolkit if you want to run this thing on your desktop machine. So how do you get it to compile on your Mac? Easy:

  1. Download ZXing
  2. Unpack it.
  3. Read this post
  4. ... or just download my modified build.xml file and put it in core/build.xml
  5. Change into core and run ant
  6. Change into javase and run ant
  7. Change into the zxing root and try running the command line client:
    java -cp javase/javase.jar:core/core.jar com.google.zxing.client.j2se.CommandLineRunner http://www.idautomation.com/ucc_ean_128.jpeg
    The result should look like this:
    Raw result:
    81007123452112345678
    Parsed result:
    81007123452112345678
    
  8. Rejoice.
OK, so this works. But I had to get the barcode from the first page of a multipage TIFF file. That didn't work. But it was easy to fix. I had to modify javase/src/com/google/zxing/client/j2se/CommandLineRunner.java a little bit.
I imported some JAI packages:
import javax.media.jai.*;
import com.sun.media.jai.codec.*;
And I changed one line in the static decode method from
image = ImageIO.read(uri.toURL());
to
PlanarImage pi = JAI.create("URL", uri.toURL());
image = pi.getAsBufferedImage();
(If you're too lazy to type that, get the file here)
Now just save the file, change back into the javase directory and run ant again. Now you should be able to decode barcodes in TIFF files as well. You might have to add the "--try_harder" argument to the CommandLineRunner, though. Without it, it didn't find the barcode in my TIFF file.
I'm not sure if it scans every page of the TIFF for a barcode or just the first. If you need to access a specific page, check out this code and this code to turn a RenderedImage into a BufferedImage.
Now enjoy your Mac-TIFF-barcode-reading awesomeness. 

Tuesday, January 13, 2009

IBM DB2 on the Mac with Ruby, Rails and Radiant

Last year ended with an amazing announcement: IBM DB2 for the Mac! I have worked with DB2 for years and it's a truly great database. Who would have thought that Big Brother would bring one of it's flagship products to the Mac? And not (directly) to make money, but only for us developers?

Ok, so how do you set this thing up? Well, I won't walk you through it step by step, but I'll give you the big steps you'll have to take:
  1. Download DB2 for Mac.
  2. Follow this PDF guide.
  3. Follow the instructions in this blog post to install the IBM DB2 Ruby Gem.
Those are the big steps. But I ran into a few minor problems on my machine. So in case you run into them as well, here's how to solve them.
Problem #1 - Error SQL1205N when running db2sampl
When I tried to create the SAMPLE database with the db2sampl command, I got this error:
Attempt to create the database “SAMPLE” failed. SQL1205N The code page “1208″ and/or territory code “0″ that has been specified is not valid.
Obviously this had to do with my code page. Adding these two lines to my .profile file solved the problem:
export LC_ALL=en_EN.UTF-8 export LANG=en_EN.UTF-8
Don't forget to source your .profile file and you'll be good to go.
Problem #2 - SQL30082N - ROOT CAPABILITY REQUIRED
I got this error when I tried to run the sample Ruby app from the blog post that tries to connect to the SAMPLE database via the ibm_db Ruby Gem. This is what it spat out:
Connection error: [IBM][CLI Driver] SQL30082N Security processing failed with reason "42" ("ROOT CAPABILITY REQUIRED"). SQLSTATE=08001 SQLCODE=-30082
The solution: Stop the DB2 server with the db2stop command and restart it with 
sudo db2start
Since DB2 uses OS authentication and the DB2 server is started without superuser privileges right after the installation, it can't authenticate other users. So you'll have to run it as a superuser.
So now we can get to what I actually wanted to try: Running the Radiant CMS on a DB2 database. These are the steps:
  1. sudo gem install radiant    (it's version 0.6.9 as of this writing)
  2. Create a new radiant app:
    radiant mygreatapp
  3. Edit config/database.yml We'll only edit the development section. Make it look like this:
    development:
    adapter:     ibm_db
    username:    your_username
    password:    your_password
    database:    db2_dev
  4. Create the database (note: it's name cannot be longer than 8 chars!)
    db2 create database db2_dev
  5. Freeze Radiant to the vendor dir (we'll have to edit it):
    rake radiant:freeze:gems
  6. OK, when the ibm_db gem can't rename columns. So we'll have to use this really ugly hack: Delete all the 21 migrations in the vendor/radiant/db/migrate directory and place this single migration file in there:
  7. Now run rake db:bootstrap
  8. Start the app with ruby script/server
  9. Go to http://localhost:3000/admin and login with admin/radiant
  10. You should be able to use your Radiant CMS now, running on DB2!
This is still pretty raw and I'll post this to the Radiant mailing list, so we can get better DB2 support built right in.