mirror of
https://github.com/apache/superset.git
synced 2026-04-24 02:25:13 +00:00
[SIP-3] Scheduled email reports for Slices / Dashboards (#5294)
* [scheduled reports] Add support for scheduled reports * Scheduled email reports for slice and dashboard visualization (attachment or inline) * Scheduled email reports for slice data (CSV attachment on inline table) * Each schedule has a list of recipients (all of them can receive a single mail, or separate mails) * All outgoing mails can have a mandatory bcc - for audit purposes. * Each dashboard/slice can have multiple schedules. In addition, this PR also makes a few minor improvements to the celery infrastructure. * Create a common celery app * Added more celery annotations for the tasks * Introduced celery beat * Update docs about concurrency / pools * [scheduled reports] - Debug mode for scheduled emails * [scheduled reports] - Ability to send test mails * [scheduled reports] - Test email functionality - minor improvements * [scheduled reports] - Rebase with master. Minor fixes * [scheduled reports] - Add warning messages * [scheduled reports] - flake8 * [scheduled reports] - fix rebase * [scheduled reports] - fix rebase * [scheduled reports] - fix flake8 * [scheduled reports] Rebase in prep for merge * Fixed alembic tree after rebase * Updated requirements to latest version of packages (and tested) * Removed py2 stuff * [scheduled reports] - fix flake8 * [scheduled reports] - address review comments * [scheduled reports] - rebase with master
This commit is contained in:
committed by
Maxime Beauchemin
parent
f366bbe735
commit
808622414c
@@ -4,6 +4,7 @@ from builtins import object
|
||||
from datetime import date, datetime, time, timedelta
|
||||
import decimal
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.image import MIMEImage
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import formatdate
|
||||
@@ -582,21 +583,23 @@ def notify_user_about_perm_udate(
|
||||
dryrun=not config.get('EMAIL_NOTIFICATIONS'))
|
||||
|
||||
|
||||
def send_email_smtp(to, subject, html_content, config, files=None,
|
||||
dryrun=False, cc=None, bcc=None, mime_subtype='mixed'):
|
||||
def send_email_smtp(to, subject, html_content, config,
|
||||
files=None, data=None, images=None, dryrun=False,
|
||||
cc=None, bcc=None, mime_subtype='mixed'):
|
||||
"""
|
||||
Send an email with html content, eg:
|
||||
send_email_smtp(
|
||||
'test@example.com', 'foo', '<b>Foo</b> bar',['/dev/null'], dryrun=True)
|
||||
"""
|
||||
smtp_mail_from = config.get('SMTP_MAIL_FROM')
|
||||
|
||||
to = get_email_address_list(to)
|
||||
|
||||
msg = MIMEMultipart(mime_subtype)
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = smtp_mail_from
|
||||
msg['To'] = ', '.join(to)
|
||||
msg.preamble = 'This is a multi-part message in MIME format.'
|
||||
|
||||
recipients = to
|
||||
if cc:
|
||||
cc = get_email_address_list(cc)
|
||||
@@ -612,6 +615,7 @@ def send_email_smtp(to, subject, html_content, config, files=None,
|
||||
mime_text = MIMEText(html_content, 'html')
|
||||
msg.attach(mime_text)
|
||||
|
||||
# Attach files by reading them from disk
|
||||
for fname in files or []:
|
||||
basename = os.path.basename(fname)
|
||||
with open(fname, 'rb') as f:
|
||||
@@ -621,6 +625,23 @@ def send_email_smtp(to, subject, html_content, config, files=None,
|
||||
Content_Disposition="attachment; filename='%s'" % basename,
|
||||
Name=basename))
|
||||
|
||||
# Attach any files passed directly
|
||||
for name, body in (data or {}).items():
|
||||
msg.attach(
|
||||
MIMEApplication(
|
||||
body,
|
||||
Content_Disposition="attachment; filename='%s'" % name,
|
||||
Name=name,
|
||||
))
|
||||
|
||||
# Attach any inline images, which may be required for display in
|
||||
# HTML content (inline)
|
||||
for msgid, body in (images or {}).items():
|
||||
image = MIMEImage(body)
|
||||
image.add_header('Content-ID', '<%s>' % msgid)
|
||||
image.add_header('Content-Disposition', 'inline')
|
||||
msg.attach(image)
|
||||
|
||||
send_MIME_email(smtp_mail_from, recipients, msg, config, dryrun=dryrun)
|
||||
|
||||
|
||||
@@ -639,7 +660,7 @@ def send_MIME_email(e_from, e_to, mime_msg, config, dryrun=False):
|
||||
s.starttls()
|
||||
if SMTP_USER and SMTP_PASSWORD:
|
||||
s.login(SMTP_USER, SMTP_PASSWORD)
|
||||
logging.info('Sent an alert email to ' + str(e_to))
|
||||
logging.info('Sent an email to ' + str(e_to))
|
||||
s.sendmail(e_from, e_to, mime_msg.as_string())
|
||||
s.quit()
|
||||
else:
|
||||
@@ -651,11 +672,13 @@ def get_email_address_list(address_string):
|
||||
if isinstance(address_string, basestring):
|
||||
if ',' in address_string:
|
||||
address_string = address_string.split(',')
|
||||
elif '\n' in address_string:
|
||||
address_string = address_string.split('\n')
|
||||
elif ';' in address_string:
|
||||
address_string = address_string.split(';')
|
||||
else:
|
||||
address_string = [address_string]
|
||||
return address_string
|
||||
return [x.strip() for x in address_string if x.strip()]
|
||||
|
||||
|
||||
def choicify(values):
|
||||
|
||||
Reference in New Issue
Block a user