Skip to content

Commit

Permalink
feat: BW-3310 add dateformat to the email subject
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Liu committed Dec 12, 2024
1 parent 423a0fe commit 60378db
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
2 changes: 2 additions & 0 deletions superset/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,8 @@ class D3TimeFormat(TypedDict, total=False):
# If on, you'll want to add "https://avatars.slack-edge.com" to the list of allowed
# domains in your TALISMAN_CONFIG
"SLACK_ENABLE_AVATARS": False,
# Allow users to optionally specify date formats in email subjects, which will be parsed if enabled.
"DATE_FORMAT_IN_EMAIL_SUBJECT": False,
}

# ------------------------------
Expand Down
27 changes: 23 additions & 4 deletions superset/reports/notifications/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
import logging
import textwrap
from dataclasses import dataclass
from datetime import datetime
from email.utils import make_msgid, parseaddr
from typing import Any, Optional

import nh3
from flask_babel import gettext as __
from pytz import timezone

from superset import app
from superset import app, is_feature_enabled
from superset.exceptions import SupersetErrorsException
from superset.reports.models import ReportRecipientType
from superset.reports.notifications.base import BaseNotification
Expand Down Expand Up @@ -79,6 +81,16 @@ class EmailNotification(BaseNotification): # pylint: disable=too-few-public-met
"""

type = ReportRecipientType.EMAIL
now = datetime.now(timezone("UTC"))

@property
def _name(self) -> str:
"""Include date format in the name if feature flag is enabled"""
return (
self._parse_name(self._content.name)
if is_feature_enabled("DATE_FORMAT_IN_EMAIL_SUBJECT")
else self._content.name
)

@staticmethod
def _get_smtp_domain() -> str:
Expand Down Expand Up @@ -173,11 +185,11 @@ def _get_content(self) -> EmailContent:
)
csv_data = None
if self._content.csv:
csv_data = {__("%(name)s.csv", name=self._content.name): self._content.csv}
csv_data = {__("%(name)s.csv", name=self._name): self._content.csv}

pdf_data = None
if self._content.pdf:
pdf_data = {__("%(name)s.pdf", name=self._content.name): self._content.pdf}
pdf_data = {__("%(name)s.pdf", name=self._name): self._content.pdf}

Check warning on line 192 in superset/reports/notifications/email.py

View check run for this annotation

Codecov / codecov/patch

superset/reports/notifications/email.py#L192

Added line #L192 was not covered by tests

return EmailContent(
body=body,
Expand All @@ -191,9 +203,16 @@ def _get_subject(self) -> str:
return __(
"%(prefix)s %(title)s",
prefix=app.config["EMAIL_REPORTS_SUBJECT_PREFIX"],
title=self._content.name,
title=self._name,
)

def _parse_name(self, name: str) -> str:
"""If user add a date format to the subject, parse it to the real date
This feature is hidden behind a feature flag `DATE_FORMAT_IN_EMAIL_SUBJECT`
by default it is disabled
"""
return self.now.strftime(name)

def _get_call_to_action(self) -> str:
return __(app.config["EMAIL_REPORTS_CTA"])

Expand Down
42 changes: 42 additions & 0 deletions tests/unit_tests/reports/notifications/email_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from datetime import datetime

import pandas as pd
from pytz import timezone

from tests.unit_tests.conftest import with_feature_flags


def test_render_description_with_html() -> None:
Expand Down Expand Up @@ -56,3 +61,40 @@ def test_render_description_with_html() -> None:
in email_body
)
assert '<td>&lt;a href="http://www.example.com"&gt;333&lt;/a&gt;</td>' in email_body


@with_feature_flags(DATE_FORMAT_IN_EMAIL_SUBJECT=True)
def test_email_subject_with_datetime() -> None:
# `superset.models.helpers`, a dependency of following imports,
# requires app context
from superset.reports.models import ReportRecipients, ReportRecipientType
from superset.reports.notifications.base import NotificationContent
from superset.reports.notifications.email import EmailNotification

now = datetime.now(timezone("UTC"))

datetime_pattern = "%Y-%m-%d"

content = NotificationContent(
name=f"test alert {datetime_pattern}",
embedded_data=pd.DataFrame(
{
"A": [1, 2, 3],
}
),
description='<p>This is <a href="#">a test</a> alert</p><br />',
header_data={
"notification_format": "PNG",
"notification_type": "Alert",
"owners": [1],
"notification_source": None,
"chart_id": None,
"dashboard_id": None,
"slack_channels": None,
},
)
subject = EmailNotification(
recipient=ReportRecipients(type=ReportRecipientType.EMAIL), content=content
)._get_subject()
assert datetime_pattern not in subject
assert now.strftime(datetime_pattern) in subject

0 comments on commit 60378db

Please sign in to comment.