All posts by Sean Hayes

Script to Convert PSD Files to HTML Templates

For a while now I’ve been tinkering with this GIMP Plugin that converts PSD files to HTML templates. There’s been some recent interest in it, so I’ve decided to work on it some more and get a usable release out.

Download psd2html-gimp-plug-in

How do I install/use it?
The project page will have current installation and usage instructions.

What does it do?
The script detects which layers are on top of other layers and what their size and relative positions to each other are. This data is used to arrange the layers into a hierarchy, which can then be expressed as HTML nodes. Each layer is expressed as a <div> element with a unique id based on the layer name, and that id is used to specify the size and position of that element using CSS. Text layers are saved as text within the HTML file, and image layers are extracted to the <template_name>_files/ directory, relative to your PSD file.

Can you port this to Adobe Photoshop?
I think it would be possible to write a similar plugin for Photoshop, but for a large variety of reasons it’s not very practical. Reasons include: GIMP is FOSS and Photoshop is proprietary; GIMP plugins can be written in Python and I think Photoshop plugins have to be in written in C, C++, or Flash/Flex; based on what I’ve read on Adobe’s website I’d need to get their permission; and I don’t have Photoshop. Plus, Photoshop and the development tools I’d need only run on Mac and Windows, and I switched to Ubuntu almost 2 years ago.
I know lots of people prefer Photoshop and hate GIMP. If so you can always do your work in Photoshop and just use GIMP for PSD conversion.


Advice from my Experience with OAuth

I recently finished coding the OAuth authentication method for accessing Picasa photos from within Darkroom. Since it was written client side using JavaScript I was trying to be as minimalist as possible, so I wrote my own minimal implementation rather than using a library. I’m sure most developers using OAuth use a library, which is probably why it’s hard to find advice on writing your own implementation, so I thought I’d share some tips, FAQ style.

Use the right documentation.
There’s a lot of outdated docs out there. I frequently find myself at OAuth Core 1.0 Revision A, and it’s such a pretty page and easy on the eyes, but way at the top where you’re likely to miss it is a notice saying it’s obsolete. The notice says to use RFC 5849: The OAuth 1.0 Protocol and, although hideous, it’s up to date and more complete.

How’s the signature algorithm written?
Here’s some pseudo-code:

If you’re writing in JavaScript as well I recommend Crypto-JS.

What’s the format for the timestamp?
It’s just a UNIX timestamp (in seconds).

How do I generate a nonce value?
The OAuth spec just says it’s a random string. I think the Google documentation says something about using a string representation of a 64 bit integer. I had no idea what they were talking about, but somewhere I read you just need to md5 hash a random integer, and it worked for me.

If developing for a Google service, use their OAuth playground.
Their OAuth Playground is a great way to see the process you have to go through and what the requests look like. If trying to authenticate with another provider see if they also have an API test app.

Don’t expect detailed errors.
You’ll be lucky if the response tells you “signature invalid”, but you won’t be told what’s wrong with it. My strategy was to compare my signatures and parameters to those used by the Google Playground; taking values from there that you know are valid and using them to test your code is a good way to debug.

The scope parameter has to EXACTLY match the URLs used in your API calls
In the Google OAuth Playground, selecting “Picasa Web” will input “; for the scope. Note the use of https:// for the protocol. If you make API calls using that URL, it will fail since none of the Picasa services are served over https. If you try to make calls using regular http you will get an OAuth error saying invalid scope. In order for it all to work, you have to use “; for the scope.

Setting up SSL on Apache

While locally testing Darkroom over HTTPS, Firefox gave me the following error: “Error code: ssl_error_rx_record_too_long”. Turns out I’d never configured the Apache instance on my laptop to use SSL.

Once you’ve got the right information it’s really quick to fix. Here’s 2 links that I found helpful:

Generating an SSL Certificate with Apache+mod_ssl
Has the commands you need for generating a self signed certificate.

If while generating the certificate you get the error “unable to write ‘random state'”, you’ll need to chown the .rnd file (sudo chown user:group ~/.rnd) and try again.
I put all the generated files in /etc/apache2/ssl/.

How to get Apache to do both HTTP and HTTPS on one IP address?
Shows the basic Apache configuration needed for HTTPS. To get HTTPS working, I just copied my existing virtual host definition, modified it to use the port 443, and added the SSLEngine, SSLCertificateFile, and SSLCertificateKeyFile directives.

Here’s a copy of my file:

MugTug Darkroom, Online/Offline Photo Editing

For those of you who don’t know, a few weeks ago I joined a project called Darkroom from It’s an image processing application using cutting edge HTML 5 features such as the <canvas> element, localStorage, and application cache, and all the editing (and most of the GUI) is done client side using JavaScript, so it works even without an Internet connection.

Yesterday it was demoed during the Google I/O 2010 Keynote Speech:

There’s currently a development version live, feel free to visit the site and try it out!

Fixing Flash

After upgrading Ubuntu I had some problems with Flash not working. I read the following threads and combined information from both to solve my problem:

Run the following commands in a terminal to remove existing Flash files:

