Exemplo n.º 1
0
def flush(from_test=False):
	"""flush email queue, every time: called from scheduler"""
	# additional check
	check_email_limit([])

	auto_commit = not from_test
	if frappe.are_emails_muted():
		msgprint(_("Emails are muted"))
		from_test = True

	frappe.db.sql("""update `tabEmail Queue` set status='Expired'
		where datediff(curdate(), creation) > 7 and status='Not Sent'""", auto_commit=auto_commit)

	smtpserver = SMTPServer()

	for i in xrange(500):
		# don't use for update here, as it leads deadlocks
		email = frappe.db.sql('''select * from `tabEmail Queue`
			where status='Not Sent' and (send_after is null or send_after < %(now)s)
			order by priority desc, creation asc
			limit 1''', { 'now': now_datetime() }, as_dict=True)

		if email:
			email = email[0]
		else:
			break

		send_one(email, smtpserver, auto_commit)
Exemplo n.º 2
0
def send(email, append_to=None, retry=1):
	"""send the message or add it to Outbox Email"""
	if frappe.flags.in_test:
		frappe.flags.sent_mail = email.as_string()
		return

	if frappe.are_emails_muted():
		frappe.msgprint(_("Emails are muted"))
		return

	def _send(retry):
		try:
			smtpserver = SMTPServer(append_to=append_to)

			# validate is called in as_string
			email_body = email.as_string()

			smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []), email_body)
		except smtplib.SMTPSenderRefused:
			frappe.throw(_("Invalid login or password"), title='Email Failed')
			raise
		except smtplib.SMTPRecipientsRefused:
			frappe.msgprint(_("Invalid recipient address"), title='Email Failed')
			raise
		except (smtplib.SMTPServerDisconnected, smtplib.SMTPAuthenticationError):
			if not retry:
				raise
			else:
				retry = retry - 1
				_send(retry)

	_send(retry)
Exemplo n.º 3
0
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

        send_one(email, smtpserver, auto_commit)
Exemplo n.º 4
0
def flush(from_test=False):
    """flush email queue, every time: called from scheduler"""
    # additional check

    auto_commit = not from_test
    if frappe.are_emails_muted():
        msgprint(_("Emails are muted"))
        from_test = True

    smtpserver_dict = frappe._dict()

    for email in get_queue():

        if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1:
            break

        if email.name:
            smtpserver = smtpserver_dict.get(email.sender)
            if not smtpserver:
                smtpserver = SMTPServer()
                smtpserver_dict[email.sender] = smtpserver

            if from_test:
                send_one(email.name, smtpserver, auto_commit)
            else:
                send_one_args = {
                    'email': email.name,
                    'smtpserver': smtpserver,
                    'auto_commit': auto_commit,
                }
                enqueue(method='frappe.email.queue.send_one',
                        queue='short',
                        **send_one_args)
Exemplo n.º 5
0
    def can_send_now(self):
        hold_queue = (cint(
            frappe.defaults.get_defaults().get("hold_queue")) == 1)
        if frappe.are_emails_muted() or not self.is_to_be_sent() or hold_queue:
            return False

        return True
