|
|
@@ -135,7 +135,7 @@ def add(email, sender, subject, formatted, text_content=None, |
|
|
|
e.reference_name = reference_name |
|
|
|
e.communication = communication |
|
|
|
e.send_after = send_after |
|
|
|
e.insert(ignore_permissions=True) |
|
|
|
e.db_insert() |
|
|
|
|
|
|
|
def check_email_limit(recipients): |
|
|
|
# if using settings from site_config.json, check email limit |
|
|
@@ -151,6 +151,9 @@ def check_email_limit(recipients): |
|
|
|
|
|
|
|
monthly_email_limit = frappe.conf.get('limits', {}).get('emails') or 500 |
|
|
|
|
|
|
|
if frappe.flags.in_test: |
|
|
|
monthly_email_limit = 500 |
|
|
|
|
|
|
|
if (this_month + len(recipients)) > monthly_email_limit: |
|
|
|
throw(_("Cannot send this email. You have crossed the sending limit of {0} emails for this month.").format(monthly_email_limit), |
|
|
|
EmailLimitCrossedError) |
|
|
@@ -244,6 +247,7 @@ def return_unsubscribed_page(email, doctype, name): |
|
|
|
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 |
|
|
@@ -251,34 +255,40 @@ def flush(from_test=False): |
|
|
|
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) |
|
|
|
make_cache_queue() |
|
|
|
|
|
|
|
if email: |
|
|
|
email = email[0] |
|
|
|
else: |
|
|
|
break |
|
|
|
for i in xrange(cache.llen('cache_email_queue')): |
|
|
|
email = cache.lpop('cache_email_queue') |
|
|
|
|
|
|
|
send_one(email, smtpserver, auto_commit) |
|
|
|
if email: |
|
|
|
send_one(email, smtpserver, auto_commit) |
|
|
|
|
|
|
|
# NOTE: removing commit here because we pass auto_commit |
|
|
|
# finally: |
|
|
|
# frappe.db.commit() |
|
|
|
def make_cache_queue(): |
|
|
|
'''cache values in queue before sendign''' |
|
|
|
cache = frappe.cache() |
|
|
|
|
|
|
|
emails = frappe.db.sql('''select name from `tabEmail Queue` |
|
|
|
where status='Not Sent' and (send_after is null or send_after < %(now)s) |
|
|
|
order by priority desc, creation asc |
|
|
|
limit 500''', { 'now': now_datetime() }) |
|
|
|
|
|
|
|
# reset value |
|
|
|
cache.delete_value('cache_email_queue') |
|
|
|
for e in emails: |
|
|
|
cache.rpush('cache_email_queue', e[0]) |
|
|
|
|
|
|
|
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': |
|
|
|
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 |
|
|
@@ -337,3 +347,6 @@ def clear_outbox(): |
|
|
|
"""Remove mails older than 31 days in Outbox. Called daily via scheduler.""" |
|
|
|
frappe.db.sql("""delete from `tabEmail Queue` where |
|
|
|
datediff(now(), creation) > 31""") |
|
|
|
|
|
|
|
frappe.db.sql("""update `tabEmail Queue` set status='Expired' |
|
|
|
where datediff(curdate(), creation) > 7 and status='Not Sent'""") |