namazu-ml(avocado)


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Call for beta test with v1.2.1.0-beta-12 (Re: How to index updated files)



Hajime BABA <baba@xxxxxxxxxxxxxxxxxxxxxx> wrote:

>> Mail/News の場合はファイルのタイムスタンプよりヘッダの Date: の方
>> があてになるのでそれを NMZ.t に記録したいところです。ところが、そ
>> うするとファイルの持つタイムスタンプと食い違ってしまいます。
>
>MHonArc なら、-modtime オプションをつければ msgXXXXX.html のタイム
>スタンプを Date: の時間にしてくれます。だから、タイムスタンプで並
>べ替えられるようにするのが実用的だし現実的だとおもいます。

なるほど。では、生の Mail/News のファイルについても Date: に合わせ
てタイムスタンプを変更できると便利そうですね。安直なツールをを作っ
てみたのでメイルの末尾に添付しておきます。

% find ~/Mail/ml/hogehoge | xargs ./mailutime.pl

みたいにして使います。

ファイル名に連番が含まれるものを擬似的に新しい順/古い順にソートす
る機能 (検索対象となるインデックスが単一の場合のみ有効) はそのまま
残すのでこれで十分という場合は NMZ.t は不要です。

-- Satoru Takabayashi

#!/usr/bin/perl -w
require 5.003;
use strict;
use IO::File;
use Time::Local;
$| = 1;   # autoflush output 

my %month_names = ("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, 
		   "May" => 4, "Jun" => 5, "Jul" => 6, "Aug" => 7, 
		   "Sep" => 8, "Oct" => 9, "Nov" => 10, "Dec" => 11);
my $re_month =  join('|', keys (%month_names));
my $re_day   =  '(?:0?[1-9]|[12][0-9]|3[01])';
my $re_year  =  '(?:\d\d|\d\d\d\d+)';  # allow 2 digit fomrat such as '98'
my $re_hour  =  '(?:[01][0-9]|2[0-3])';
my $re_min   =  '(?:[012345][0-9])';
my $re_sec   =  '(?:[012345][0-9])';
    
main();

sub main () {
    my $file;

    foreach $file (@ARGV) {
	my $date;
	my ($fh) = new IO::File;
	$fh->open("$file") || die "$!: $file\n";
	while (<$fh>) {
	    last if /^$/;
	    $date = $1 if /^Date: (.*)/i;
	}
	unless (defined($date)) {
	    print STDERR "$file: 'Date:' not found!\n";
	    next;
	}

	my $time = rfc822time($date);
	if ($time != -1) {
	    utime($time, $time, $file);
	    print "$file: $date\n";
	} else {
	    print STDERR "$file: [$date] malformed 'Date:' format!\n";
	    next;
	}
    }
}

# calculate time from RFC 822 'Date: ' field string like:
#   'Thu, 18 Dec 1997 21:09:43 GMT'
# timezone and its adjustment such as GMT or +0900 would be ignored.
sub rfc822time($) {
    my ($date) = @_;

    if ($date =~ /
	^\s*
	\w{3},\s+                          # a day of the week (ignored)
	($re_day)\s+                       # a day of the month
	($re_month)\s+                     # name of month
	($re_year)\s+                      # year
	($re_hour):($re_min):($re_sec)     # HH:MM:SS
	/x) 
    {
	my ($mday, $mon, $year, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
	$mon = $month_names{$mon};
	my $mtime = timelocal($sec, $min, $hour, $mday, $mon, $year);
	return $mtime;
    } else {
	return -1; # return with error
    }
}