2

我需要一些建议/推动正确的方向。

我编写了一些小脚本,接收传入的 HTML 电子邮件,将其转换为 PostScript,然后通过 CUPS 将其发送到指定的打印机。打印机基于电子邮件的收件人。

我正在使用以下方法来实现这一点;

  1. 进出口
  2. 收件箱
  3. HTML2PS
  4. 两个自定义脚本(发布在下面)

流量

  1. Exim 收到一封电子邮件并传递给 Procmail
  2. .procmailrc 调用自定义脚本“process_mail”,将主题和内容作为参数传递
  3. “process_mail”将内容拉入一个函数并调用“get_html_from_message”(我还没有对主题做任何事情)
  4. “get_html_from_message”转储除 HTML 之外的所有内容
  5. 然后将 HTML 转换为 PostScript
  6. PostScript 文件被发送到指定的打印机。

问题

  1. 在 HTML2PS 阶段会生成一个错误,并将 NDR 发送回发件人,说明打开图像时出错。打开 cid:logo.jpg 时出错
  2. PostScript 文件已成功打印,但显然不包含电子邮件中的图像。

我的问题是:如何从电子邮件中获取这些图像,以便它们在 PostScript 文件中成功打印出来?

如果 PostScript 不适合,我很乐意转换为 PDF,但即使转换为 PDF 也会让我没有图像,因为我无法获取它们。

.procmailrc

SHELL=/bin/bash

# Extract the subject and normalise
SUBJECT=`formail -x"Subject: "\
| /usr/bin/tr '[:space:][:cntrl:][:punct:]' '_' | expand | sed -e     's/^[_]*//' -e 's/[_]*$//'`
YMD=`date +%Y%m%d`

MAKE_SURE_DIRS_EXIST=`
mkdir -p received_mail/backup
if [ ! -z ${SUBJECT} ]
then
    mkdir -p received_mail/${YMD}/${SUBJECT}
else
    mkdir -p received_mail/${YMD}/no_subject
fi
`

# Backup all received mail into the backup directory appending to a file named by date
:0c
received_mail/backup/${YMD}.m

# If no subject, just store the mail
:0c
* SUBJECT ?? ^^^^
received_mail/${YMD}/no_subject/.

# Else there is a subject, generate a unique filemane, place the received email 
# in that file and then execute process_mail passing the filename and subject as parameters
:0Eb
| f=`uuidgen`; export f; cat > received_mail/${YMD}/${SUBJECT}/${f};     $HOME/bin/process_mail received_mail/${YMD}/${SUBJECT}/${f} "${SUBJECT}"

# and don't deliver to standard mail, don't want to clutter up the inbox. 
:0
/dev/null

进程邮件

#/bin/bash

# Test Printer
printer=$(whoami)

file=$1
subject=$2

function process_rrs {
typeset file
file=$1
cat $file \
| $HOME/bin/get_html_from_message \
| html2ps \
| lp -d ${printer} -o media=a4 2>&1
}

case "$subject" in
*)
    process_rrs $file
    ;;
esac

get_html_from_message

cat | awk '
BEGIN {
typeout=0
}
{
if($0 ~ /<html/)
    typeout=1
if($0 ~ /^------=/)
    typeout=0
if(typeout)
    print $0
}'

编辑:格式化

4

2 回答 2

2

我已经想出了如何实现这一目标。详情如下。所有这些都在两个负载平衡的 CentOS 6 机器上运行。

应用

  1. 进出口
  2. 杯子
  3. Mhonarc(不在 repo 中。RPM 和网站在这里https://www.mhonarc.org/
  4. 收件箱
  5. html2ps

这个怎么运作

  1. 一封电子邮件将发送到两个盒子上都存在的用户帐户。
  2. Exim 通过管道将电子邮件发送到 Procmail
  3. Procmail 在用户主目录中查找 .procmailrc 并采取行动。
  4. Mhonarc 将电子邮件转换为 HTML 文件,保存图像和附件。
  5. 使用“sed”,打开 HTML 文件并查找电子邮件 () 的开头并将所有文本收集到文件末尾
  6. 再次管道到“sed”以删除由 Mhonarc 添加的多余的 HTML 标记(hr 标记)
  7. 管道到 Html2ps 以转换为 PostScript
  8. 管道到指定打印机(打印机名称与用户帐户相同)

使用上述过程,我可以将它放到一个脚本中,.procmailrc。这就是我在 .procmailrc 文件中写的内容。

SHELL=/bin/bash

# Designate the printer. Printer names match usernames so you don't have to manually change 60+ files. 
printer=`whoami`

# Generate a unique ID
f=`uuidgen`

# Convert email, including headers and body into a HTML file and save off the images using MHONARC https://www.mhonarc.org/
# Open file and search <!--X-Body-of-Message--> string using SED and collect all text to EOF.
# Pipe the result into SED again to remove unwanted HTML tags added by MHONARC
# Pipe result into HTML2PS to convert to PostScript
# Pipe PostScript file to the designated printer
:0E
| mhonarc -single > ${f}.html; sed -n '/^<!--X-Body-of-Message-->$/ { s///; :a; n; p; ba; }' ${f}.html | sed -e '/<hr>/d' | html2ps | lp -d ${printer} -o media=a4 2>&1

# Finally, delete the email
:0
/dev/null

我不太了解“sed”,可能有更简单的方法来实现这一点。我会在某个时候进一步调查。

希望这可以帮助某人:)

于 2016-06-03T14:49:08.867 回答
0

问题可能是对 HTML 如何在电子邮件中表示的不完全理解。通常会有一个包含一个 HTML 部分和多个图像的 MIME 多部分。HTML 使用cid:图像链接中的寻址方案来引用这些同级部分。但是如果你只提取 HTML,它就不再存在于它有任何兄弟的上下文中。(即使您将所有部分提取到文件中,cid:通常也不会映射到本地文件。也许您可以对 HTML 进行后处理以解决该问题;但我认为您的方法可能应该重新考虑。您是否考虑过使用邮件客户端具有用于呈现这些消息的本机 HTML 支持?)

从任何链接的属性中去除前缀​​的简单xmlstarlet脚本或类似脚本应该不难,但是如果您尝试此路径,您可能会发现需要做的其他事情。cid:srcimg

于 2016-05-31T18:39:45.717 回答