sudo apt-get remove -y –purge flashplugin-nonfree gnash gnash-common mozilla-plugin-gnash swfdec-mozilla libflashsupport nspluginwrapper
sudo rm -f /usr/lib/mozilla/plugins/*flash*
sudo rm -f ~/.mozilla/plugins/*flash*
sudo rm -f /usr/lib/firefox/plugins/*flash*
sudo rm -f /usr/lib/firefox-addons/plugins/*flash*
sudo rm -rfd /usr/lib/nspluginwrapper
sudo rm -rf /usr/lib/flashplugin*

Then run the following command to install the correct version of Flash:

sudo apt-get install flashplugin-installer

Using a Test Database in Django

At Govnex we’re using MySQL on our development machines. It has several advantages, but one of the drawbacks is unittests run slower when not using Sqlite (big ups to MockSoul for posting his benchmarks). The reason for this is when running unittests in Django with a Sqlite database, the database is run in memory (RAM) instead of being written to the disk.

Django only allows you to specify one database, and although a new database is created for unittests, it still uses most of the same settings (auto prepending “test_” to the database name), which means a Django install using MySQL also uses MySQL for unittests.

To get around this problem, I created a file in my project root called containing the following lines:

I then opened my, imported sys, and inserted the following lines at the end of the file:

If one of the command line arguments is “test”, that means a unittest is being run, in which case Django will attempt to import, which will override the database settings and use Sqlite instead. Migrations won’t be an issue, since Django South uses the old syncdb command for generating databases for unittests.

Hope this helps you save some time testing.

Web Dev Bash Utils

I’ve just open sourced these bash scripts I wrote for web development. They’re available on GitHub.

Unfortunately they were written for use on a strict Unix environment with an outdated version of bash and without the benefit of GNU extensions (I was not the administrator), so they don’t currently work on Linux. My next step is to port them to Linux, and any help would be appreciated.

Update: I’ve seen some recent traffic to this post, and I wanted to let everyone know that this project has been taken down from GitHub. I didn’t have the time to port it to the GNU/Linux version of Bash, I didn’t really need the scripts anymore (if I did I’d rewrite them in Python, maybe using Fabric), and no one seemed interested in them, so I thought it would be better to take it down than leave a substandard, mostly unusable project on my GitHub profile.

Whitespace Management: Use Tabs, Spaces Considered Harmful

At one of my previous jobs I worked on dozens of websites that had been created by other people. I prefer to use tabs instead of spaces when indenting code, and I can get a little OCD sometimes, so every time I edited a file I would do a search and replace to change every 4 spaces to a tab character. I didn’t like the idea of having some files use spaces while others used tabs, so when I wrote a bash script for recursively searching and replacing inside text files throughout an entire directory structure, I added some code that would clean up the white space as well. The actions it performed were:

  • Converting from Windows (“rn”) or Mac (“r” on older versions) end of line encodings to Unix style encodings (just “n”)
  • Removing trailing whitespace from the end of lines
  • Condensing multiple blank lines to single blank lines
  • And most importantly, converting every 4 spaces to a tab character

I had anticipated that this would save some disk space, but I was surprised by how much; after running the bash script, the total size of each website would decrease by 10-50% (that’s not a typo, fifty), and that’s including binary files such as images and PDFs which were unchanged. Think about the impact that has. Every individual whitespace character takes up 1 byte, bytes which have to be stored on disk, loaded into memory, transferred over a network, loaded into the client’s memory, and iterated past when it gets processed by the browser. Whitespace management saves:

  • Disk Space
  • RAM
  • Processing Power
  • Bandwidth

which in turn helps save:

  • Money
  • Electricity
  • the Environment

It also helps you provide a better user experience. When browsing the Internet, I’d much rather download a 5KB HTML file than a 10KB one, since it’ll download faster and render faster.
(On a side note, generally these are all also benefits of writing standards compliant, semantic XHTML with external CSS and JS.)

Another reason I prefer tabs to spaces is, when browsing code it’s easier to tell if the proper levels of indentation are being used. If there’s one space missing or one additional space it can sometimes be hard to tell, but if a tab character is missing it’s very obvious. Also, most text editors allow you to specify how wide a tab character should be displayed, so if one developer likes 8 space indentation width, another likes 4 spaces, and another likes 2 spaces, they can all use the same code containing tabs and configure their respective editors to display the tab character at their preferred width. If you were to use 4 space characters for each indentation level, the developers who like 8 and 2 spaces are forced to use it as well.

Survey of Best Programming Practices

I was having a talk today with some colleagues about the scarcity of web developers, and even software engineers, who use best practices such as:

  • using version control
  • using a bug tracker
  • writing unit tests
  • using a programming framework

In all honesty, I didn’t do any of these before my current job at Govnex (aside from a little dabbling with CakePHP), nobody at my first 2 web development jobs did any of these, and we didn’t learn about any of this stuff in college. As far as I know, nobody I knew at RIT followed these practices except for maybe using a framework. Of all the job descriptions I’ve read in the past few years, only a handful mentioned using a framework, and only a couple mentioned anything about unit tests or version control; none of them mentioned the use of bug tracking software. One of my colleagues said that these practices are common among all developers, while my other colleague agreed with me that they’re hard to find.

What do you think? I’ve created a 6 question Google Apps form for collecting survey data and made the results public, it would be a big help if you could fill it out. Afterwards, please share your comments below.