Imprimindo mensagens de e-mail do mutt - como evitar a quebra de linha?

3

Eu uso o mutt como cliente de e-mail e recentemente decidi consertar minha configuração de impressão de e-mail.

Eu sei sobre o Muttprint, mas decidi não usá-lo. Eu vim com o seguinte.

Em .muttrc , tenho:

set print_command="grep -v X-Spam-Status | $HOME/bin/mutt_print.sh"

O script ~/bin/mutt_print.sh , que eu adaptei das coisas que encontrei na net, é o seguinte:

#!/bin/bash

PDIR="$HOME/tmp/mutt_print" 
OPEN_PDF=zathura

# create temp dir if it does not exist
if [ ! -d "$PDIR" ]; then
    mkdir -p "$PDIR" 2>/dev/null
    if [ $? -ne 0 ]; then
        echo "Unable to make directory '$PDIR'" 1>&2
        exit 2
    fi
fi

infile="'mktemp $PDIR/mutt_XXXXXXXX.txt'"
tmpfile="'mktemp $PDIR/mutt_XXXXXXXX.ps'"
outfile="'mktemp $PDIR/mutt_XXXXXXXX.pdf'"

echo "infile = $infile"
echo "tmpfile = $tmpfile"
echo "outfile = $outfile"

while read line
do
  echo "$line" >> $infile
done < "${1:-/dev/stdin}"

echo "running vim $infile -c \"hardcopy > $outfile | q\""
vim $infile -c "hardcopy > $tmpfile | q"
echo "running ps2pdf $tmpfile $outfile"
ps2pdf $tmpfile $outfile

read
$OPEN_PDF $outfile >/dev/null 2>&1 &
sleep 1
rm $infile $tmpfile $outfile

Então, quando eu decido imprimir uma mensagem, Mutt a abre com Zathura, e eu posso imprimir ou salvar o PDF - esta é a configuração que eu quero.

No entanto, notei que embora eu usei grep para remover a linha X-Spam-Status , nem sempre funciona: às vezes, o mesmo parece ser quebrado antes de ser enviado ao comando de impressão, e parte dele é exibida no PDF:

Date: Wed, 11 May 2016 21:17:14 −0300
From: John Doe <[email protected]>
To: my-email@here
Subject: Re: blah
tests=FREEMAIL_FROM,HTML_MESSAGE,RDNS_NONE,T_DKIM_INVALID

A linha X-Spam-Status na mensagem original era

X-Spam-Status: No, hits=2.4 required=8.0 tests=FREEMAIL_FROM,HTML_MESSAGE,RDNS_NONE,T_DKIM_INVALID

que é dividido entre required=8.0 e tests... .

Então - como posso evitar a quebra dessa linha?

(saúdo também quaisquer sugestões de melhoria para o script)

    
por Jay 18.05.2016 / 16:12

2 respostas

3

Parece que X-Spam-Status line é um cabeçalho "continuado" RFC822 que abrange várias linhas.

Um cabeçalho começa com espaços não brancos no primeiro caractere de uma linha. Uma linha não vazia com espaço em branco no início é uma continuação da linha anterior e uma linha em branco termina os cabeçalhos.

Se você quiser filtrar um cabeçalho específico, precisará de algo mais com RFC822 do que grep . Talvez uma coisa perl ou awk .

Você pode até fazer algo sobre isso

while read line
do
  echo "$line" >> $infile
done < "${1:-/dev/stdin}"

como se não ecoasse uma linha que começa com X-Spam-Status (e defina um sinalizador), pule as linhas "continuadas" até que você acerte um novo cabeçalho (e limpe o sinalizador).

De qualquer forma, é necessária a conscientização do programa sobre como os cabeçalhos RFC822 são formatados.

Talvez você precise se perguntar se realmente se importa com esse cabeçalho em sua impressão

Ainda assim, um filtro não é tão difícil

#!/user/bin/perl

my $skip=0;

# First do the headers
while(<STDIN>)
{
        #Test for end of headers
        if(/^\s*$/)
        {
                #copy the header ending blank
                printf $_;

                #exit the while loop
                last;
        }

        #Starts with non whitespace, new header
        $skip = 0 if /^\S/;

        #skip stuff if its the header we don't want
        $skip = 1 if /^X-Spam-Status/i;

        #copy lines if we're not skipping
        print $_ if !$skip;
}

# now the rest of the file
while(<STDIN>)
{
        #copy lines
        print $_;
}
    
por 18.05.2016 / 16:55
2

Como @infixed diz, o cabeçalho X-Spam-Status continua em várias linhas.

Se você tiver procmail instalado, poderá usar seu utilitário formail para concatenar os cabeçalhos continuados.

De man formail :

-c      Concatenate continued fields in the header. Might be convenient when postprocessing mail with standard (line oriented) text utilities.

Por exemplo:

set print_command="formail -c | grep -v X-Spam-Status: | $HOME/bin/mutt_print.sh"

Melhor ainda, você pode usar formail -I para remover um cabeçalho, sem a necessidade de grep -v :

set print_command="formail -I X-Spam-Status | $HOME/bin/mutt_print.sh"

-I headerfield

Same as -i, except that any existing similar fields are simply removed. If headerfield consists only of a field-name, it effectively deletes the field.

RE: melhorias no script:

  1. Por que usar vim (e cópia impressa ) quando ferramentas como a2ps e enscript existirem?

    Ambos têm todos os tipos de opções úteis para formatar o texto e a saída do postscript.

  2. Por que o loop lento while read line... quando você pode usar apenas cat ${1:--} > "$infile" para salvar stdin em um arquivo?

  3. Sempre coloque aspas duplas em torno de suas variáveis ao usá-las. por exemplo. não use $infile , use "$infile" .

  4. Use $ (...) em vez de carrapatos.

  5. O script não usa nenhum recurso específico do bash, então use #!/bin/sh (ou talvez #!/bin/dash se você o tiver instalado).

  6. Se você estiver usando mkdir -p , não será necessário testar se o diretório já existe. mkdir -p faz isso para você já.

  7. gjots2lpr do pacote gjots2 parece fazer a maioria ou a totalidade do seu script.

    Seu script pode ser substituído por um simples wrapper em torno de gjots2lpr que define as variáveis de ambiente usadas para substituir os padrões (por exemplo, para informar se deve usar a2ps ou enscript , que ps / pdf viewer usará , qual comando de impressão usar, etc).

    De gjots2lpr -h :

Usage: gjots2lpr [-pt ] [ filename ... ]

Prints a text file - if possible using postscript or PDF and available pre-viewers and printer dialog. It looks for and uses whatever utilities it can find on the system.

If 'filename' is not given then STDIN is printed.

    
por 18.05.2016 / 23:40