Jak skonfigurować mutt, aby wyświetlał nagłówek daty w mojej lokalnej strefie czasowej na pagerze?


13

Kiedy przeglądam komunikat w pagerze, mutt wyświetla czas w nagłówku Data w UTC zamiast w mojej lokalnej strefie czasowej. Widok indeksu wyświetla poprawnie czas lokalny. Znalazłem ten stary post z listą mailingową, który opisuje, jak uzyskać czas lokalny do wyświetlenia na pasku stanu u dołu ekranu, ale to nadal nie „naprawia” czasu w nagłówku Data u góry ekranu. Czy jest jakiś sposób, aby pager przekonwertował czas nagłówka Data na czas lokalny?

Odpowiedzi:


3

W swoim .muttrcdodaj następujący wiersz:

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

Spowoduje to zmianę Date:nagłówka w komunikacie (tylko do wyświetlania) na lokalną strefę czasową, jeśli nagłówek zawierał prawidłową datę sformatowaną w formacie RFC. Jeśli podany format daty był niepoprawny (w końcu mamy do czynienia z niezaufanymi danymi użytkownika), zostanie on zachowany. Aby zwalczyć ewentualną próbę wstrzyknięcia kodu powłoki przez nagłówek, sedwzorzec implementuje białą listę opartą na RFC 5322 (ta RFC określa format Date:pola).

Zauważ, że muttlimit linii poleceń nie może być dłuższy niż 255 znaków, dlatego zoptymalizowałem oryginalne sedpolecenie, które miało ściślejszą białą listę, aby zmieściło się w 255 bajtach. Jeśli planujesz robić inne rzeczy z wiadomością, wtedy pełne sedpolecenie, które możesz umieścić w skrypcie, to:

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"

Czy istnieje możliwość, aby działało to w systemie macOS? Chciałbym dołączyć to do mojego filter.sedpliku. Dzięki!
Philipp L.

Nie ma, chyba że używasz GNU sed (np. Przez Homebrew) - powyższe sedpolecenia polegają na emodyfikatorze spolecenia. Ten modyfikator jest rozszerzeniem GNU, a macOS sedto BSD.
galaktyka

Odpowiedź @viric jest dobra. Nie trzeba zmieniać wiadomości przez filtr.
Jangid

@Jangid, proszę przeczytać oryginalne żądanie, a konkretnie prosi o prawidłowe wyświetlenie strefy lokalnej u góry strony, a nie w wierszu stanu.
galaktyka

@galaxy Oh! tak. Właśnie to zauważyłem. Poprawny.
Jangid

11

Formatowanie indeksu jest kontrolowane przez index_formatustawienie - jest generowane przez mutt. DateNagłówek nie jest kontrolowana przez kundla, to nagłówek zawarte z przesłaniem, że po prostu zostanie wyświetlony. Jeśli pokazuje czas UTC, to dlatego, że serwer wysyłający zdecydował się użyć UTC podczas generowania nagłówka. Jedynym sposobem, aby to zmienić, jest faktyczna zmiana samej wiadomości, zarówno po jej otrzymaniu, jak i wyświetleniu.

Zmieniając go w momencie, w jakim się pojawia, oznacza dodawanie filtra do agenta dostarczającego pocztę, ale musi on być wystarczająco wyrafinowany, aby przeanalizować istniejący Datenagłówek i przepisać go. Prawie na pewno lepiej jest po prostu przeformatować wiadomość, gdy na nią patrzysz. Możesz ustawić display_filterwłaściwość na plik wykonywalny, a on wyświetli każdą wiadomość otwieraną przez plik wykonywalny przed jego wyświetleniem.

Musisz napisać program lub skrypt powłoki, który odczytuje każdy wiersz wiadomości i zastępuje go nagłówkiem Date, lub znajduje istniejący skrypt (jest tu jeden , który może działać, chociaż nie wydaje się, że powinien konieczne jest włączenie pliku tymczasowego)



5

Korzystając z rad Gillesa, oto wersja, która używa pliku tymczasowego i 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"

Jest to podatne na ataki polegające na wstrzykiwaniu kodu przez zniekształcony Date:nagłówek - jeśli przejdziesz do podpowłoki, musisz sprawdzić / odkazić dane wejściowe.
galaktyka

2

Oto rozwiązanie 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"

I wyświetl LocalDate: in muttrc:

unignore localdate

jak to wywołujesz?
Janus Troelsen,

@JanusTroelsen, wierzę przypisać skrypt display_filterw .muttrc.
galaktyka

2

set display_filter="/PATH/TO/THIS/PYTHON/FILE"w twoim .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)

Skomentowany wiersz jest podatny na ataki polegające na wstrzykiwaniu kodu przez zniekształcony Date:nagłówek - jeśli przejdziesz do podpowłoki, musisz sprawdzić poprawność / odkazić dane wejściowe, w przeciwnym razie skrypt jest OK z punktu widzenia bezpieczeństwa. Jest to jednak dość trudne dla skryptu, który działa przy każdej przeglądanej wiadomości.
galaktyka

2

Obowiązkowe rozwiązanie Perla, które zachowuje nagłówek „Data”, a jednocześnie dodaje dodatkowy nagłówek „Data lokalna”, który zawiera wersję czasu lokalnego:

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

0

Zrobiłem skrypt powłoki, jak opisano na końcu odpowiedzi Michaela, która wykonuje dla mnie zadanie:

#!/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

1
Analiza wiadomości e-mail jest dość trudna. Polecam użycie dedykowanego narzędzia, takiego jak formail(część pakietu procmail ) lub reformail(część zrzutu poczty ), aby wyodrębnić istniejący Date:nagłówek i umieścić nowy na miejscu. Zadbaj o przypadki krawędzi, takie jak brakujący lub źle sformatowany Date:nagłówek.
Gilles „SO- przestań być zły”,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.