Merge pull request #24235 from akhilnarang/notification-receiver-language
fix: use receiver's language for some notifications
This commit is contained in:
commit
beac0122b6
4 changed files with 38 additions and 32 deletions
|
|
@ -29,6 +29,7 @@ class NotificationLog(Document):
|
|||
read: DF.Check
|
||||
subject: DF.Text | None
|
||||
type: DF.Literal["Mention", "Energy Point", "Assignment", "Share", "Alert"]
|
||||
|
||||
# end: auto-generated types
|
||||
def after_insert(self):
|
||||
frappe.publish_realtime("notification", after_commit=True, user=self.for_user)
|
||||
|
|
@ -115,18 +116,17 @@ def _get_user_ids(user_emails):
|
|||
return [user for user in user_names if is_notifications_enabled(user)]
|
||||
|
||||
|
||||
def send_notification_email(doc):
|
||||
|
||||
def send_notification_email(doc: NotificationLog):
|
||||
if doc.type == "Energy Point" and doc.email_content is None:
|
||||
return
|
||||
|
||||
from frappe.utils import get_url_to_form, strip_html
|
||||
|
||||
email = frappe.db.get_value("User", doc.for_user, "email")
|
||||
if not email:
|
||||
user = frappe.db.get_value("User", doc.for_user, fieldname=["email", "language"], as_dict=True)
|
||||
if not user:
|
||||
return
|
||||
|
||||
header = get_email_header(doc)
|
||||
header = get_email_header(doc, user.language)
|
||||
email_subject = strip_html(doc.subject)
|
||||
args = {
|
||||
"body_content": doc.subject,
|
||||
|
|
@ -140,7 +140,7 @@ def send_notification_email(doc):
|
|||
args["doc_link"] = get_url_to_form(doc.document_type, doc.document_name)
|
||||
|
||||
frappe.sendmail(
|
||||
recipients=email,
|
||||
recipients=user.email,
|
||||
subject=email_subject,
|
||||
template="new_notification",
|
||||
args=args,
|
||||
|
|
@ -149,14 +149,14 @@ def send_notification_email(doc):
|
|||
)
|
||||
|
||||
|
||||
def get_email_header(doc):
|
||||
def get_email_header(doc, language: str | None = None):
|
||||
docname = doc.document_name
|
||||
header_map = {
|
||||
"Default": _("New Notification"),
|
||||
"Mention": _("New Mention on {0}").format(docname),
|
||||
"Assignment": _("Assignment Update on {0}").format(docname),
|
||||
"Share": _("New Document Shared {0}").format(docname),
|
||||
"Energy Point": _("Energy Point Update on {0}").format(docname),
|
||||
"Default": _("New Notification", lang=language),
|
||||
"Mention": _("New Mention on {0}", lang=language).format(docname),
|
||||
"Assignment": _("Assignment Update on {0}", lang=language).format(docname),
|
||||
"Share": _("New Document Shared {0}", lang=language).format(docname),
|
||||
"Energy Point": _("Energy Point Update on {0}", lang=language).format(docname),
|
||||
}
|
||||
|
||||
return header_map[doc.type or "Default"]
|
||||
|
|
|
|||
|
|
@ -253,8 +253,10 @@ def notify_assignment(
|
|||
if not (assigned_by and allocated_to and doc_type and doc_name):
|
||||
return
|
||||
|
||||
assigned_user = frappe.db.get_value("User", allocated_to, ["language", "enabled"], as_dict=True)
|
||||
|
||||
# return if self assigned or user disabled
|
||||
if assigned_by == allocated_to or not frappe.db.get_value("User", allocated_to, "enabled"):
|
||||
if assigned_by == allocated_to or not assigned_user.enabled:
|
||||
return
|
||||
|
||||
# Search for email address in description -- i.e. assignee
|
||||
|
|
@ -263,14 +265,16 @@ def notify_assignment(
|
|||
description_html = f"<div>{description}</div>" if description else None
|
||||
|
||||
if action == "CLOSE":
|
||||
subject = _("Your assignment on {0} {1} has been removed by {2}").format(
|
||||
frappe.bold(_(doc_type)), get_title_html(title), frappe.bold(user_name)
|
||||
)
|
||||
subject = _(
|
||||
"Your assignment on {0} {1} has been removed by {2}", lang=assigned_user.language
|
||||
).format(frappe.bold(_(doc_type)), get_title_html(title), frappe.bold(user_name))
|
||||
else:
|
||||
user_name = frappe.bold(user_name)
|
||||
document_type = frappe.bold(_(doc_type))
|
||||
document_type = frappe.bold(_(doc_type, lang=assigned_user.language))
|
||||
title = get_title_html(title)
|
||||
subject = _("{0} assigned a new task {1} {2} to you").format(user_name, document_type, title)
|
||||
subject = _("{0} assigned a new task {1} {2} to you", lang=assigned_user.language).format(
|
||||
user_name, document_type, title
|
||||
)
|
||||
|
||||
notification_doc = {
|
||||
"type": "Assignment",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import quopri
|
|||
import traceback
|
||||
from contextlib import suppress
|
||||
from email.parser import Parser
|
||||
from email.policy import SMTPUTF8, default
|
||||
from email.policy import SMTP
|
||||
|
||||
import frappe
|
||||
from frappe import _, safe_encode, task
|
||||
|
|
@ -169,7 +169,9 @@ class EmailQueue(Document):
|
|||
else:
|
||||
if not frappe.flags.in_test or frappe.flags.testing_email:
|
||||
ctx.smtp_server.session.sendmail(
|
||||
from_addr=self.sender, to_addrs=recipient.recipient, msg=message
|
||||
from_addr=self.sender,
|
||||
to_addrs=recipient.recipient,
|
||||
msg=message.decode("utf-8").encode(),
|
||||
)
|
||||
|
||||
ctx.update_recipient_status_to_sent(recipient)
|
||||
|
|
@ -264,7 +266,7 @@ class SendMailContext:
|
|||
@savepoint(catch=Exception)
|
||||
def notify_failed_email(self):
|
||||
# Parse the email body to extract the subject
|
||||
subject = Parser(policy=default).parsestr(self.queue_doc.message)["Subject"]
|
||||
subject = Parser(policy=SMTP).parsestr(self.queue_doc.message)["Subject"]
|
||||
|
||||
# Construct the notification
|
||||
notification = frappe.new_doc("Notification Log")
|
||||
|
|
@ -281,7 +283,7 @@ class SendMailContext:
|
|||
recipient.update_db(status="Sent", commit=True)
|
||||
|
||||
def get_message_object(self, message):
|
||||
return Parser(policy=SMTPUTF8).parsestr(message)
|
||||
return Parser(policy=SMTP).parsestr(message)
|
||||
|
||||
def message_placeholder(self, placeholder_key):
|
||||
# sourcery skip: avoid-builtin-shadow
|
||||
|
|
@ -293,9 +295,10 @@ class SendMailContext:
|
|||
}
|
||||
return map.get(placeholder_key)
|
||||
|
||||
def build_message(self, recipient_email):
|
||||
def build_message(self, recipient_email) -> bytes:
|
||||
"""Build message specific to the recipient."""
|
||||
message = self.queue_doc.message
|
||||
|
||||
if not message:
|
||||
return ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
|
||||
import email.utils
|
||||
import os
|
||||
import re
|
||||
|
|
@ -136,8 +135,8 @@ class EMail:
|
|||
self.subject = subject
|
||||
self.expose_recipients = expose_recipients
|
||||
|
||||
self.msg_root = MIMEMultipart("mixed", policy=policy.SMTPUTF8)
|
||||
self.msg_alternative = MIMEMultipart("alternative", policy=policy.SMTPUTF8)
|
||||
self.msg_root = MIMEMultipart("mixed", policy=policy.SMTP)
|
||||
self.msg_alternative = MIMEMultipart("alternative", policy=policy.SMTP)
|
||||
self.msg_root.attach(self.msg_alternative)
|
||||
self.cc = cc or []
|
||||
self.bcc = bcc or []
|
||||
|
|
@ -186,7 +185,7 @@ class EMail:
|
|||
"""
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
part = MIMEText(message, "plain", "utf-8", policy=policy.SMTPUTF8)
|
||||
part = MIMEText(message, "plain", "utf-8", policy=policy.SMTP)
|
||||
self.msg_alternative.attach(part)
|
||||
|
||||
def set_part_html(self, message, inline_images):
|
||||
|
|
@ -199,9 +198,9 @@ class EMail:
|
|||
message, _inline_images = replace_filename_with_cid(message)
|
||||
|
||||
# prepare parts
|
||||
msg_related = MIMEMultipart("related", policy=policy.SMTPUTF8)
|
||||
msg_related = MIMEMultipart("related", policy=policy.SMTP)
|
||||
|
||||
html_part = MIMEText(message, "html", "utf-8", policy=policy.SMTPUTF8)
|
||||
html_part = MIMEText(message, "html", "utf-8", policy=policy.SMTP)
|
||||
msg_related.attach(html_part)
|
||||
|
||||
for image in _inline_images:
|
||||
|
|
@ -215,7 +214,7 @@ class EMail:
|
|||
|
||||
self.msg_alternative.attach(msg_related)
|
||||
else:
|
||||
self.msg_alternative.attach(MIMEText(message, "html", "utf-8", policy=policy.SMTPUTF8))
|
||||
self.msg_alternative.attach(MIMEText(message, "html", "utf-8", policy=policy.SMTP))
|
||||
|
||||
def set_html_as_text(self, html):
|
||||
"""Set plain text from HTML"""
|
||||
|
|
@ -228,7 +227,7 @@ class EMail:
|
|||
from email.mime.text import MIMEText
|
||||
|
||||
maintype, subtype = mime_type.split("/")
|
||||
part = MIMEText(message, _subtype=subtype, policy=policy.SMTPUTF8)
|
||||
part = MIMEText(message, _subtype=subtype, policy=policy.SMTP)
|
||||
|
||||
if as_attachment:
|
||||
part.add_header("Content-Disposition", "attachment", filename=filename)
|
||||
|
|
@ -342,7 +341,7 @@ class EMail:
|
|||
"""validate, build message and convert to string"""
|
||||
self.validate()
|
||||
self.make()
|
||||
return self.msg_root.as_string(policy=policy.SMTPUTF8)
|
||||
return self.msg_root.as_string(policy=policy.SMTP)
|
||||
|
||||
|
||||
def get_formatted_html(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue