def send_one(email, smtpserver=None, auto_commit=True, now=False): '''Send Email Queue with given smtpserver''' email = frappe.db.sql('''select name, status, communication, message, sender, recipient, reference_doctype from `tabEmail Queue` where name=%s for update''', email, as_dict=True)[0] if email.status != 'Not Sent': # rollback to release lock and return frappe.db.rollback() return frappe.db.sql("""update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) try: if auto_commit: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email.sender, email.recipient, encode(email.message)) frappe.db.sql("""update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.rollback() frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s where name=%s""", (unicode(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) if now: raise e else: # log to scheduler log log('frappe.email.queue.flush', unicode(e))
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False: msgprint(_("Emails are muted")) from_test = True for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test # additional check check_bulk_limit([]) if frappe.are_emails_muted(): msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3""", auto_commit=auto_commit) for i in xrange(100): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by priority desc, creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql("""update `tabBulk Email` set status='Not Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit) finally:
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test # additional check check_bulk_limit([]) if frappe.are_emails_muted(): msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3 and status='Not Sent'""", auto_commit=auto_commit) for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by priority desc, creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.replace_sender_in_email(email) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql("""update `tabBulk Email` set status='Not Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False: msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3""", auto_commit=auto_commit) for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql( """update `tabBulk Email` set status='Sending' where name=%s""", (email["name"], ), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql( """update `tabBulk Email` set status='Sent' where name=%s""", (email["name"], ), auto_commit=auto_commit) except Exception, e: frappe.db.sql( """update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def send_one(email, smtpserver=None, auto_commit=True, now=False): '''Send bulk email with given smtpserver''' if not smtpserver: smtpserver = SMTPServer() frappe.db.sql( """update `tabBulk Email` set status='Sending' where name=%s""", (email.name, ), auto_commit=auto_commit) try: if auto_commit: smtpserver.setup_email_account(email.reference_doctype) smtpserver.replace_sender_in_email(email) smtpserver.sess.sendmail(email.sender, email.recipient, encode(email.message)) frappe.db.sql( """update `tabBulk Email` set status='Sent' where name=%s""", (email.name, ), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql( """update `tabBulk Email` set status='Not Sent' where name=%s""", (email.name, ), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email.name), auto_commit=auto_commit) if now: raise e
def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=False): '''Send Email Queue with given smtpserver''' email = frappe.db.sql('''select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, show_as_cc, add_unsubscribe_link, attachments from `tabEmail Queue` where name=%s for update''', email, as_dict=True)[0] recipients_list = frappe.db.sql('''select name, recipient, status from `tabEmail Queue Recipient` where parent=%s''', email.name, as_dict=1) if frappe.are_emails_muted(): frappe.msgprint(_("Emails are muted")) return if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1: return if email.status not in ('Not Sent', 'Partially Sent'): # rollback to release lock and return frappe.db.rollback() return frappe.db.sql( """update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) try: if not frappe.flags.in_test: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype, sender=email.sender) for recipient in recipients_list: if recipient.status != "Not Sent": continue message = prepare_message(email, recipient.recipient, recipients_list) if not frappe.flags.in_test: smtpserver.sess.sendmail(email.sender, recipient.recipient, encode(message)) recipient.status = "Sent" frappe.db.sql( """update `tabEmail Queue Recipient` set status='Sent', modified=%s where name=%s""", (now_datetime(), recipient.name), auto_commit=auto_commit) #if all are sent set status if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", ("No recipients to send to", email.name), auto_commit=auto_commit) if frappe.flags.in_test: frappe.flags.sent_mail = message return if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Partially Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception as e: frappe.db.rollback() if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) if now: print(frappe.get_traceback()) raise e else: # log to Error Log log('frappe.email.queue.flush', text_type(e))
def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=False): '''Send Email Queue with given smtpserver''' email = frappe.db.sql('''select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, show_as_cc, add_unsubscribe_link, attachments from `tabEmail Queue` where name=%s for update''', email, as_dict=True)[0] recipients_list = frappe.db.sql('''select name, recipient, status from `tabEmail Queue Recipient` where parent=%s''',email.name,as_dict=1) if frappe.are_emails_muted(): frappe.msgprint(_("Emails are muted")) return if cint(frappe.defaults.get_defaults().get("hold_queue"))==1 : return if email.status not in ('Not Sent','Partially Sent') : # rollback to release lock and return frappe.db.rollback() return frappe.db.sql("""update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) try: if not frappe.flags.in_test: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype, sender=email.sender) for recipient in recipients_list: if recipient.status != "Not Sent": continue message = prepare_message(email, recipient.recipient, recipients_list) if not frappe.flags.in_test: smtpserver.sess.sendmail(email.sender, recipient.recipient, encode(message)) recipient.status = "Sent" frappe.db.sql("""update `tabEmail Queue Recipient` set status='Sent', modified=%s where name=%s""", (now_datetime(), recipient.name), auto_commit=auto_commit) #if all are sent set status if any("Sent" == s.status for s in recipients_list): frappe.db.sql("""update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s where name=%s""", ("No recipients to send to", email.name), auto_commit=auto_commit) if frappe.flags.in_test: frappe.flags.sent_mail = message return if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later if any("Sent" == s.status for s in recipients_list): frappe.db.sql("""update `tabEmail Queue` set status='Partially Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception as e: frappe.db.rollback() if any("Sent" == s.status for s in recipients_list): frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) else: frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) if now: print(frappe.get_traceback()) raise e else: # log to Error Log log('frappe.email.queue.flush', text_type(e))
def send_one(email, smtpserver=None, auto_commit=True, now=False): """Send Email Queue with given smtpserver""" email = frappe.db.sql( """select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, show_as_cc, add_unsubscribe_link, attachments, retry from `tabEmail Queue` where name=%s for update""", email, as_dict=True, ) if len(email): email = email[0] else: return recipients_list = frappe.db.sql( """select name, recipient, status from `tabEmail Queue Recipient` where parent=%s""", email.name, as_dict=1, ) if frappe.are_emails_muted(): frappe.msgprint(_("Emails are muted")) return if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1: return if email.status not in ("Not Sent", "Partially Sent"): # rollback to release lock and return frappe.db.rollback() return frappe.db.sql( """update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit, ) if email.communication: frappe.get_doc( "Communication", email.communication).set_delivery_status(commit=auto_commit) email_sent_to_any_recipient = None try: message = None if not frappe.flags.in_test: if not smtpserver: smtpserver = SMTPServer() # to avoid always using default email account for outgoing if getattr(frappe.local, "outgoing_email_account", None): frappe.local.outgoing_email_account = {} smtpserver.setup_email_account(email.reference_doctype, sender=email.sender) for recipient in recipients_list: if recipient.status != "Not Sent": continue message = prepare_message(email, recipient.recipient, recipients_list) if not frappe.flags.in_test: method = get_hook_method("override_email_send") if method: queue = frappe.get_doc("Email Queue", email.name) method(queue, email.sender, recipient.recipient, message) return else: smtpserver.sess.sendmail(email.sender, recipient.recipient, message) recipient.status = "Sent" frappe.db.sql( """update `tabEmail Queue Recipient` set status='Sent', modified=%s where name=%s""", (now_datetime(), recipient.name), auto_commit=auto_commit, ) email_sent_to_any_recipient = any("Sent" == s.status for s in recipients_list) # if all are sent set status if email_sent_to_any_recipient: frappe.db.sql( """update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit, ) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", ("No recipients to send to", email.name), auto_commit=auto_commit, ) if frappe.flags.in_test: frappe.flags.sent_mail = message return if email.communication: frappe.get_doc( "Communication", email.communication).set_delivery_status(commit=auto_commit) if smtpserver.append_emails_to_sent_folder and email_sent_to_any_recipient: smtpserver.email_account.append_email_to_sent_folder(message) except ( smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, smtplib.SMTPRecipientsRefused, JobTimeoutException, ): # bad connection/timeout, retry later if email_sent_to_any_recipient: frappe.db.sql( """update `tabEmail Queue` set status='Partially Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit, ) else: frappe.db.sql( """update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit, ) if email.communication: frappe.get_doc( "Communication", email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception as e: frappe.db.rollback() if email.retry < 3: frappe.db.sql( """update `tabEmail Queue` set status='Not Sent', modified=%s, retry=retry+1 where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit, ) else: if email_sent_to_any_recipient: frappe.db.sql( """update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit, ) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit, ) if email.communication: frappe.get_doc( "Communication", email.communication).set_delivery_status(commit=auto_commit) if now: print(frappe.get_traceback()) raise e else: # log to Error Log frappe.log_error("frappe.email.queue.flush")
def send_one(email, smtpserver=None, auto_commit=True, now=False): '''Send Email Queue with given smtpserver''' status = frappe.db.sql( '''select status from `tabEmail Queue` where name=%s for update''', email.name)[0][0] if status != 'Not Sent': # rollback to release lock and return frappe.db.rollback() return frappe.db.sql( """update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) try: if auto_commit: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email.sender, email.recipient, encode(email.message)) frappe.db.sql( """update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later frappe.db.sql( """update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.rollback() frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s where name=%s""", (unicode(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) if now: raise e else: # log to scheduler log log('frappe.email.queue.flush', unicode(e))