重建快递信息文件

重建快递信息文件

我运行一个邮件服务器,上面运行着 courier imap 和 pop3。最近我将一些本地邮件从我的机器(之前使用 pop3 下载)移到了服务器上,以便可以使用 imap。我在 Mac OS X 10.5.8 上使用 Mail.app 来执行此操作。

这导致邮件服务器上出现一系列如下所示的文件:

1324697191.M91227P15574V000000000000CA00I0004B07D_556.hostname,S=5622:2,S
1324697192.M322096P15574V000000000000CA00I0004B07F_557.hostname,S=225691:2,RS
1324697196.M144018P15574V000000000000CA00I0004B081_558.hostname,S=7702:2,RS
1324697197.M715598P15574V000000000000CA00I0004B083_559.hostname,S=15741:2,S
1324697199.M327587P15574V000000000000CA00I0004B085_560.hostname,S=8744:2,RS

这些消息的接收时间(按照上面列出的顺序)如下:

01/15/2010
01/09/2009
07/13/2010
02/21/2010
05/06/2010

现在,桌面邮件客户端不存在这个问题——它们只需获取所有邮件,对它们进行排序,一切就都正常了。在谷歌上搜索了几次这个主题后,人们发现有人试图以正确的顺序排列邮件,而建议的补救措施是“在客户端对它们进行排序”。

不幸的是,在 iOS 5.0.1 上,邮件应用程序假定从 imap 服务器获取的消息的顺序已经按日期排序。由于此示例中的消息的文件名与其接收时间戳不匹配,而是与其重新上传时间戳匹配,这意味着消息在 iOS 设备上的显示顺序错误。为了解决这个问题,我必须多次点击“加载更多消息”按钮来加载所有邮件。

我希望能够重建这些消息文件,使文件名中的时间戳(看起来是句点之前的第一组数字)与接收时间戳相匹配。然后,当 iOS 设备尝试加载它们时,它们将按正确的顺序排序。我对 Courier 如何组织消息了解不够多——我可以简单地编写一个脚本,将文件名中的第一组数字替换为消息接收时间的 unix 时间戳吗?

谢谢!

答案1

谢谢@mailq。事实证明,除了时间戳位于消息文件名的开头之外,Courier 还会查看文件本身的修改时间戳。我还必须将其设置为收到的时间戳。

这是一个脚本,它将给定一堆消息,在重写文件名和修改时间以包含接收时间戳后将它们复制到输出目录。

#!/usr/bin/env perl

use Email::Simple;
use Date::Parse;
use Getopt::Long;
use File::Path qw(make_path);
use File::Copy qw(copy);
use File::stat;

my $outfolder = "";

$result = GetOptions("output-dir=s" => \$outfolder);

# create directories if needed
if (length($outfolder) > 0) {
    make_path($outfolder);
}

foreach my $file (@ARGV) {
    my $text = "";

    # read file as one string
    {
        local $/=undef;
        open FILE, "$file" or die "Couldn't open file: $!";
        binmode FILE;
        $text = <FILE>;
        close FILE;
    }

    # use Email::Simple to parse the Received header
    my $email = Email::Simple->new($text);
    my @received = $email->header("Received");

    # Find the latest receive time
    my $latestTime = 0;
    my $latestTimeStr = "";
    foreach my $r (@received) {
        if ($r =~ /[^;]*;(.*)$/) {
            my $time = str2time($1);

            if ($time > $latestTime) {
                $latestTime = $time;
                $latestTimeStr = $1;
            }
        }
    }

    # if this is a sent message, it doesn't have a received header. Use the
    # Date header instead.
    if ($latestTime == 0) {
        my $date = $email->header("Date");
        my $time = str2time($date);
        if ($time > $latestTime) {
            $latestTime = $time;
            $latestTimeStr = $date;
        }
    }

    # If we found one, rename or tell about the rename
    if ($latestTime != 0) {
        if ($file =~ /([0-9]*)(\..*$)/) {
            my $newfilename = $latestTime . $2;

            if (length($outfolder) == 0) {
                print "Would Copy $file ($latestTimeStr) -> \n             ";
                print "$newfilename\n";
            } else {
                print "Copied $file ($latestTimeStr) -> \n             ";
                print "$outfolder/$newfilename\n";

                # use the latest received timestamp as the atime and mtime
                copy($file, "$outfolder/$newfilename");
                utime($latestTime, $latestTime, "$outfolder/$newfilename");
            }
        }
    } else {
        print "Couldn't find receive time for " . $file . "\n";
    }
}

使用如下脚本:

perl rename.pl cur/*

当你确信它会做正确的事情时:

perl rename.pl cur/* --output-dir cur_renamed

然后,您只需要切换到cur_renamedcur删除courierimapuiddb文件,并可能重新启动电子邮件客户端。对于我的 iOS 设备,我必须删除邮件帐户,然后与 iTunes 重新同步,才能正确清除缓存。

相关内容