Getting non-Aero toolbars for Thunderbird 5 on Windows 7

Thunderbird 5 brings a custom chrome on Windows Vista/7 that uses translucent Aero decorations on toolbars and menubars. Here is how to restore solid backgrounds if you don't like it.

Put the following into chrome\userChrome.css in your Thunderbird profile directory:

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
window {
  background-color: -moz-dialog !important;
}

(Re-)start Thunderbird afterwards.


If you need more info on where the userChrome.css is suppose...

Traverse large XML files with Nokogiri

If you need to parse a large XML file (> 20 MB or so), you should parse it in chunks, otherwise it will need lots of memory.

Nokogiri offers a reader that lets you parse your XML one node at a time.

Given an XML library.xml with this content

    <library>
      <book>
        <title>...</title>
        <author>...</author>
      </book>
      <book>
         ...
      </book>
       ...
    </library>

you can for example loop over all books with

    def each_book(filename, &block)
      File.open(filename) do |file|
      ...

The challenging setup of an offshore project

After managing a few agile projects from India and learning the tricks of the trade, I have been wondering why life is much easier when you are working closely with the client as compared to working offshore. What worried me more was that I had to learn and use a lot more of project management techniques (making trade offs , managing risks etc..) from offshore, but what mattered while at a local client was building relationships and managing client expectations.

Check whether an element is visible or hidden with Javascript

jQuery

You can say:

$(element).is(':visible')

and

$(element).is(':hidden')

jQuery considers an element to be visible if it consumes space in the document. For most purposes, this is exactly what you want.

Native DOM API

Emulate jQuery's implementation :

element.offsetWidth > 0 && element.offsetHeight > 0;

jQuery > 3

Query 3 slightly modifies the meaning of :visible (and therefore of :hidden).

Emulate jQuery'...

console-for opens a Rails console remotely on a Capistrano deployment target

We're adding a script console-for to open a remote Rails console with one command. Also have a look at shell-for, which this script is relying on.

Run it from any project directory like this, passing a Capistrano multistage deployment target:

console-for staging

This script is part of our geordi gem on github.

Be careful when closing expanded stories in Pivotal Tracker

When you open up a story to only have a look at it, close it by pressing the "Cancel" button (or Esc key).

Clicking the arrow in the top left is the same as pressing the "Save" button. If someone changes the story description in the meantime you will overwrite their changes with everything you see, even if you did not change anything. If you only want to take a peek, prefer to hover the speech bubble icon.

If your story gets shotgunned and you notice it, you are lucky -- and you may be able to get your changes back. Open up the his...

Install the SQLite 3 gem for Ruby under Ubuntu

sudo apt-get install sqlite3 libsqlite3-dev
sudo gem install sqlite3-ruby

Test that a string of text is (not) linked in Webrat or Capybara

The step definition below allows you to write:

Then I should see a link labeled "Foo"
But I should not see a link labeled "Bar"

Webrat

Then /^I should( not)? see a link labeled "([^"]*)"$/ do |negate, label|
  expectation = negate ? :should_not : :should
  response.send(expectation, have_selector("a", :content => label))
end

Capybara

