Merge pull request #2724 from RobertSchouten/email-fixes

assorted email fixes
This commit is contained in:
Makarand Bauskar 2017-03-07 11:03:31 +05:30 committed by GitHub
commit 71d281b6b8
6 changed files with 40 additions and 16 deletions

View file

@ -372,7 +372,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
attachments=None, content=None, doctype=None, name=None, reply_to=None,
cc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None,
send_priority=1, communication=None, retry=1, now=None, read_receipt=None):
send_priority=1, communication=None, retry=1, now=None, read_receipt=None, is_notification=False):
"""Send email using user's default **Email Account** or global default **Email Account**.
@ -411,7 +411,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
attachments=attachments, reply_to=reply_to, cc=cc, message_id=message_id, in_reply_to=in_reply_to,
send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority,
communication=communication, now=now, read_receipt=read_receipt)
communication=communication, now=now, read_receipt=read_receipt, is_notification=is_notification)
whitelisted = []
guest_methods = []

View file

@ -196,6 +196,8 @@ class Communication(Document):
'''Look into the status of Email Queue linked to this Communication and set the Delivery Status of this Communication'''
delivery_status = None
status_counts = Counter(frappe.db.sql_list('''select status from `tabEmail Queue` where communication=%s''', self.name))
if self.sent_or_received == "Received":
return
if status_counts.get('Not Sent') or status_counts.get('Sending'):
delivery_status = 'Sending'

View file

@ -61,7 +61,8 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
"reference_doctype": doctype,
"reference_name": name,
"message_id":get_message_id().strip(" <>"),
"read_receipt":read_receipt
"read_receipt":read_receipt,
"has_attachment": 1 if attachments else 0
})
comm.insert(ignore_permissions=True)
@ -157,7 +158,8 @@ def _notify(doc, print_html=None, print_format=None, attachments=None,
unsubscribe_message=unsubscribe_message,
delayed=True,
communication=doc.name,
read_receipt = doc.read_receipt
read_receipt=doc.read_receipt,
is_notification=True if doc.sent_or_received =="Received" else False
)
def update_parent_status(doc):
@ -418,8 +420,6 @@ def sendmail(communication_name, print_html=None, print_format=None, attachments
for i in xrange(3):
try:
communication = frappe.get_doc("Communication", communication_name)
if communication.sent_or_received == "Received":
communication.message_id = None
communication._notify(print_html=print_html, print_format=print_format, attachments=attachments,
recipients=recipients, cc=cc)

View file

@ -183,12 +183,14 @@ class EMail:
sender_name, sender_email = email.utils.parseaddr(self.sender)
self.sender = email.utils.formataddr((sender_name or self.email_account.name, self.email_account.email_id))
def set_message_id(self, message_id):
def set_message_id(self, message_id, is_notification=False):
if message_id:
self.msg_root["Message-Id"] = '<' + message_id + '>'
else:
self.msg_root["Message-Id"] = get_message_id()
self.msg_root["isnotification"] = '<notification>'
if is_notification:
self.msg_root["isnotification"] = '<notification>'
def set_in_reply_to(self, in_reply_to):
"""Used to send the Message-Id of a received email back as In-Reply-To"""

View file

@ -20,7 +20,7 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
attachments=None, reply_to=None, cc=[], message_id=None, in_reply_to=None, send_after=None,
expose_recipients=None, send_priority=1, communication=None, now=False, read_receipt=None,
queue_separately=False, add_unsubscribe_link=1):
queue_separately=False, is_notification=False, add_unsubscribe_link=1):
"""Add email to sending queue (Email Queue)
:param recipients: List of recipients.
@ -39,6 +39,7 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
:param communication: Communication link to be set in Email Queue record
:param now: Send immediately (don't send in the background)
:param queue_separately: Queue each email separately
:param is_notification: Marks email as notification so will not trigger notifications from system
:param add_unsubscribe_link: Send unsubscribe link in the footer of the Email, default 1.
"""
if not unsubscribe_method:
@ -109,6 +110,7 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
expose_recipients=expose_recipients,
read_receipt=read_receipt,
queue_separately=queue_separately,
is_notification = is_notification,
now=now)
@ -151,7 +153,7 @@ def get_email_queue(recipients, sender, subject, **kwargs):
email_account=kwargs.get('email_account'),
expose_recipients=kwargs.get('expose_recipients'))
mail.set_message_id(kwargs.get('message_id'))
mail.set_message_id(kwargs.get('message_id'),kwargs.get('is_notification'))
if kwargs.get('read_receipt'):
mail.msg_root["Disposition-Notification-To"] = sender
if kwargs.get('in_reply_to'):

View file

@ -265,11 +265,16 @@ class Email:
self.message_id = (self.mail.get('Message-ID') or "").strip(" <>")
if self.mail["Date"]:
utc = email.utils.mktime_tz(email.utils.parsedate_tz(self.mail["Date"]))
utc_dt = datetime.datetime.utcfromtimestamp(utc)
self.date = convert_utc_to_user_timezone(utc_dt).strftime('%Y-%m-%d %H:%M:%S')
try:
utc = email.utils.mktime_tz(email.utils.parsedate_tz(self.mail["Date"]))
utc_dt = datetime.datetime.utcfromtimestamp(utc)
self.date = convert_utc_to_user_timezone(utc_dt).strftime('%Y-%m-%d %H:%M:%S')
except:
self.date = now()
else:
self.date = now()
if self.date > now():
self.date = now()
def parse(self):
"""Walk and process multi-part email."""
@ -294,21 +299,34 @@ class Email:
# use X-Original-Sender if available, as gmail sometimes modifies the 'From'
_from_email = self.mail.get("X-Original-From") or self.mail["From"]
_from_email, encoding = decode_header(_from_email)[0]
_reply_to, _reply_to_encoding = decode_header(self.mail.get("Reply-To"))[0]
if encoding:
_from_email = _from_email.decode(encoding)
else:
_from_email = _from_email.decode('utf-8')
if _reply_to_encoding:
_reply_to = _from_email.decode(encoding)
else:
_reply_to = _from_email.decode('utf-8')
self.from_email = extract_email_id(_from_email)
self.from_real_name = email.utils.parseaddr(_from_email)[0]
if _reply_to and not frappe.db.get_value('Email Account', {"email_id":_reply_to}, 'email_id'):
self.from_email = extract_email_id(_reply_to)
else:
self.from_email = extract_email_id(_from_email)
if self.from_email:
self.from_email = self.from_email.lower()
self.from_real_name = email.utils.parseaddr(_from_email)[0] if "@" in _from_email else _from_email
def set_content_and_type(self):
self.content, self.content_type = '[Blank Email]', 'text/plain'
if self.html_content:
self.content, self.content_type = self.html_content, 'text/html'
else:
self.content, self.content_type = EmailReplyParser.parse_reply(self.text_content), 'text/plain'
self.content, self.content_type = EmailReplyParser.read(self.text_content).text.replace("\n","\n\n"), 'text/plain'
def process_part(self, part):
"""Parse email `part` and set it to `text_content`, `html_content` or `attachments`."""
@ -323,7 +341,7 @@ class Email:
# sent by outlook when another email is sent as an attachment to this email
self.show_attached_email_headers_in_content(part)
elif part.get_filename():
elif part.get_filename() or 'image' in content_type:
self.get_attachment(part)
def show_attached_email_headers_in_content(self, part):