Bagaimana cara mengkonfigurasi mutt untuk menampilkan tajuk tanggal di zona waktu lokal di pager?

13

Ketika saya melihat pesan di pager mutt, waktu ditampilkan di header Tanggal di UTC daripada di zona waktu lokal saya. Tampilan indeks menampilkan waktu lokal dengan benar. Saya menemukan posting milis lama ini yang menjelaskan cara mendapatkan waktu lokal untuk ditampilkan di bilah status di bagian bawah layar, tetapi ini masih tidak "memperbaiki" waktu di header Tanggal di bagian atas layar. Apakah ada cara untuk membuat pager mengubah waktu tajuk Date ke waktu lokal?

Ben Williams
sumber

Jawaban:

3

Di .muttrctambahkan Anda baris berikut:

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\""

Ini akan mengubah Date:header dalam pesan (hanya untuk tampilan) ke zona waktu lokal Anda jika header berisi tanggal diformat RFC yang valid. Jika format tanggal yang diberikan salah (kami berhadapan dengan input pengguna yang tidak dipercaya) itu akan dipertahankan. Untuk mengatasi kemungkinan upaya untuk menyuntikkan kode shell melalui header, sedpola mengimplementasikan daftar putih berdasarkan RFC 5322 (RFC ini mendefinisikan format Date:bidang).

Catatan yang muttmembatasi baris perintah tidak lebih dari 255 karakter, maka saya mengoptimalkan sedperintah asli yang memiliki daftar putih lebih ketat untuk masuk ke 255 byte. Jika Anda berencana melakukan hal-hal lain dengan pesan tersebut, maka sedperintah lengkap yang dapat Anda masukkan ke dalam skrip adalah:

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"
galaksi
sumber
Apakah ada kemungkinan untuk membuatnya bekerja pada macOS? Saya ingin memasukkannya ke dalam filter.sedfile saya . Terima kasih!
Philipp L.
Tidak ada, kecuali Anda menggunakan sed GNU (misalnya via Homebrew) - sedperintah di atas bergantung pada epengubah ke sperintah. Pengubah itu adalah ekstensi GNU dan macOS'es sedadalah BSD.
galaksi
Jawaban oleh @viric baik. Tidak perlu mengubah pesan melalui filter.
Jangid
@Jangid, harap baca permintaan asli dan secara spesifik meminta tampilan zona lokal yang tepat di bagian atas halaman dan bukan di baris status.
galaksi
@galaxy Oh! Iya. Hanya memperhatikan itu. Benar.
Jangid
11

Pemformatan dalam indeks dikendalikan oleh index_formatpengaturan - itu dihasilkan oleh mutt. The Dateheader tidak dikendalikan oleh mutt, itu header disertakan dengan pesan yang hanya akan ditampilkan. Jika ini menunjukkan waktu UTC itu karena server pengirim memutuskan untuk menggunakan UTC ketika membuat header. Satu-satunya cara untuk mengubahnya adalah dengan benar-benar mengubah pesan itu sendiri, baik ketika Anda menerimanya atau ketika Anda melihatnya.

Mengubahnya saat datang berarti menambahkan filter ke agen pengiriman surat Anda, tetapi perlu cukup canggih untuk mem-parsing Dateheader yang ada dan menulis ulang. Ini hampir pasti lebih baik untuk hanya memformat ulang pesan ketika Anda melihatnya. Anda dapat mengatur display_filterproperti ke file yang dapat dieksekusi, dan itu akan mengirimkan pesan apa pun yang Anda buka melalui file yang dapat dieksekusi sebelum menampilkannya.

Anda harus menulis skrip program atau shell yang membaca setiap baris pesan dan menggantikannya dengan header Tanggal, atau menemukan skrip yang ada (ada satu di sini yang mungkin berfungsi, meskipun sepertinya tidak seharusnya benar-benar diperlukan untuk melibatkan file sementara)

Michael Mrozek
sumber
5

Mengambil saran Gilles, inilah versi yang menggunakan file temp dan 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"
Ben Williams
sumber
Ini rentan terhadap serangan injeksi kode melalui Date:header yang salah bentuk - jika Anda masuk ke subkulit Anda perlu memvalidasi / membersihkan input.
galaksi
2

Berikut ini adalah solusi 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"

Dan tampilkan LocalDate: dalam muttrc:

unignore localdate
lemah
sumber
bagaimana Anda memohon ini?
Janus Troelsen
@ JanusTroelsen, saya yakin Anda memasukkan skrip ke display_filterdalam .muttrc.
galaksi
2

set display_filter="/PATH/TO/THIS/PYTHON/FILE"di Anda .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)
Janus Troelsen
sumber
Baris yang dikomentari rentan terhadap serangan injeksi kode melalui Date:header yang salah bentuk - jika Anda masuk ke subkulit Anda perlu memvalidasi / membersihkan input, jika tidak skrip OK dari sudut pandang keamanan. Namun, ini cukup berat untuk skrip yang berjalan pada setiap pesan yang Anda telusuri.
galaksi
2

Solusi Perl Wajib yang mempertahankan header "Date" sambil menambahkan header "Local-Date" tambahan untuk memuat versi localtime:

#!/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;
hyperair
sumber
0

Saya membuat skrip shell seperti yang dijelaskan pada akhir jawaban Michael yang melakukan pekerjaan untuk saya:

#!/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
Ben Williams
sumber
1
Parsing email cukup rumit. Saya sarankan menggunakan alat khusus seperti formail(bagian dari paket procmail ) atau reformail(bagian dari maildrop ) untuk mengekstrak Date:header yang ada dan meletakkan yang baru di tempatnya. Jaga kasus tepi seperti Date:header yang hilang atau salah format .
Gilles 'SANGAT berhenti menjadi jahat'