web-dev-qa-db-ja.com

ページャーのローカルタイムゾーンで日付ヘッダーを表示するようにmuttを構成するにはどうすればよいですか?

ページャーでメッセージを表示すると、muttがローカルタイムゾーンではなくUTCのDateヘッダーに時刻を表示します。インデックスビューは現地時間を正しく表示します。私は この古いメーリングリストの投稿 を見つけました。これは、画面下部のステータスバーに表示する現地時間を取得する方法を示していますが、日付ヘッダーの時間はまだ修正されていません。画面上部にあります。ページャーに日付ヘッダー時間を現地時間に変換させる方法はありますか?

13
Ben Williams

.muttrcに次の行を追加します。

set display_filter="exec sed -r \"s/^Date:\\s*(([F-Wa-u]{3},\\s*)?[[:digit:]]{1,2}\\s+[A-Sa-y]{3}\\s+[[:digit:]]{4}\\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\\1'/e\""

ヘッダーに有効なRFC形式の日付が含まれている場合、メッセージのDate:ヘッダーがローカルタイムゾーンに変更されます(表示のみ)。提供された日付形式が正しくなかった場合(結局、信頼できないユーザー入力を処理しているため)、保持されます。ヘッダーからシェルコードを挿入する可能性のある試みに対抗するために、sedパターンはRFC 5322(このRFCはDate:フィールドの形式を定義する)に基づいてホワイトリストを実装します。

muttはコマンドラインを255文字以下に制限することに注意してください。したがって、255バイトに収まるように、より厳密なホワイトリストを持つ元のsedコマンドを最適化しました。メッセージで他のことを行う予定の場合、スクリプトに含めることができる完全なsedコマンドは次のとおりです。

sed -r "s/^Date:\s*(((Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s*)?[[:digit:]]{1,2}\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[[:digit:]]{4}\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\1'/e"
3
galaxy

インデックス内のフォーマットは、index_format設定によって制御されます。これは、muttによって生成されます。 Dateヘッダーはmuttによって制御されず、表示されるだけのメッセージに含まれるヘッダーです。 UTC時刻が表示される場合は、送信サーバーがヘッダーの生成時にUTCを使用することを決定したためです。メッセージを変更する唯一の方法は、メッセージを受信したときまたは表示したときに、メッセージ自体を実際に変更することです。

受信時に変更することは、メール配信エージェントにフィルターを追加することを意味しますが、既存のDateヘッダーを解析して書き換えるのに十分なほど洗練されている必要があります。メッセージを見るときは、muttでメッセージを再フォーマットする方がほぼ確実です。 display_filter プロパティを実行可能ファイルに設定すると、表示する前に、実行可能ファイルを介して開いたメッセージをパイプ処理します。

メッセージの各行を読み取り、Dateヘッダーで置き換えるプログラムまたはシェルスクリプトを作成するか、既存のスクリプトを見つける必要があります(機能しますが、動作する可能性のある here があります)一時ファイルを含める必要が本当にあるようには思えない)

11
Michael Mrozek

http://www.mail-archive.com/[email protected]/msg44341.html

これは、「pager_format」を使用して、ローカルのタイムゾーンで文字の日付を表示することをお勧めします。

set pager_format = "%4C%Z%[!%b%e at%I:%M%p]%.20n%s%*-(%P)"

7
viric

Gillesのアドバイスを受けて、一時ファイルとformailを使用するバージョンを次に示します。

#!/bin/bash
TMPFILE=$(mktemp)

# save the message to a file
cat - >"$TMPFILE"
# extract the date header
DATE=$( formail -xDate: < "$TMPFILE" )
# convert to the current timezone (defined by TZ)
DATE=$( date -R -d "$DATE" )
# output the modified message
echo "Date: $DATE"
formail -fI Date < "$TMPFILE"
# clean up
rm -f "$TMPFILE"
5
Ben Williams

これがprocmailソリューションです:

# extract date from mail
:0
TMPDATE=| formail -x Date

# get local date
LOCALDATE=`date --rfc-2822 -d "$TMPDATE"`

# add it new header to the mail
:0 f
| formail -I "LocalDate: $LOCALDATE"

そして、muttrcにLocalDate:を表示します。

unignore localdate
2
fraff

Localtimeバージョンを含むように「Local-Date」ヘッダーを追加しながら「Date」ヘッダーを保持する必須のPerlソリューション:

#!/usr/bin/Perl -n

use Date::Parse;
use POSIX;
use strict;

if (/^Date: (.*)$/) {
    my $datestr = $1;
    my $date = strftime ("%a, %d %b %Y %H:%M:%S",
                         localtime (str2time ($datestr)));
    print "Local-Date: $date\n";
}

print;
2
hyperair

set display_filter="/PATH/TO/THIS/PYTHON/FILE"あなたの.muttrc

Python 3.3:

#!/usr/bin/env python3
import sys
import re
# import subprocess
from email.utils import format_datetime, parsedate_to_datetime

in_headers = True
for line in sys.stdin.readlines():
    if line == "\n": in_headers = False
    match = re.match(r'^Date: (.+)', line)

    if not in_headers or not match:
        print(line, end="")
        continue

    date_string = match.group(1)
    # use this if you do not have python 3.3+
    # converted_date = subprocess.Popen(['date','-d',date_string], stdout=subprocess.PIPE).communicate()[0].strip()
    converted_date = format_datetime(parsedate_to_datetime(date_string).astimezone(tz=None))
    print('Date:', converted_date)
2
Janus Troelsen

Michaelの答えの最後に説明されているシェルスクリプトを作成しました。

#!/bin/bash
while IFS= read -r LINE; do
    if [[ "${LINE}" =~ ^Date:\ .* ]]; then
        DATE=${LINE#Date: }
        # convert to the current timezone (defined by TZ)
        DATE=$(date -d "${DATE}")
        printf '%s' "Date: ${DATE}"
    Elif [[ -n $LINE ]]; then
      # We've reach the end of the headers, so stop parsing
      echo
      exec cat
    else
        printf '%s\n' "${LINE}"
    fi
done
0
Ben Williams