From ac842872666e5ff92a9a58183efd2b6ef12c2e58 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Fri, 24 Jun 2022 18:31:43 +0530 Subject: [PATCH 1/4] fix: improve SVG for expenses icon --- frappe/public/icons/timeless/icons.svg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/icons/timeless/icons.svg b/frappe/public/icons/timeless/icons.svg index fbd72d6fb5..af63d0c8ff 100644 --- a/frappe/public/icons/timeless/icons.svg +++ b/frappe/public/icons/timeless/icons.svg @@ -613,8 +613,8 @@ - + From 07d7b34fd9d3b60eb4c03b61069f6718cff84b6d Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Tue, 28 Jun 2022 11:31:17 +0530 Subject: [PATCH 2/4] refactor: get_unsubscribe_message * Add fallback label "Unsubscribe" instead of printing None in the email * Add typing hints, f-stringify & make code DRY-er for better readability --- frappe/__init__.py | 2 +- .../email/doctype/email_queue/email_queue.py | 16 ++++---- frappe/email/email_body.py | 3 +- frappe/email/queue.py | 37 ++++++------------- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 9104cd5109..063a62c84b 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -78,7 +78,7 @@ class _dict(dict): return _dict(self) -def _(msg, lang=None, context=None): +def _(msg, lang=None, context=None) -> str: """Returns translated string in current lang, if exists. Usage: _('Change') diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index c3002607b4..330dab9e7f 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -183,7 +183,7 @@ def send_mail(email_queue_name, is_background_task=False): class SendMailContext: def __init__(self, queue_doc: Document, is_background_task: bool = False): - self.queue_doc = queue_doc + self.queue_doc: EmailQueue = queue_doc self.is_background_task = is_background_task self.email_account_doc = queue_doc.get_email_account() self.smtp_server = self.email_account_doc.get_smtp_server() @@ -287,16 +287,16 @@ class SendMailContext: ).decode() return message - def get_unsubscribe_str(self, recipient_email): + def get_unsubscribe_str(self, recipient_email: str) -> str: unsubscribe_url = "" + if self.queue_doc.add_unsubscribe_link and self.queue_doc.reference_doctype: - doctype, doc_name = self.queue_doc.reference_doctype, self.queue_doc.reference_name unsubscribe_url = get_unsubcribed_url( - doctype, - doc_name, - recipient_email, - self.queue_doc.unsubscribe_method, - self.queue_doc.unsubscribe_param, + reference_doctype=self.queue_doc.reference_doctype, + reference_name=self.queue_doc.reference_name, + email=recipient_email, + unsubscribe_method=self.queue_doc.unsubscribe_method, + unsubscribe_params=self.queue_doc.unsubscribe_param, ) return quopri.encodestring(unsubscribe_url.encode()).decode() diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index 50c66e1ad2..3a952e1487 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -7,6 +7,7 @@ import re from email import policy from email.header import Header from email.mime.multipart import MIMEMultipart +from typing import Optional import frappe from frappe.email.doctype.email_account.email_account import EmailAccount @@ -353,7 +354,7 @@ def get_formatted_html( print_html=None, email_account=None, header=None, - unsubscribe_link=None, + unsubscribe_link: Optional[frappe._dict] = None, sender=None, with_container=False, ): diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 1519c26841..45abe0374a 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -67,37 +67,24 @@ def get_emails_sent_today(email_account=None): return frappe.db.sql(q, q_args)[0][0] -def get_unsubscribe_message(unsubscribe_message, expose_recipients): - if unsubscribe_message: - unsubscribe_html = """{0}""".format( - unsubscribe_message - ) - else: - unsubscribe_link = """{0}""".format( - _("Unsubscribe") - ) - unsubscribe_html = _("{0} to stop receiving emails of this type").format(unsubscribe_link) - - html = """""" + text = f"\n\n{unsubscribe_message}: \n" if expose_recipients == "footer": - text = "\n" - else: - text = "" - text += "\n\n{unsubscribe_message}: \n".format( - unsubscribe_message=unsubscribe_message - ) + text = f"\n{text}" - return frappe._dict({"html": html, "text": text}) + return frappe._dict(html=html, text=text) def get_unsubcribed_url( From 4dff0d25a36942560bf65ace9e58bbb2da73d351 Mon Sep 17 00:00:00 2001 From: Shariq Ansari <30859809+shariquerik@users.noreply.github.com> Date: Tue, 28 Jun 2022 16:17:26 +0530 Subject: [PATCH 3/4] feat: add email retry limit in system settings (#17259) **MAX_RETRY_COUNT** for email was hard coded as 3. Added **Email Retry Limit** field in **Email** section in **System Settings** image >no-docs --- .../doctype/system_settings/system_settings.json | 13 ++++++++++--- frappe/email/doctype/email_queue/email_queue.py | 8 +++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index c954e41202..a444062b5a 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -63,6 +63,7 @@ "otp_issuer_name", "email", "email_footer_address", + "email_retry_limit", "column_break_18", "disable_standard_email_footer", "hide_footer_in_auto_email_reports", @@ -495,8 +496,8 @@ "fieldname": "allow_older_web_view_links", "fieldtype": "Check", "label": "Allow Older Web View Links (Insecure)" - }, - { + }, + { "fieldname": "column_break_64", "fieldtype": "Column Break" }, @@ -518,12 +519,18 @@ "fieldtype": "Duration", "label": "Reset Password Link Expiry Duration", "non_negative": 1 + }, + { + "default": "3", + "fieldname": "email_retry_limit", + "fieldtype": "Int", + "label": "Email Retry Limit" } ], "icon": "fa fa-cog", "issingle": 1, "links": [], - "modified": "2022-05-19 00:00:18.095269", + "modified": "2022-06-21 13:55:04.796152", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index c3002607b4..4fc828eb62 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -30,8 +30,6 @@ from frappe.utils import ( split_emails, ) -MAX_RETRY_COUNT = 3 - class EmailQueue(Document): DOCTYPE = "Email Queue" @@ -210,7 +208,7 @@ class SendMailContext: email_status = (self.sent_to and "Partially Sent") or "Not Sent" self.queue_doc.update_status(status=email_status, commit=True) elif exc_type: - if self.queue_doc.retry < MAX_RETRY_COUNT: + if self.queue_doc.retry < get_email_retry_limit(): update_fields = {"status": "Not Sent", "retry": self.queue_doc.retry + 1} else: update_fields = {"status": (self.sent_to and "Partially Errored") or "Error"} @@ -372,6 +370,10 @@ def on_doctype_update(): ) +def get_email_retry_limit(): + return cint(frappe.db.get_system_setting("email_retry_limit")) or 3 + + class QueueBuilder: """Builds Email Queue from the given data""" From d58f2ed8e7cf1ef33df8196174193c760f2d2daf Mon Sep 17 00:00:00 2001 From: Samuel Danieli <23150094+scdanieli@users.noreply.github.com> Date: Tue, 28 Jun 2022 13:58:27 +0200 Subject: [PATCH 4/4] fix: german translations (#17324) --- frappe/translations/de.csv | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frappe/translations/de.csv b/frappe/translations/de.csv index d00548458c..b22befd321 100644 --- a/frappe/translations/de.csv +++ b/frappe/translations/de.csv @@ -1993,7 +1993,7 @@ QR Code,QR-Code, QR Code for Login Verification,QR Code für Login-Bestätigung, QZ Tray Connection Active!,QZ-Tray-Verbindung aktiv!, QZ Tray Failed: ,QZ-Fach fehlgeschlagen:, -Quarter Day,Quartalstag, +Quarter Day,Viertel-Tag, Query,Abfrage, Query Report,Abfragebericht, Query must be a SELECT,Abfrage muss ein SELECT sein, @@ -4793,3 +4793,17 @@ Reset to default,Auf Standard zurücksetzen, Column Width,Spaltenbreite, Choose Kanban Board,Kanban-Tafel auswählen, Create New Board,Neue Tafel erstellen, +Only If Creator,Nur wenn Ersteller, +Rebuild Tree,Baum neu aufbauen, +Customize Dashboard,Dashboard anpassen, +Reset Dashboard Customizations,Dashboard-Anpassungen zurücksetzen, +Add {0},{0} hinzufügen, +descending,absteigend, +ascending,aufsteigend, +Next Document,Nächstes Dokument, +Previous Document,Vorheriges Dokument, +Mark all as read,Alle als gelesen markieren, +See all Activity,Alle Aktivitäten anzeigen, +Go to Notification Settings List,Gehe zur Listenansicht Benachrichtigungseinstellungen, +Load more,Mehr laden, +Edit Full Form,Vollständiges Formular bearbeiten,