Then /^I should( not)? see a link labeled "([^"]*)"$/ do |negate, label|
  expectation = negate ? :should_not : :should
  page.send(expectat...

Using Dropbox on Ubuntu

If you are exchanging files with a client via Dropbox you do not need to access the Web page every time you want to fetch files. Instead, you can fully integrate your Dropbox account(s) into nautilus (Gnome's file manager) with automatic synchronization.

  1. Get the .deb file for your system architecture (32 or 64 bit) from the Linux download page.
  2. Install the downloaded package using either the Gnome integration (double-click it) or the shell, e.g.: `dpkg -i naut...

Build vs. Buy

A common question in IT departments is whether to provide a capability by building custom software or by buying a package. If the business process you are supporting is part of your competitive advantage you should build custom software, if not you should buy a package and adjust your business process to fit the way the package works.

How to build the perfect number of blank records for a nested form

When you render a nested form for a Movie which has_many :actors, you want to render the right number of blank Actor forms. The right number means:

  • A minimum number of blank forms so the user can add more Actors to an existing Movie, e.g. 2.
  • A minimum total number of forms (both blank and pre-filled) so the user sees more than just 2 blank Actor forms when she is entering Actors for the first time, e.g. 5.

For the example above, this is the desired progression of the number of blank forms:

| Number of actors | Number of ...

Force SSH client to use password authentication instead of public key

To test if you can connect to a host using password authentication and explicitly deny public key authentication:

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@host

This also works for Secure Copy:

scp -o PreferredAuthentications=password -o PubkeyAuthentication=no local.file user@host:/path/to/remote.file

Run Selenium tests in Chrome instead of Firefox

Here is how to switch your Selenium to Chrome:

  1. Make sure you've got a recent version of chromedriver in your $PATH

See also geordi chromedriver_update which is automatically executed before every usage of geordi cucumber.

  1. Register Driver:

Create a file features/support/capybara.rb with the following content for recent version of Capybara:

Capybara.register_driver :selenium do |app|
  Capyb...

Change the name of your Ubuntu machine

In order to rename your Ubuntu box, replace all occurences of the the old name in the following two files:

  • /etc/hostname
  • /etc/hosts

After a reboot your hostname is changed. If you don't want to reboot your Ubuntu box you have to execute hostname your.hostname.

Linux: Refer to all arguments of a script call

In shell scripts you can use $1 to refer to the first argument, $2 for the second, etc. If you want to refer to all arguments (e.g. when writing a bash script that takes an arbitrary amount of arguments and passes them on to another call), you may not want to do a “$1 $2 $3 $4 ...”.

Use $@ instead, like in this script:
$ cat welcome
#!/bin/bash
echo Hello to $@

When called, the above would produce this:
$ ./welcome the world and universe
Hello to the world and universe

Note that $@ works for both sh and `ba...

mysqltuner.pl

This Perl script will run diagnostics on your MySQL database and recommend changes to your MySQL configuration.

Hack of the day: A reverse for Rails' &:

Ever wondered if there is a reverse for Rails' .each(&:to_s) idiom? Turns out there is...

You probably already know, that you can abbreviate code like

dogs.each { |dog| dog.bark! }

with

dogs.each(&:bark!)

Now suppose it is the other way round and you have

bones.each { |bone| dog.eat!(bone) }

Good old Ruby already has a solution:

bones.each(&dog.method(:eat!))

Change the timestamp of a file in Ruby

This is somewhat similar to the touch command of Linux:

FileUtils.touch 'example.txt', :mtime => Time.now - 2.hours

If you omit the :mtime the modification timestamp will be set to the current time:

FileUtils.touch 'example.txt'

You may also pass an array of filenames:

FileUtils.touch %w[ foo bar baz ], :mtime => Time.now - 2.hours

Non-existent files will be created.

See which Rails applications are being served by your Passenger

To obtain a list of Passenger processes with their application directories and memory usages, you can say

sudo passenger-memory-stats

This will output a list like this:

----- Passenger processes -----
PID    VMSize    Private  Name
-------------------------------
671    112.9 MB  95.5 MB  Rails: /opt/www/project1/current
707    79.4 MB   60.5 MB  Rails: /opt/www/project2/current
1094   88.1 MB   69.3 MB  Rails: /opt/www/project3/current
1260   81.6 MB   62.6 MB  Rails: /opt/www/project4/current
1269   7...

Force Google Chrome to run in English on Linux

If you need Google Chrome to run in English, and your system locale is a non-English one, you have two options:

  • Switch your system to an English locale
  • Head over to /opt/google/chrome/locales/ and remove any .pak files except those starting with “en”. They reappear when Chrome gets updated.

This may help you running your Selenium tests using the Chrome driver on applications that choose the language from what the browser sends as preferred language (which Chrome guesses from your system locale).

What to do when Google only syncs some of your contacts

When some of your Google contacts are no longer synchronized with your e-mail client or mobile phone, those contacts are not in a group "My Contacts". Google only syncs contacts in that group.

In order to fix this:

  • Open Google Contacts
  • Select all contacts (there's a link)
  • Press "Move to My Contacts"

Note that when you are using Mozilla Thunderbird with the Google Contacts add-on, Thunderbird won't add new contacts into the "My Co...

How to fix: undefined method `specifications' (caused by RubyGems 1.8)

Sometimes, when running a rake task, RubyGems 1.8.5 raises an error:

rake aborted!
undefined method `specifications' for "/usr/lib/ruby/gems/1.8":String

This has been fixed since May 31 but is still not available as a new RubyGems version.

Either wait for a new version to eventually come out, downgrade to some really old version (1.6.2 works for some) or apply the fix manually:

  • Find your rubygems.rb -- mine was located at `/usr/local/lib/sit...

Sanitize filename with user input

If you have to build a filename (e.g. for use in downloads) that contains user input, keep in mind that malicious input might come from users and could lead to security problems.

Instead of blacklisting characters such as / , . \ ´ etc. better go for a stricter approach and use a whitelist such as:

def sanitize_filename(filename)
  filename.gsub(/[^0-9A-z.\-]/, '_')
end

If you need to have German Umlauts you can use /[^\w\-]/. This, however, will only work if the locale is set to German.
You might also want to translitera...