【问题标题】:How to do scheduled sending of email with django-mailer如何使用 django-mailer 定时发送电子邮件
【发布时间】:2010-11-13 16:59:17
【问题描述】:

我正在制作一个 django 应用程序,该应用程序需要能够发送电子邮件,然后在给定时间发送出去。我在想我可以使用 django-mailer 将东西放入 que 然后发送。但是,即使他们的示例案例列表列出了这是一项功能,我似乎也无法找出具体方法。

我需要的是能够在 django-mailer 的消息模型中设置一个“when_to_send”字段,并且当 cron 作业触发 send_mail 函数时,这需要过滤掉具有“when_to_send”日期的那些大于当前时间...

def send_all():
    """
    Send all eligible messages in the queue.
    """

    lock = FileLock("send_mail")

    logging.debug("acquiring lock...")
    try:
        lock.acquire(LOCK_WAIT_TIMEOUT)
    except AlreadyLocked:
        logging.debug("lock already in place. quitting.")
        return
    except LockTimeout:
        logging.debug("waiting for the lock timed out. quitting.")
        return
    logging.debug("acquired.")

    start_time = time.time()

    dont_send = 0
    deferred = 0
    sent = 0

    try:
        for message in prioritize():
            if DontSendEntry.objects.has_address(message.to_address):
                logging.info("skipping email to %s as on don't send list " % message.to_address)
                MessageLog.objects.log(message, 2) # @@@ avoid using literal result code
                message.delete()
                dont_send += 1
            else:
                try:
                    logging.info("sending message '%s' to %s" % (message.subject.encode("utf-8"), message.to_address.encode("utf-8")))
                    core_send_mail(message.subject, message.message_body, message.from_address, [message.to_address])
                    MessageLog.objects.log(message, 1) # @@@ avoid using literal result code
                    message.delete()
                    sent += 1
                except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError), err:
                    message.defer()
                    logging.info("message deferred due to failure: %s" % err)
                    MessageLog.objects.log(message, 3, log_message=str(err)) # @@@ avoid using literal result code
                    deferred += 1
    finally:
        logging.debug("releasing lock...")
        lock.release()
        logging.debug("released.")

    logging.info("")
    logging.info("%s sent; %s deferred; %s don't send" % (sent, deferred, dont_send))
    logging.info("done in %.2f seconds" % (time.time() - start_time))

有人知道如何自定义此功能以在 message.when_to_send 字段大于当前时间的地方不发送电子邮件吗?

【问题讨论】:

    标签: python django email schedule django-mailer


    【解决方案1】:

    你需要为django-mailer实现cron作业:

    * * * * * (cd $PINAX; /usr/local/bin/python2.5 manage.py send_mail >> $PINAX/cron_mail.log 2>&1)
    

    然后在engine.py 第 96 行:

       # Get rid of "while True:"
       while not Message.objects.all():
            # Get rid of logging.debug("sleeping for %s seconds before checking queue again" % EMPTY_QUEUE_SLEEP)
            # Get rid of sleep
            send_all()
    

    【讨论】:

      【解决方案2】:

      您可以在消息处理循环下的条件中添加另一个子句(您还需要在文件顶部导入日期时间):

               for message in prioritize():
                  if DontSendEntry.objects.has_address(message.to_address):
                      logging.info("skipping email to %s as on don't send list " % message.to_address)
                      MessageLog.objects.log(message, 2) # @@@ avoid using literal result code
                      message.delete()
                      dont_send += 1
                  elif message.when_to_send > datetime.datetime.now():
                      continue
                  else:
                      try:
                        ... the rest of your code ...
      

      【讨论】:

      • 我试过这个,但是结果是从priority()函数中无限循环,这当然不好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多