使用Procmail

时间:2016-05-31 16:06:59

标签: exim procmail html2ps

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

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

我正在使用以下内容来实现此目的;

  1. 进出口
  2. procmail的
  3. html2ps的
  4. 两个自定义脚本(在下面发布)
  5. 流程

    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文件发送到指定的打印机。
    7. 问题

      1. 在HTML2PS阶段,会生成错误并将NDR发送回发件人,说明打开图像时出错。 打开cid时出错:logo.jpg
      2. PostScript文件已成功打印,但显然不包含电子邮件中的图像。
      3. 我的问题是:如何从电子邮件中获取这些图像,以便它们能够在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
        

        process_mail

        #/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
        }'
        

        编辑:格式化

2 个答案:

答案 0 :(得分:1)

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

<强>应用

  1. 进出口
  2. CUPS
  3. Mhonarc(不在repo的.RPM和网站https://www.mhonarc.org/
  4. procmail的
  5. html2ps的
  6. 工作原理

    1. 电子邮件将发送到两个框中都存在的用户帐户。
    2. 通过电子邮件发送给Procmail的Exim管道
    3. Procmail在用户主目录中查找.procmailrc并获取 动作。
    4. Mhonarc将电子邮件转换为HTML文件,保存图像和附件。
    5. 使用“sed”,打开HTML文件并查找电子邮件的开头()并将所有文本收集到文件末尾
    6. 管道再次“sed”以删除由Mhonarc添加的多余HTML标记(hr标记)
    7. 管道转换为Html2ps以转换为PostScript
    8. 管道到指定的打印机(打印机的名称与用户帐户相同)
    9. 使用上面的过程,我可以将它放到一个脚本,.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”,并且可能有更简单的方法来实现这一目标。我会在某个时候进一步调查。

      希望这有助于某人:)

答案 1 :(得分:0)

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

xmlstarletcid:链接的src属性中删除img前缀的简单var SCRIPT_ID = "1eC5VsM2vkJXa9slM40MTKTlfARGAGyK1myMCU3AB_-Ox_jGxQaoPM8P2"; // get a callback url to render in popup function getAuthURL() { var authorizeURL = getCallbackURL('testCallback'); return authorizeURL; } // generate a user callback url function getCallbackURL(callback) { var state = ScriptApp.newStateToken().withTimeout(3600).withMethod(callback).createToken(); return 'https://script.google.com/macros/d/'+SCRIPT_ID+'/usercallback?state='+state; } // generate login function doGet(e){ return HtmlService.createTemplate("<div><p><a href='<?=getAuthURL()?>' id='start-auth'><?=getAuthURL()?></a></p></div>") .evaluate()); } enter code here // dummy callback function function testCallback(e){ return HtmlService.createHtmlOutput('<b>Success. You can close this window. !</b>') } 脚本或类似内容应该不会很难,但可能还有其他一些内容发现如果你尝试这条道路就需要做。