Thunderbird: Recovering corrupt address book

This post was written by eli on February 6, 2011
Posted Under: Software

It all started with a blue screen (Windows, right?), which seems to have something to do with Firefox. Anyhow, after that crash Thunderbird told me it can’t open the abook.mab file, and hence my contacts are lost. Which means it won’t autocomplete email addresses as I type them, which I’m not ready to take.

The solution was given in a forum thread in the form of a PHP script. Perl would be the correct language to do this, but since it saved my bottom, who am I to complain.

Since it’s so good, I hope it’s OK that I’ll repeat it here. It’s by the Ubuntu forum user mikerobinson:

<?php
error_reporting(E_ALL);
$abook = file_get_contents('abook.mab-1.bak');

preg_match_all('/\((.*)\)/Ums', $abook, $matches);

$matches = $matches[1];

foreach ($matches as $key => $match) {
    $entry = explode('=', $match);
    if (isset($entry[1]) && strlen($entry[1]) > 4 && !isset($skipnext)) {
        $entry[1] = str_replace("\\\n", '', $entry[1]);
        $entry[1] = str_replace('\\\\', '', $entry[1]);
        $entry[1] = str_replace('\\', ')', $entry[1]); // the backslashes SHOULD be at the end of each line

        // Unicode characters
        if (strstr($entry[1],'$')) {
            $entry[1] = str_replace('$', "\\x", $entry[1]);
            $entry[1] = preg_replace("#(\\\x[0-9A-F]{2})#e", "chr(hexdec('\\1'))", $entry[1]);
        }

        $matches[$key] = utf8_decode($entry[1]);
        if (strstr($entry[1],'@')) $skipnext = true;
    }
    else {
        unset($matches[$key]);
        unset($skipnext);
        if (strstr($entry[1],'@')) $skipnext = true;
    }
    unset($entry);
}

$previous = null;
foreach ($matches as $match) {
    if (strstr($match,'@')) {
        if (strtolower($match) != strtolower($previous)) {
            if (isset($addy)) $addressbook[] = array($match, end($addy));
            else $addressbook[] = array($match, $match);
            unset($addy);
            $previous = $match;
        }
    }
    else {
        $addy[] = $match;
    }
}

echo "First Name\tLast Name\tDisplay Name\tNickname\tPrimary Email\tSecondary Email\tScreen Name\tWork Phone\tHome Phone\tFax Number\tPager Number\tMobile Number\tHome Address\tHome Address 2\tHome City\tHome State\tHome ZipCode\tHome Country\tWork Address\tWork Address 2\tWork City\tWork State\tWork ZipCode\tWork Country\tJob Title\tDepartment\tOrganization\tWeb Page 1\tWeb Page 2\tBirth Year\tBirth Month\tBirth Day\tCustom 1\tCustom 2\tCustom 3\tCustom 4\tNotes\t";
foreach ($addressbook as $addy) {
    echo "\t\t{$addy[1]}\t\t{$addy[0]}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n";
}

After saving this script as savior.php, one goes at shell prompt (on Linux, right?):

# php savior > book.txt

And then manually edit any garbage away from the text file. Keep in mind that a title line should be kept as the first line.

And then go back to thunderbird, click Tools > Address book > Tools > Import… and import the file as a tab separated file. That’s it. The new addresses will be in a new folder, but who cares. Autocompletion is back!

Add a Comment

required, use real name
required, will not be published
optional, your blog address