Merge branch 'develop'
This commit is contained in:
commit
a955023bd7
8 changed files with 58 additions and 46 deletions
|
|
@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json
|
|||
from .exceptions import *
|
||||
from .utils.jinja import get_jenv, get_template, render_template
|
||||
|
||||
__version__ = "7.0.14"
|
||||
__version__ = "7.0.15"
|
||||
|
||||
local = Local()
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class TestEmailAccount(unittest.TestCase):
|
|||
def setUp(self):
|
||||
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
|
||||
email_account.db_set("enable_incoming", 1)
|
||||
frappe.db.sql('delete from `tabEmail Queue`')
|
||||
|
||||
def tearDown(self):
|
||||
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Newsletter(Document):
|
|||
self.validate_send()
|
||||
|
||||
# using default queue with a longer timeout as this isn't a scheduled task
|
||||
enqueue(send_newsletter, queue='default', timeout=1500, event='send_newsletter', newsletter=self.name)
|
||||
enqueue(send_newsletter, queue='default', timeout=3000, event='send_newsletter', newsletter=self.name)
|
||||
|
||||
else:
|
||||
self.queue_all()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
for i in xrange(cache.llen('cache_email_queue')):
|
||||
email = cache.lpop('cache_email_queue')
|
||||
|
||||
if email:
|
||||
email = email[0]
|
||||
else:
|
||||
break
|
||||
|
||||
send_one(email, smtpserver, auto_commit)
|
||||
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'""")
|
||||
|
|
|
|||
|
|
@ -686,17 +686,8 @@ fieldset {
|
|||
padding-bottom: 30px;
|
||||
}
|
||||
.blog-comments {
|
||||
background-color: #fafbfc;
|
||||
position: relative;
|
||||
}
|
||||
.blog-comments:before {
|
||||
content: "";
|
||||
background-color: #fafbfc;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100vw;
|
||||
left: calc((100vw - 100%)/ -2);
|
||||
z-index: -1;
|
||||
border-top: 1px solid #d1d8dd;
|
||||
}
|
||||
.blog-comment-row {
|
||||
margin: 0px -15px;
|
||||
|
|
|
|||
|
|
@ -396,18 +396,8 @@ fieldset {
|
|||
.help-article-comments {
|
||||
}
|
||||
.blog-comments {
|
||||
background-color: @light-bg;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.blog-comments:before {
|
||||
content:"";
|
||||
background-color: @light-bg;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100vw;
|
||||
left: ~"calc((100vw - 100%)/ -2)";
|
||||
z-index: -1;
|
||||
border-top: 1px solid @border-color;
|
||||
}
|
||||
|
||||
.blog-comment-row {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,18 @@ class RedisWrapper(redis.Redis):
|
|||
if key in frappe.local.cache:
|
||||
del frappe.local.cache[key]
|
||||
|
||||
def lpush(self, key, value):
|
||||
super(redis.Redis, self).lpush(self.make_key(key), value)
|
||||
|
||||
def rpush(self, key, value):
|
||||
super(redis.Redis, self).rpush(self.make_key(key), value)
|
||||
|
||||
def lpop(self, key):
|
||||
return super(redis.Redis, self).lpop(self.make_key(key))
|
||||
|
||||
def llen(self, key):
|
||||
return super(redis.Redis, self).llen(self.make_key(key))
|
||||
|
||||
def hset(self, name, key, value):
|
||||
if not name in frappe.local.cache:
|
||||
frappe.local.cache[name] = {}
|
||||
|
|
@ -174,3 +186,4 @@ class RedisWrapper(redis.Redis):
|
|||
except redis.exceptions.ConnectionError:
|
||||
return []
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,19 +25,23 @@ def get_secret():
|
|||
|
||||
def verify_request():
|
||||
"""Verify if the incoming signed request if it is correct."""
|
||||
query_string = frappe.request.query_string if hasattr(frappe.request, "query_string") \
|
||||
else frappe.local.flags.signed_query_string
|
||||
query_string = frappe.local.flags.signed_query_string or \
|
||||
getattr(frappe.request, 'query_string', None) \
|
||||
|
||||
params, signature = query_string.split("&_signature=")
|
||||
valid = False
|
||||
|
||||
given_signature = hmac.new(params.encode("utf-8"))
|
||||
if '&_signature=' in query_string:
|
||||
params, signature = query_string.split("&_signature=")
|
||||
|
||||
given_signature.update(get_secret())
|
||||
valid = signature == given_signature.hexdigest()
|
||||
given_signature = hmac.new(params.encode("utf-8"))
|
||||
|
||||
given_signature.update(get_secret())
|
||||
valid = signature == given_signature.hexdigest()
|
||||
|
||||
if not valid:
|
||||
frappe.respond_as_web_page(_("Invalid Link"),
|
||||
_("This link is invalid or expired. Please make sure you have pasted correctly."))
|
||||
|
||||
return valid
|
||||
|
||||
def get_url(cmd, params, nonce=None, secret=None):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue