Восстановление файлов сообщений курьера
Я запускаю почтовый сервер, на котором у меня работают курьерские imap и pop3. Недавно я переместил некоторые локальные сообщения со своего компьютера (ранее загруженного с помощью pop3) на сервер, чтобы я мог использовать imap. Я использовал Mail.app на Mac OS X 10.5.8, чтобы сделать это.
Это привело к серии файлов на почтовом сервере, которые выглядят так:
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
Теперь это не проблема для настольных почтовых клиентов - они просто выбирают все сообщения, сортируют их, и все в порядке. Несколько поисков в Google по этой теме привели к появлению потоков, в которых люди пытались получить свои сообщения в правильном порядке, и предлагаемое решение было "отсортировать их на стороне клиента".
К сожалению, в iOS 5.0.1 почтовое приложение предполагает, что порядок сообщений, которые он получает от сервера imap, уже отсортирован по дате. Из-за того, что сообщения в этом примере имеют имя файла, которое не соответствует их метке времени получения, а вместо этого - метку времени повторной загрузки, это означает, что сообщения отображаются в неправильном порядке на устройстве iOS. Чтобы это исправить, я должен загрузить ВСЕ сообщения, нажав несколько раз кнопку "Загрузить еще сообщения".
Я хотел бы просто иметь возможность перестроить эти файлы сообщений так, чтобы временная метка в имени файла (которая выглядит как первый набор цифр перед периодом) соответствовала временной метке получения. Затем они будут отсортированы в правильном порядке, когда устройство iOS пытается их загрузить. Я не знаю достаточно о том, как курьер организует сообщения - могу ли я просто написать скрипт, который заменяет первый набор цифр в имени файла на временную метку unix времени получения сообщения?
Спасибо!
1 ответ
Спасибо @mailq. Оказывается, что в дополнение к временной метке, которая находится в начале имени файла сообщения, курьер также просматривает временную метку изменения самого файла. Я должен был установить это к полученной метке времени также.
Вот скрипт, который, учитывая кучу сообщений, скопирует их в выходной каталог после переписывания имени файла и времени модификации, чтобы содержать метку времени получения.
#!/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_renamed
с cur
удалите courierimapuiddb
файл, и, возможно, перезапустите ваши почтовые клиенты. Для моего устройства iOS мне пришлось удалить почтовую учетную запись, а затем выполнить повторную синхронизацию с iTunes, чтобы правильно очистить кэш.