web-dev-qa-db-ja.com

宅配便メッセージファイルの再構築

Courierimapとpop3を実行しているメールサーバーを実行しています。最近、imapを使用できるように、いくつかのローカルメッセージを自分のマシン(以前はpop3でダウンロードしたもの)からサーバーに移動しました。これを行うには、Mac OS X10.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デバイスがそれらを読み込もうとしたときに正しい順序で並べ替えられます。宅配便がメッセージを整理する方法について十分に知りません-ファイル名の最初の数字のセットをメッセージ受信時間のUNIXタイムスタンプに置き換えるスクリプトを簡単に作成できますか?

ありがとう!

1
Devin Lane

@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_renamedcurと交換し、courierimapuiddbファイルを削除して、メールクライアントを再起動する必要があります。 iOSデバイスの場合、メールアカウントを削除してから、iTunesと再同期して、キャッシュを適切にクリアする必要がありました。

1
Devin Lane