Python smtplib:只有几个中的第一封电子邮件到达目的地

时间:2014-07-03 10:13:45

标签: python email sendmail smtplib

我已经组合了一个函数send_email [1]来发送支持纯文本和HTML消息的电子邮件。它运作良好,但我有一个问题,我不知道如何调试。我的系统有sendmail作为其MTA。

该函数在for循环中调用,如下所示:

for data in data_set:
    subject, message = process(data)  # Irrelevant stuff

    send_email(subject, message, "fixed@email.address")

smtplib [1]的调试输出中,我看到对send_email的所有调用都已成功完成。奇怪的行为是:

  • 如果message是"短" (我用一行测试过),所有发送的消息实际到达fixed@email.address
  • 如果message是"不是短暂的" (即,我使用真正的process_data函数生成的多行),只有第一个电子邮件确实到达,而其他人不会,即使调试输出{ [1]中的{1}}报告了每封电子邮件和所有电子邮件的成功。
  • 如果smtplib是平等的,则不是短暂的" 每封邮件的目标地址不同,然后所有邮件都会到达目的地。

对于后一种情况,message循环看起来像:

for

预期的行为当然是针对不同数据的不同地址,但我担心不理解为什么会发生这种情况可能会在以后以意想不到的方式让我感到厌恶。

[1]我的发送邮件功能:

addresses = ["fixed@email.address", "fixed.2@email.address", ...]
for data, addr in zip(data_set, addresses):
    subject, message = process(data)  # Irrelevant stuff

    send_email(subject, message, addr)

2 个答案:

答案 0 :(得分:0)

我发送电子邮件的工作解决方案:

from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import smtplib

class EMail(object):
        """ Class defines method to send email
        """
        def __init__(self, mailFrom, server, usrname, password, files, debug=False):
                self.debug = debug
                self.mailFrom = mailFrom
                self.smtpserver = server
                self.EMAIL_PORT = 587
                self.usrname = usrname
                self.password = password


        def sendMessage(self, subject, msgContent, files, mailto):
            """ Send the email message

                Args:
                    subject(string): subject for the email
                    msgContent(string): email message Content
                    files(List): list of files to be attached
                    mailto(string): email address to be sent to
            """

            msg = self.prepareMail(subject, msgContent, files, mailto)

            # connect to server and send email
            server=smtplib.SMTP(self.smtpserver, port=self.EMAIL_PORT)
            server.ehlo()
            # use encrypted SSL mode
            server.starttls()
            # to make starttls work
            server.ehlo()
            server.login(self.usrname, self.password)
            server.set_debuglevel(self.debug)
            try:
                failed = server.sendmail(self.mailFrom, mailto, msg.as_string())
            except Exception as er:
                print er
            finally:
                server.quit()

        def prepareMail(self, subject, msgHTML, attachments, mailto):
            """ Prepare the email to send
                Args:
                    subject(string): subject of the email.
                    msgHTML(string): HTML formatted email message Content.
                    attachments(List): list of file paths to be attached with email. 
            """
            msg = MIMEMultipart()
            msg['From'] = self.mailFrom
            msg['To'] = mailto
            msg['Date'] = formatdate(localtime=True)
            msg['Subject'] = subject

            #the Body message
            msg.attach(MIMEText(msgHTML, 'html'))
            msg.attach(MIMEText("Add signature here"))
            if attachments:
                for phile in attachments:
                        # we could check for MIMETypes here
                        part = MIMEBase('application',"octet-stream")
                        part.set_payload(open(phile, "rb").read())
                        Encoders.encode_base64(part)
                        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(phile))
                        msg.attach(part)
            return msg

我希望这会有所帮助。

答案 1 :(得分:0)

我的工作解决方案以这种方式格式化您的列表(经过几个小时的实验):

@Component({ selector: 'am-card', template: ` <span>{{ articleLength }} - {{ cardTitle }}<span> ` }) export class AmCard { @Input() cardTitle: string; @Input() cardLink: string; @Input() cardAuthor: string; constructor(@Inject(forwardRef(() => Article)) article: Article) { // here you have the parent element - `article` // you can do whatever you want with it this.articleLength = article.articleArr.length; setTimeout(() => { article.articleSubmit({ value: Math.random() }, {}, {}); }, 1000) } }

我用过:

@Component({ /* ... component config */})
class AmCard {
  // ... input properties
  @Output() callSubmit = new EventEmitter();

  constructor() {
    setTimeout(() => {
      // send message to a parent component (Article)
      this.callSubmit.next({ value: Math.random() });
    }, 1000)
  }
}

@Component({
  // ... component config
  template: `
    <h3>Article array:</h3>
    <div *ng-for="#item of articleArr">
      <am-card 
        [card-title]="item.title" 
        [card-link]="item.url" 
        [card-author]="item.user"
        `/* handle message from AmCard component */+`
        (call-submit)=" articleSubmit($event, {}, {}) " 
      ></am-card>
    </div>
  `
})
class Article{
  // ... properties and constructor

  articleSubmit(aa, an, au) {
    this.articleArr.push({ title: as.value, user: an.value, url: au.value });
  }
}

将我的QString转换为字符串然后转换为列表,并使用&#34;,&#34;

在我的情况下,COMMASPACE无效,因为默认情况下已经添加了分割空间。