Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extra configuration to the email reports #9342

Merged
merged 1 commit into from May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions superset/config.py
Expand Up @@ -751,6 +751,11 @@ class CeleryConfig: # pylint: disable=too-few-public-methods

# The base URL to query for accessing the user interface
WEBDRIVER_BASEURL = "http://0.0.0.0:8080/"
# The base URL for the email report hyperlinks.
WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL
# Time in seconds, selenium will wait for the page to load
# and render for the email report.
EMAIL_PAGE_RENDER_WAIT = 30

# Send user to a link where they can report bugs
BUG_REPORT_URL = None
Expand Down
41 changes: 26 additions & 15 deletions superset/tasks/schedules.py
Expand Up @@ -58,9 +58,9 @@
logger = logging.getLogger("tasks.email_reports")
logger.setLevel(logging.INFO)

# Time in seconds, we will wait for the page to load and render
PAGE_RENDER_WAIT = 30

EMAIL_PAGE_RENDER_WAIT = config["EMAIL_PAGE_RENDER_WAIT"]
WEBDRIVER_BASEURL = config["WEBDRIVER_BASEURL"]
WEBDRIVER_BASEURL_USER_FRIENDLY = config["WEBDRIVER_BASEURL_USER_FRIENDLY"]

EmailContent = namedtuple("EmailContent", ["body", "data", "images"])

Expand Down Expand Up @@ -152,11 +152,12 @@ def _get_auth_cookies() -> List[TypeConversionDict]:
return cookies


def _get_url_path(view: str, **kwargs: Any) -> str:
def _get_url_path(view: str, user_friendly: bool = False, **kwargs: Any) -> str:
with app.test_request_context():
return urllib.parse.urljoin(
str(config["WEBDRIVER_BASEURL"]), url_for(view, **kwargs)
base_url = (
WEBDRIVER_BASEURL_USER_FRIENDLY if user_friendly else WEBDRIVER_BASEURL
)
return urllib.parse.urljoin(str(base_url), url_for(view, **kwargs))


def create_webdriver() -> Union[
Expand Down Expand Up @@ -225,19 +226,22 @@ def deliver_dashboard(schedule: DashboardEmailSchedule) -> None:
dashboard = schedule.dashboard

dashboard_url = _get_url_path("Superset.dashboard", dashboard_id=dashboard.id)
dashboard_url_user_friendly = _get_url_path(
"Superset.dashboard", user_friendly=True, dashboard_id=dashboard.id
)

# Create a driver, fetch the page, wait for the page to render
driver = create_webdriver()
window = config["WEBDRIVER_WINDOW"]["dashboard"]
driver.set_window_size(*window)
driver.get(dashboard_url)
time.sleep(PAGE_RENDER_WAIT)
time.sleep(EMAIL_PAGE_RENDER_WAIT)

# Set up a function to retry once for the element.
# This is buggy in certain selenium versions with firefox driver
get_element = getattr(driver, "find_element_by_class_name")
element = retry_call(
get_element, fargs=["grid-container"], tries=2, delay=PAGE_RENDER_WAIT
get_element, fargs=["grid-container"], tries=2, delay=EMAIL_PAGE_RENDER_WAIT
)

try:
Expand All @@ -251,7 +255,7 @@ def deliver_dashboard(schedule: DashboardEmailSchedule) -> None:

# Generate the email body and attachments
email = _generate_mail_content(
schedule, screenshot, dashboard.dashboard_title, dashboard_url
schedule, screenshot, dashboard.dashboard_title, dashboard_url_user_friendly
)

subject = __(
Expand All @@ -271,7 +275,9 @@ def _get_slice_data(schedule: SliceEmailSchedule) -> EmailContent:
)

# URL to include in the email
url = _get_url_path("Superset.slice", slice_id=slc.id)
slice_url_user_friendly = _get_url_path(
"Superset.slice", slice_id=slc.id, user_friendly=True
)

cookies = {}
for cookie in _get_auth_cookies():
Expand All @@ -298,15 +304,15 @@ def _get_slice_data(schedule: SliceEmailSchedule) -> EmailContent:
columns=columns,
rows=rows,
name=slc.slice_name,
link=url,
link=slice_url_user_friendly,
)

elif schedule.delivery_type == EmailDeliveryType.attachment:
data = {__("%(name)s.csv", name=slc.slice_name): content}
body = __(
'<b><a href="%(url)s">Explore in Superset</a></b><p></p>',
name=slc.slice_name,
url=url,
url=slice_url_user_friendly,
)

return EmailContent(body, data, None)
Expand All @@ -321,17 +327,20 @@ def _get_slice_visualization(schedule: SliceEmailSchedule) -> EmailContent:
driver.set_window_size(*window)

slice_url = _get_url_path("Superset.slice", slice_id=slc.id)
slice_url_user_friendly = _get_url_path(
"Superset.slice", slice_id=slc.id, user_friendly=True
)

driver.get(slice_url)
time.sleep(PAGE_RENDER_WAIT)
time.sleep(EMAIL_PAGE_RENDER_WAIT)

# Set up a function to retry once for the element.
# This is buggy in certain selenium versions with firefox driver
element = retry_call(
driver.find_element_by_class_name,
fargs=["chart-container"],
tries=2,
delay=PAGE_RENDER_WAIT,
delay=EMAIL_PAGE_RENDER_WAIT,
)

try:
Expand All @@ -344,7 +353,9 @@ def _get_slice_visualization(schedule: SliceEmailSchedule) -> EmailContent:
destroy_webdriver(driver)

# Generate the email body and attachments
return _generate_mail_content(schedule, screenshot, slc.slice_name, slice_url)
return _generate_mail_content(
schedule, screenshot, slc.slice_name, slice_url_user_friendly
)


def deliver_slice(schedule: Union[DashboardEmailSchedule, SliceEmailSchedule]) -> None:
Expand Down