Как я настраиваю дурака для отображения заголовка даты в моей зоне местного времени в пейджере?

Драйверы устройств Linux являются другим хорошим ресурсом. Это дало бы Вам другой способ войти во внутренние работы. От предисловия:

Это, на поверхности, книге о записи драйверов устройств для системы Linux. Это - достойная цель, конечно; поток новых изделий вряд ли замедлится в ближайшее время, и кто-то оказывается перед необходимостью заставлять все те новые гаджеты работать с Linux. Но эта книга также о том, как ядро Linux работает и как адаптировать его работы к Вашим потребностям или интересам. Linux является открытой системой; с этой книгой мы надеемся, это более открыто и доступно для более многочисленного сообщества разработчиков.

13
16.08.2011, 15:37
8 ответов

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

Это изменит заголовок Date:в сообщении (только для отображения )на ваш местный часовой пояс, если заголовок содержит допустимую дату в формате RFC. Если предоставленный формат даты был неправильным (, мы имеем дело с ненадежным пользовательским вводом, в конце концов )он будет сохранен. Для борьбы с возможной попыткой внедрить шелл-код через заголовок шаблон sedреализует белый список на основе RFC 5322 (. Этот RFC определяет формат поля Date:).

Обратите внимание, что muttограничивает длину командной строки до 255 символов, поэтому я оптимизировал исходную команду sedс более строгим белым списком, чтобы она умещалась в 255 байт. Если вы планируете делать другие вещи с сообщением, то полная команда 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"
6
27.01.2020, 19:52

Форматированием в индексе управляют index_format установка - это сгенерировано дураком. Date заголовком не управляет дурак, это - заголовок, включенный с сообщением, которое просто отображено. Если это показывает время UTC, это - потому что передающий сервер решил использовать UTC при генерации заголовка. Единственный способ изменить его состоит в том, чтобы на самом деле изменить само сообщение, или когда Вы получаете его или когда Вы просматриваете его.

Изменение его, как это прибывает в средства, добавляющие фильтр к агенту доставки почты, но это должно быть достаточно сложно для парсинга существующего Date заголовок и переписывает его. Почти наверняка лучше просто сделать, чтобы дурак переформатировал сообщение, при рассмотрении его. Можно установить display_filter свойство к исполняемому файлу, и это передаст по каналу любое сообщение, которое Вы открываете через исполняемый файл прежде, чем отобразить его.

Необходимо будет записать программу или сценарий оболочки, который читает каждую строку сообщения и заменяет то заголовком Даты, или найдите существующий сценарий (существует тот здесь, который мог бы работать, хотя не кажется, что должно действительно быть необходимо включить временный файл),

11
27.01.2020, 19:52

Слушая совет Жабр, вот версия, которая использует временный файл и 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
27.01.2020, 19:52

Я сделал сценарий оболочки, как описано в конце ответа 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
27.01.2020, 19:52
  • 1
    Парсинг электронных писем довольно хитер. Я рекомендую использовать специальный инструмент как formail (часть procmail пакета) или reformail (часть maildrop) для извлечения существующего Date: заголовок и помещенный новый на месте. Заботьтесь о пограничных случаях, таких как отсутствие или malformatted Date: заголовок. –  Gilles 'SO- stop being evil' 15.08.2011, 19:29

http://www.mail-archive.com/mutt-users@mutt.org/msg44341.html

Это предлагает использовать 'pager_format', заставить его показать дату буквы в локальном часовом поясе:

набор pager_format = "% 4C %Z % [! %b %e в %I: % M %p] %.20n %s %* - (%P)"

7
27.01.2020, 19:52
  • 1
    Это работает очень хорошо, также для index_format. –  Phil 23.04.2014, 07:57

Обязательное решение для Perl, которое сохраняет заголовок "Даты" при добавлении дополнительного заголовка "Локальной Даты" для содержания 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;
2
27.01.2020, 19:52

Вот решение для 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"

И отобразите LocalDate: в muttrc:

unignore localdate
2
27.01.2020, 19:52

установить 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
27.01.2020, 19:52

Теги

Похожие вопросы