New Client Site: TABBForum

| |

Tabb ForumIf you’re interested in capital markets, check out our newest client site, Tabb Forum.

Streamlining Drupal updates

| |

We don’t run many Drupal sites, but there are enough of them. I wish the upgrade path for Drupal was as easy as Wordpress’s svn-based upgrades, but I’ve borrowed some ideas from Rails and Capistrano to make my process a little quicker than it might be otherwise.

Each Drupal upgrade provides a zip file (unless you’re working with CVS and frankly I’d rather not). Each of our Drupal sites has its own user, and the site root lives in the home directory of that user (e.g. ~/public_html or ~/www.) I started by unzipping each version of Drupal independently in the home directories (e.g. ~/drupal-6.14, ~/drupal-6.15.) Then I would make public_html a symbolic link to that directory. This meant I could “flip the switch” between versions with one command:

$ rm public_html && ln -s drupal-6.15 public_html

Still, I needed to copy a bunch of site-dependent files (e.g. the drupal/sites/* files, among others) between the old versions and the new, and that was getting tedious. So finally I created a shared directory, ~/shared/ with all the site-dependent files. This served to take those files out of the “deploy path”. Now I can use symlinks to install them in each new version in turn:

$ cd ~/drupal-6.15/sites/all/ && ln -s ~/shared/sites/all/* ./
$ cd ~/drupal-6.15/sites/default && ln -s ~/shared/sites/default/* ./
$ cd ~/drupal-6.15/themes && ln -s ~/shared/themes/* ./

Undoubtedly someone has already scripted this stuff, but I was pretty proud of it so maybe it will be useful to someone else. (There’s always Deploying Drupal with Capistrano, but I think that’s solving a slightly different problem.)

Python package trouble? Check your python

| |

This is exactly the sort of low-level stuff you’d think everyone should know, but I searched an error message today and didn’t get a useful answer. I found one, so here it is for the next searcher.

If you’re trying to build a Python package (in my case, the ReportLab toolkit), and your build fails with a string of error messages starting with Python.h: No such file or directory, the problem is that the package includes some amount of code which is written in C. The build is trying to compile that code, and the C compiler is looking for the Python C headers, and for most Linux users (I ran in to this on an Ubuntu system) the C headers aren’t part of the core Python package. You need the python-dev package. Try this:

sudo apt-get install python-dev

Then try your build again; I bet it will work.

YouthBuild Providence launches!

| |
YouthBuild Home Page

YouthBuild Home Page

In conjunction with the fabulous design team at PopKitchen, we’re delighted to announce the debut of YouthBuild Providence’s brand new website!

It’s always fun to be on board from kick-off to launch, and this was no exception.

Set 3 Breakpoints at org.spring.EyeOfNewt…

| |

It’s kind of a cryptic procedure, but this method really works for debugging the mysterious “SEVERE: Error listenerStart” I’ve been getting when a Spring app fails to load.

Physical addresses and SEO

| |

We only have our tongue a little bit in cheek when we say if you really want to improve your search engine results, you might want to consider relocating.

By way of example, let’s consider what happens when you search for “web development” near Amherst, MA. Google Maps shows results ordered by proximity to the center of town, and guess which web development company has an office closest to the center of Amherst?

When the Amherst College development offices move on-campus, there will be some closer-to-the-center addresses available, just in case you thought geography was irrelevant in today’s virtual world.

Clean out role-user mailboxes

| |

I suppose the subtitle to this post could be, “why you don’t want to be a mail administrator.” The fact is, spam has made running a host which accepts email a pretty unpleasant task all around, and we strongly suggest clients we host domains for run email for that domain through Google Apps rather than relying on POP/IMAP through our host.

We do still have a box which accepts incoming SMTP, though, and that means putting up with a certain amount of unsolicited commercial overhead. Every Linux box has a certain number of no-shell users set up to run daemons with limited privilege, e.g. the apache user. Oddly, some spammers either run the same username scans as the brute-force ssh hackers, or they think the apache user is actually reading its email. I found 44MB of unread email, about 5,000 messages, waiting in that inbox. uucp had the next biggest collection; mail and news were right up there as well.

That’s a lot of disk space. After a cursory glance to ensure there was nothing actually important in there, I simply used sudo cp /dev/null /var/spool/mail/apache to take out the trash.

If you are root or have appropriate sudo privileges, you can check another user’s mail using mutt or a similar command-line mail client. Just use the -f flag to feed mutt a mailbox path as an argument. In this case, I could check the apache mailbox using sudo mutt -f /var/spool/mail/apache . Naturally, you would want to have a talk with your company ethicist before doing this on a mailbox belonging to an actual user.

The best shortcut here is to bounce any email destined for the role users. This will vary depending on your MTA, so I won’t detail it here.

XSL namespaces for HTML output

| |

One of our current projects involves an application where certain PHP scripts request XML from a SOAP service, then use XSL templates combined with parameters set by the PHP script to generate XHTML from that XML.  (Follow that? If not, you may be able to safely skip this.) We haven’t had to cope with setting up this system, but we did have to update the HTML produced by the XSLT, if that’s the proper verb.

The problem we ran in to was getting around Internet Explorer’s quirks mode. The original XSL templates use a bare xsl:output tag with few options, and a bare html tag to start the output code as well, like this:

<xsl:output method="html" indent="yes"/>
<html>

This produces HTML with no document type and no XML namespace, which means IE is going to go to Quirks Mode, which we don’t want because it hurts our carefully-crafted CSS. We want something more like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:
lang="en" lang="en">

First, we tried just adding the xmlns attributes to our html tag. This didn’t really help: it added extraneous xmlns="" attributes to many of the child tags in the output document, which quirkified IE just as much as not having the tag.

Solving the second part of the first problem (producing a document type tag) turned out to also be the solution to the second problem (extraneous xmlns attributes). XSLT will add a document type tag automatically if the appropriate attributes are given to the xsl:output tag. Specifically, we wound up with this:

<xsl:output method="html" indent="yes" encoding="utf-8"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

Notice the bonus encoding, doctype-public and doctype-system attributes. That got us the DOCTYPE tag shown above, and bailed us out of IE Quirks Mode.

Passenger, Paperclip, and Permissions (another route)

| |

We had issues with file uploads recently on a site using Paperclip to handle uploads and served with Passenger. The site worked fine in development, but in production the uploads would fail. Checking the production log showed that Paperclip was producing the following error:

[paperclip] An error was received while processing: #<Paperclip::NotIdentifiedByImageMagickError: /tmp/passenger.1358/var/stream.25635.1 is not recognized by the 'identify' command.>

A web search produced this railsforum thread with some helpful advice, specifically to set

Paperclip.options[:command_path] = "/usr/local/bin"

in an initializer for Paperclip. Our problem was environment-specific, though, so we put it in the config/environment/production.rb file instead. No luck.

So I checked the Apache logs to see what error Passenger was producing. It wasn’t throwing an error of its own; instead we were seeing a lot of

[DEPRECATION] S3 support through RightAWS is deprecated. S3 support will be changed to AWS::S3 in a future version.

…in the Apache error log. It turned out that our development boxes were all using the aws-s3 gem, and the production box was still on RightAWS. When we installed aws-s3 on the server, the problem was solved.

So if you’re having Passenger and Paperclip problems, make sure you’re using the right interface with s3 as part of your troubleshooting process.

Baseline, Software Licenses and Services Agreements

| |

This is probably not the best place to be tracking the step-by-step growth of Baseline Solutions, but we’re proud of the software package we built for them, and it’s nice to see other people saying good things about it as well.

The most recent upgrade added software licenses and services agreements to the kinds of documents the application handles, and Jeffrey Gordon of the Software Licensing Handbook gave Baseline a run-through before agreeing to allow his templates to be used as Baseline “playbooks”. Gordon captures neatly the advantage the Baseline application gives to a legal review team (emphasis ours):

You upload your preferred language (the baseline information) and then you can bounce any other proposed agreement off your preferences. The software uses proprietary algorithms to review the wording and match the sections. It looks for common phrasing but also appears to recognize intent. Frankly, I’m not sure how it works, but it does.

… The result is that the first review … is accomplished in a few seconds. The basic review is complete – now I can spend my valuable time reviewing the unique contract issues. I’ve just saved time and produced a better document.

We especially like where he calls it “Pop-Up Video for your contract.” (We do know how it works, and we’re still impressed.)