blog dds

2010.10.14

Synchronizing Thunderbird's Replied Flag

My main email client is Thunderbird, but I also use BlackBerry's and Apple's clients, all through the same IMAP account. Disconcertingly, email messages to which I have replied through the other clients don't show up in Thunderbird with the "replied" (replied icon) icon. This means that when I browse my email using Thunderbird, I waste time trying to remember whether I have responded to a particular message. Here is how I solved the problem.

The replied icon appears when the Thunderbird-specific message header X-Mozilla-Status contains the MSG_FLAG_REPLIED flag set. (Flags are well documented in the client's source code). To set it in messages I have replied to, the script goes through the local Sent message folder (I store them there after fetching them from the IMAP Sent folder) and looks at the In-Reply-To header. It then scans my Pending messages folder, and sets the replied flag for all messages whose Message-ID matches one of those encountered in the sent messages. In common with an email analytics script I wrote a few months ago, I used Mark Overmeer's excellent Mail-Box email processing Perl package to read and write the message folders.

Here is the script; I hope you'll find it useful!

#!/usr/bin/perl
#
# Find messages that are replies to others and set Thunderbird's Replied flag
# D. Spinellis, October 2010
#

use strict;
use Mail::Box::Mbox;

my %replied;

if ($#ARGV != 1) {
	print STDERR "usage: $0 sent-filder pending-folder\n";
	exit 1;
}

read_sent($ARGV[0]);
set_replied($ARGV[1]);
unlink("$ARGV[1].msf");

# Find all messages that have been replied
sub read_sent {
	my ($folder) = @_;
	print STDERR "Processing folder $folder\n";
	my $folder = Mail::Box::Mbox->new(folder => $folder, lock_type => 'NONE');
	foreach my $m ($folder->messages) {
		my $irt = $m->head->get('In-Reply-To');
		$replied{$irt} = 1 if (defined($irt));
	}
	$folder->DESTROY();
}


# Set the Thunderbird replied bit in messages that were replied
sub set_replied {
	my ($folder) = @_;
	my $MSG_FLAG_REPLIED = 0x0002;

	print STDERR "Processing folder $folder\n";
	my $folder = Mail::Box::Mbox->new(folder => $folder,
		extract => 'LAZY',
		access => 'rw',
		write_policy => 'INPLACE', # REPLACE
		lock_type => 'NONE');
	foreach my $m ($folder->messages) {
		my $status = hex(my $oh = $m->head->get('X-Mozilla-Status'));
		next if ($status & $MSG_FLAG_REPLIED);
		my $id = $m->head->get('Message-ID');
		if ($replied{$id}) {
			my $newval = sprintf("%04x", $status | $MSG_FLAG_REPLIED);
			print "$oh -> $newval\n";
			$m->head->set('X-Mozilla-Status', $newval);
		}
	}
	$folder->close() or die "Couldn't write $folder: $!\n";
}

Read and post comments, or share through   


Creative Commons License Last modified: Thursday, October 14, 2010 1:40 am
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.