¿Cómo configuro mutt para mostrar el encabezado de fecha en mi zona horaria local en el localizador?

13

Cuando veo un mensaje en el buscapersonas mutt muestra la hora en el encabezado Fecha en UTC en lugar de en mi zona horaria local. La vista de índice muestra la hora local correctamente. Encontré esta vieja publicación de la lista de correo que describe cómo hacer que se muestre la hora local en la barra de estado en la parte inferior de la pantalla, pero esto todavía no "arregla" la hora en el encabezado Fecha en la parte superior de la pantalla. ¿Hay alguna forma de hacer que el buscapersonas convierta la hora del encabezado de la fecha en hora local?

Ben Williams
fuente

Respuestas:

3

En su .muttrcagregar la siguiente línea:

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

Esto cambiará el Date:encabezado del mensaje (sólo pantalla) a su zona horaria local si el encabezado contenía un RFC fecha válida con formato. Si el formato de fecha proporcionado era incorrecto (después de todo, estamos tratando con una entrada de usuario no confiable) se conservará. Para combatir un posible intento de inyectar el código de shell a través del encabezado, el sedpatrón implementa una lista blanca basada en RFC 5322 (este RFC define el formato del Date:campo).

Tenga en cuenta que muttlimita la línea de comando para que no tenga más de 255 caracteres de largo, por lo tanto, optimicé el sedcomando original que tenía una lista blanca más estricta para caber en 255 bytes. Si planea hacer otras cosas con el mensaje, entonces el sedcomando completo que puede poner en un script es:

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"
galaxia
fuente
¿Existe la posibilidad de hacer que eso funcione en macOS? Me gustaría incluir eso en mi filter.sedarchivo. ¡Gracias!
Philipp L.
No existe, a menos que esté utilizando GNU sed (por ejemplo, a través de Homebrew): los sedcomandos anteriores se basan en el emodificador del scomando. Ese modificador es una extensión GNU y macOS'es sedes el BSD.
galaxia
La respuesta de @viric es buena. No es necesario cambiar el mensaje a través del filtro.
Jangid
@Jangid, lea la solicitud original y específicamente pide la visualización adecuada de una zona local en la parte superior de la página y no en la línea de estado.
galaxia
@galaxy ¡Oh! si. Acabo de notar eso. Correcto.
Jangid
11

El formato en el índice se controla mediante la index_formatconfiguración: se genera mediante mutt. El Dateencabezado no está controlado por mutt, es un encabezado incluido con el mensaje que solo se muestra. Si muestra la hora UTC es porque el servidor remitente decidió usar UTC al generar el encabezado. La única forma de cambiarlo es cambiar el mensaje en sí, ya sea cuando lo reciba o cuando lo vea.

Cambiarlo tal como viene significa agregar un filtro a su agente de entrega de correo, pero debe ser lo suficientemente sofisticado como para analizar el Dateencabezado existente y reescribirlo. Es casi seguro que mutt vuelva a formatear el mensaje cuando lo mire. Puede establecer la display_filterpropiedad en un archivo ejecutable y canalizará cualquier mensaje que abra a través del ejecutable antes de mostrarlo.

Tendrá que escribir un script o programa de shell que lee cada línea del mensaje y reemplaza el uno con el encabezado Fecha, o encontrar un guión existente (hay uno aquí que el trabajo de fuerza, aunque no parece que en realidad debería ser necesario para involucrar un archivo temporal)

Michael Mrozek
fuente
5

Siguiendo el consejo de Gilles, aquí hay una versión que usa un archivo temporal y 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
fuente
Esto es susceptible a los ataques de inyección de código a través de un Date:encabezado con formato incorrecto ; si ingresa a una subshell, debe validar / desinfectar la entrada.
galaxia
2

Aquí hay una solución de 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"

Y mostrar LocalDate: en muttrc:

unignore localdate
fraff
fuente
¿Cómo invocas esto?
Janus Troelsen
@JanusTroelsen, creo que se asigna a la secuencia de comandos display_filteren .muttrc.
galaxia
2

set display_filter="/PATH/TO/THIS/PYTHON/FILE"en su .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
fuente
La línea comentada es susceptible a ataques de inyección de código a través de un Date:encabezado con formato incorrecto : si ingresa a una subshell, debe validar / desinfectar la entrada; de lo contrario, el script está bien desde el punto de vista de la seguridad. Sin embargo, es bastante pesado para un script que se ejecuta en cada mensaje que navega.
galaxia
2

Solución Perl obligatoria que conserva el encabezado "Fecha" al tiempo que agrega un encabezado "Fecha-Local" adicional para contener la versión de hora local:

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

Hice un script de shell como se describe al final de la respuesta de Michael que hace el trabajo por mí:

#!/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
fuente
1
Analizar correos electrónicos es bastante complicado. Recomiendo usar una herramienta dedicada como formail(parte del paquete procmail ) o reformail(parte de maildrop ) para extraer el Date:encabezado existente y colocar uno nuevo. Tenga cuidado con casos extremos como un Date:encabezado faltante o mal formateado.
Gilles 'SO- deja de ser malvado'