Exemplo n.º 6
0
def flush(from_test=False):
	"""flush email queue, every time: called from scheduler"""
	# additional check
	check_bulk_limit([])

	auto_commit = not from_test
	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) > 7 and status='Not Sent'""", auto_commit=auto_commit)

	smtpserver = SMTPServer()

	for i in xrange(500):
		# don't use for update here, as it leads deadlocks
		email = frappe.db.sql('''select * from `tabBulk Email`
			where status='Not Sent' and (send_after is null or send_after < %(now)s)
			order by priority desc, creation asc
			limit 1''', { 'now': now_datetime() }, as_dict=True)

		if email:
			email = email[0]
		else:
			break

		send_one(email, smtpserver, auto_commit)
Exemplo n.º 7
0
def send(email, append_to=None):
	"""send the message or add it to Outbox Email"""
	if frappe.flags.in_test:
		frappe.flags.sent_mail = email.as_string()
		return

	if frappe.are_emails_muted():
		frappe.msgprint(_("Emails are muted"))
		return

	try:
		smtpserver = SMTPServer(append_to=append_to)
		if hasattr(smtpserver, "always_use_account_email_id_as_sender") and \
			cint(smtpserver.always_use_account_email_id_as_sender) and smtpserver.login:
			if not email.reply_to:
				email.reply_to = email.sender
			email.sender = smtpserver.login

		smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []),
			email.as_string())

	except smtplib.SMTPSenderRefused:
		frappe.msgprint(_("Invalid login or password"))
		raise
	except smtplib.SMTPRecipientsRefused:
		frappe.msgprint(_("Invalid recipient address"))
		raise
Exemplo n.º 8
0
def send(email, append_to=None):
    """send the message or add it to Outbox Email"""
    if frappe.flags.in_test:
        frappe.flags.sent_mail = email.as_string()
        return

    if frappe.are_emails_muted():
        frappe.msgprint(_("Emails are muted"))
        return

    try:
        smtpserver = SMTPServer(append_to=append_to)
        if hasattr(smtpserver, "always_use_account_email_id_as_sender") and \
         cint(smtpserver.always_use_account_email_id_as_sender) and smtpserver.login:
            if not email.reply_to:
                email.reply_to = email.sender
            email.sender = smtpserver.login

        smtpserver.sess.sendmail(email.sender,
                                 email.recipients + (email.cc or []),
                                 email.as_string())

    except smtplib.SMTPSenderRefused:
        frappe.msgprint(_("Invalid login or password"))
        raise
    except smtplib.SMTPRecipientsRefused:
        frappe.msgprint(_("Invalid recipient address"))
        raise
Exemplo n.º 9
0
def get_default_outgoing_email_account(raise_exception_not_set=True):
    email_account = _get_email_account({
        "enable_outgoing": 1,
        "default_outgoing": 1
    })

    if not email_account and frappe.conf.get("mail_server"):
        # from site_config.json
        email_account = frappe.new_doc("Email Account")
        email_account.update({
            "smtp_server":
            frappe.conf.get("mail_server"),
            "smtp_port":
            frappe.conf.get("mail_port"),
            "use_tls":
            cint(frappe.conf.get("use_ssl") or 0),
            "email_id":
            frappe.conf.get("mail_login"),
            "password":
            frappe.conf.get("mail_password"),
            "sender":
            frappe.conf.get("auto_email_id", "*****@*****.**")
        })
        email_account.from_site_config = True
        email_account.name = frappe.conf.get("email_sender_name") or "Frappe"

    if not email_account and not raise_exception_not_set:
        return None

    if frappe.are_emails_muted():
        # create a stub
        email_account = frappe.new_doc("Email Account")
        email_account.update({"sender": "*****@*****.**"})

    return email_account
Exemplo n.º 10
0
def get_default_outgoing_email_account(raise_exception_not_set=True):
	email_account = _get_email_account({"enable_outgoing": 1, "default_outgoing": 1})

	if not email_account and frappe.conf.get("mail_server"):
		# from site_config.json
		email_account = frappe.new_doc("Email Account")
		email_account.update({
			"smtp_server": frappe.conf.get("mail_server"),
			"smtp_port": frappe.conf.get("mail_port"),
			"use_tls": cint(frappe.conf.get("use_ssl") or 0),
			"email_id": frappe.conf.get("mail_login"),
			"password": frappe.conf.get("mail_password"),
			"sender": frappe.conf.get("auto_email_id", "*****@*****.**")
		})
		email_account.from_site_config = True

	if not email_account and not raise_exception_not_set:
		return None

	if frappe.are_emails_muted():
		# create a stub
		email_account = frappe.new_doc("Email Account")
		email_account.update({
			"sender": "*****@*****.**"
		})

	return email_account
Exemplo n.º 11
0
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(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 (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)
Exemplo n.º 12
0
def send(email, append_to=None):
    """send the message or add it to Outbox Email"""
    if frappe.flags.in_test:
        frappe.flags.sent_mail = email.as_string()
        return

    if frappe.are_emails_muted():
        frappe.msgprint(_("Emails are muted"))
        return

    try:
        smtpserver = SMTPServer(append_to=append_to)

        # validate is called in as_string
        email_body = email.as_string()

        smtpserver.sess.sendmail(email.sender,
                                 email.recipients + (email.cc or []),
                                 email_body)

    except smtplib.SMTPSenderRefused:
        frappe.msgprint(_("Invalid login or password"))
        raise
    except smtplib.SMTPRecipientsRefused:
        frappe.msgprint(_("Invalid recipient address"))
        raise
Exemplo n.º 13
0
def send(email, append_to=None, retry=1):
	"""send the message or add it to Outbox Email"""
	if frappe.flags.in_test:
		frappe.flags.sent_mail = email.as_string()
		return

	if frappe.are_emails_muted():
		frappe.msgprint(_("Emails are muted"))
		return

	def _send(retry):
		try:
			smtpserver = SMTPServer(append_to=append_to)

			# validate is called in as_string
			email_body = email.as_string()

			smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []), email_body)
		except smtplib.SMTPSenderRefused:
			frappe.throw(_("Invalid login or password"), title='Email Failed')
			raise
		except smtplib.SMTPRecipientsRefused:
			frappe.msgprint(_("Invalid recipient address"), title='Email Failed')
			raise
		except (smtplib.SMTPServerDisconnected, smtplib.SMTPAuthenticationError):
			if not retry:
				raise
			else:
				retry = retry - 1
				_send(retry)

	_send(retry)
Exemplo n.º 14
0
def get_default_outgoing_email_account(raise_exception_not_set=True):
    '''conf should be like:
		{
		 "mail_server": "smtp.example.com",
		 "mail_port": 587,
		 "use_tls": 1,
		 "mail_login": "******",
		 "mail_password": "******",
		 "auto_email_id": "*****@*****.**",
		 "email_sender_name": "Example Notifications",
		 "always_use_account_email_id_as_sender": 0,
		 "always_use_account_name_as_sender_name": 0
		}
	'''
    email_account = _get_email_account({
        "enable_outgoing": 1,
        "default_outgoing": 1
    })
    if email_account:
        email_account.password = email_account.get_password(
            raise_exception=False)

    if not email_account and frappe.conf.get("mail_server"):
        # from site_config.json
        email_account = frappe.new_doc("Email Account")
        email_account.update({
            "smtp_server":
            frappe.conf.get("mail_server"),
            "smtp_port":
            frappe.conf.get("mail_port"),

            # legacy: use_ssl was used in site_config instead of use_tls, but meant the same thing
            "use_tls":
            cint(frappe.conf.get("use_tls") or 0)
            or cint(frappe.conf.get("use_ssl") or 0),
            "login_id":
            frappe.conf.get("mail_login"),
            "email_id":
            frappe.conf.get("auto_email_id") or frappe.conf.get("mail_login")
            or '*****@*****.**',
            "password":
            frappe.conf.get("mail_password"),
            "always_use_account_email_id_as_sender":
            frappe.conf.get("always_use_account_email_id_as_sender", 0),
            "always_use_account_name_as_sender_name":
            frappe.conf.get("always_use_account_name_as_sender_name", 0)
        })
        email_account.from_site_config = True
        email_account.name = frappe.conf.get("email_sender_name") or "Frappe"

    if not email_account and not raise_exception_not_set:
        return None

    if frappe.are_emails_muted():
        # create a stub
        email_account = frappe.new_doc("Email Account")
        email_account.update({"email_id": "*****@*****.**"})

    return email_account
Exemplo n.º 15
0
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:
Exemplo n.º 16
0
def get_default_outgoing_email_account(raise_exception_not_set=True):
	'''conf should be like:
		{
		 "mail_server": "smtp.example.com",
		 "mail_port": 587,
		 "use_tls": 1,
		 "mail_login": "******",
		 "mail_password": "******",
		 "auto_email_id": "*****@*****.**",
		 "email_sender_name": "Example Notifications",
		 "always_use_account_email_id_as_sender": 0,
		 "always_use_account_name_as_sender_name": 0
		}
	'''
	email_account = _get_email_account({"enable_outgoing": 1, "default_outgoing": 1})
	if email_account:
		email_account.password = email_account.get_password(raise_exception=False)

	if not email_account and frappe.conf.get("mail_server"):
		# from site_config.json
		email_account = frappe.new_doc("Email Account")
		email_account.update({
			"smtp_server": frappe.conf.get("mail_server"),
			"smtp_port": frappe.conf.get("mail_port"),

			# legacy: use_ssl was used in site_config instead of use_tls, but meant the same thing
			"use_tls": cint(frappe.conf.get("use_tls") or 0) or cint(frappe.conf.get("use_ssl") or 0),
			"login_id": frappe.conf.get("mail_login"),
			"email_id": frappe.conf.get("auto_email_id") or frappe.conf.get("mail_login") or '*****@*****.**',
			"password": frappe.conf.get("mail_password"),
			"always_use_account_email_id_as_sender": frappe.conf.get("always_use_account_email_id_as_sender", 0),
			"always_use_account_name_as_sender_name": frappe.conf.get("always_use_account_name_as_sender_name", 0)
		})
		email_account.from_site_config = True
		email_account.name = frappe.conf.get("email_sender_name") or "Frappe"

	if not email_account and not raise_exception_not_set:
		return None

	if frappe.are_emails_muted():
		# create a stub
		email_account = frappe.new_doc("Email Account")
		email_account.update({
			"email_id": "*****@*****.**"
		})

	return email_account
Exemplo n.º 17
0
def flush(from_test=False):
    """flush email queue, every time: called from scheduler
	"""
    from frappe.email.doctype.email_queue.email_queue import send_mail
    # To avoid running jobs inside unit tests
    if frappe.are_emails_muted():
        msgprint(_("Emails are muted"))
        from_test = True

    if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1:
        return

    for row in get_queue():
        try:
            func = send_mail if from_test else send_mail.enqueue
            is_background_task = not from_test
            func(email_queue_name=row.name,
                 is_background_task=is_background_task)
        except Exception:
            frappe.log_error()
Exemplo n.º 18
0
def flush(from_test=False):
	"""flush email queue, every time: called from scheduler"""
	# additional check
	cache = frappe.cache()
	check_email_limit([])

	auto_commit = not from_test
	if frappe.are_emails_muted():
		msgprint(_("Emails are muted"))
		from_test = True

	smtpserver = SMTPServer()

	make_cache_queue()

	for i in xrange(cache.llen('cache_email_queue')):
		email = cache.lpop('cache_email_queue')

		if email:
			send_one(email, smtpserver, auto_commit)
Exemplo n.º 19
0
def flush(from_test=False):
    """flush email queue, every time: called from scheduler"""
    # additional check
    cache = frappe.cache()
    check_email_limit([])

    auto_commit = not from_test
    if frappe.are_emails_muted():
        msgprint(_("Emails are muted"))
        from_test = True

    smtpserver = SMTPServer()

    make_cache_queue()

    for i in xrange(cache.llen('cache_email_queue')):
        email = cache.lpop('cache_email_queue')

        if email:
            send_one(email, smtpserver, auto_commit, from_test=from_test)
Exemplo n.º 20
0
def send(email, append_to=None):
	"""send the message or add it to Outbox Email"""
	if frappe.flags.in_test:
		frappe.flags.sent_mail = email.as_string()
		return

	if frappe.are_emails_muted():
		frappe.msgprint(_("Emails are muted"))
		return

	try:
		smtpserver = SMTPServer(append_to=append_to)
		smtpserver.replace_sender_in_email(email)
		smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []),
			email.as_string())

	except smtplib.SMTPSenderRefused:
		frappe.msgprint(_("Invalid login or password"))
		raise
	except smtplib.SMTPRecipientsRefused:
		frappe.msgprint(_("Invalid recipient address"))
		raise
Exemplo n.º 21
0
def flush(from_test=False):
    """flush email queue, every time: called from scheduler"""
    # additional check

    auto_commit = not from_test
    if frappe.are_emails_muted():
        msgprint(_("Emails are muted"))
        from_test = True

    smtpserver_dict = frappe._dict()

    for email in get_queue():

        if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1:
            break

        if email.name:
            smtpserver = smtpserver_dict.get(email.sender)
            if not smtpserver:
                smtpserver = SMTPServer()
                smtpserver_dict[email.sender] = smtpserver

            send_one(email.name, smtpserver, auto_commit, from_test=from_test)
Exemplo n.º 22
0
def flush(from_test=False):
	"""flush email queue, every time: called from scheduler"""
	# additional check
	check_email_limit([])

	auto_commit = not from_test
	if frappe.are_emails_muted():
		msgprint(_("Emails are muted"))
		from_test = True

	smtpserver_dict = frappe._dict()

	for email in get_queue():

		if cint(frappe.defaults.get_defaults().get("hold_queue"))==1:
			break

		if email.name:
			smtpserver = smtpserver_dict.get(email.sender)
			if not smtpserver:
				smtpserver = SMTPServer()
				smtpserver_dict[email.sender] = smtpserver

			send_one(email.name, smtpserver, auto_commit, from_test=from_test)
Exemplo n.º 23
0
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")
Exemplo n.º 24
0
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))
Exemplo n.º 25
0
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))