procmail处理后的邮件正文编码

时间:2014-10-16 11:29:55

标签: python linux bash procmail

我在SMTP服务器上的 .procmailrc 中有以下行:

BODY=`formail -I ""`

稍后我将此主体回显到本地文件:

echo "$BODY" >> $HOME/$FILENAME; \

我也试过prinf(但我也有同样的效果):

printf "$BODY" >> $HOME/$FILENAME; \

当我读到这个文件时,我可以看到编码已经改变了。这就是我得到的:

Administrator System=C3=B3w

虽然它应该是(波兰语):

Administrator Systemów

如何直接在 .procmailrc 或更高版本(bash / python)中对主体进行解码/编码以获得正确的字符串?

我的.procmailrc中的另一行正常工作,但需要使用perl编码器的其他管道:

SUBJECT=`formail -xSubject: | tr -d '\n' | sed -e 's/^ //' | /usr/bin/perl -MEncode -ne 'print encode ("utf8",decode ("MIME-Header",$_ )) '`

SUBJECT包含UTF8字符,一切看起来都不错。也许有办法在邮件正文中使用类似的解决方案?

行。 我终于把一切都搞定了。这是我做的:

首先是 .procmailrc 文件:

VERBOSE=yes
LOGFILE=$HOME/procmail.log
:0f
* ^From.*(some_address@somedomain.com)
| $HOME/python_script.py

现在到 python_script.py

#!/usr/bin/python

from email.parser import Parser
import sys

temp_file = open("/home/(user)/file.txt","w")
temp_file.write("START\n")

if not message.is_multipart():
        temp_file.write(message.get_payload(decode=True))
else:
        for part in message.get_payload():
                if part.get_content_type() == 'text/plain':
                        temp_file.write(part.get_payload(decode=True))

temp_file.close()

调试最困难的部分是 .procmailrc 配方,我必须测试许多选项:0,:0f,:0fbW等...最后找到最适合的选项

下一个有问题的步骤是直接在 .procmailrc 中解码的$ BODY部分。我找到了解决方案,通过摆脱所有的东西,并将一切都移动到Python脚本。正如三人建议的那样。

2 个答案:

答案 0 :(得分:1)

它没有更改,但是您正在切换标头,以便不再出现正确的Content-Type:标头(您还应该保留Mime-Version:和任何其他标准Content-*标头)。

通过检查邮件客户端中的邮件来源,您应该看到Procmail或Bash实际上没有更改任何内容。您收到的文字实际上是字面Administrator System=C3=B3w,但MIME标题会通知您的电子邮件客户端这是Content-Transfer-Encoding: quoted-printableContent-type: text/plain; charset="utf-8",因此它知道如何正确解码和显示。

如果你只想要有效载荷,你需要自己解码,但为了做到这一点,你需要来自MIME标题的这些信息,所以你不应该在处理消息之前杀掉它们(如果有的话) )。这样的事情,也许是:

from email.parser import Parser
import sys

message = Parser().parse(sys.stdin)
if message['content-type'].lower().startswith('text/'):
    print(message.get_payload(decode=True))
else:
    raise DieScreamingInAnguish('aaaargh!')  # pseudo-pseudocode

这非常简单,因为它假设(就像您当前的,甚至更破碎的解决方案)消息包含单个文本部分。将它扩展到多部分消息在技术上并不难,但是你究竟如何做到这取决于你期望接收的多部分类型,以及你想要对有效负载做什么。

就像在your previous question中一样,如果您打算使用它,我建议您将更多或全部的电子邮件操作移动到Python中。 Procmail没有明确的MIME支持,所以你必须重新发明Procmail中的所有内容,这既不简单也不特别富有成效。

答案 1 :(得分:0)

我认为可能是您echo首先没有返回正确的unicode写入您的文件,以下是可能对您有所帮助的众多解决方案中的两个:

以转义字符回显:

echo -e "$BODY" >> $HOME/$FILENAME; \

或者,使用iconv或类似代码将您的文件编码为utf-8,假设您在linux中有iconv

iconv -t UTF-8 original.txt > encoded_result.txt