def _get_and_send_report(self, language, emails): from corehq.apps.reports.views import get_scheduled_report_response, render_full_report_notification with localize(language): title = (_(DEFAULT_REPORT_NOTIF_SUBJECT) if self.email_subject == DEFAULT_REPORT_NOTIF_SUBJECT else self.email_subject) attach_excel = getattr(self, 'attach_excel', False) content, excel_files = get_scheduled_report_response( self.owner, self.domain, self._id, attach_excel=attach_excel, send_only_active=True) # Will be False if ALL the ReportConfigs in the ReportNotification # have a start_date in the future. if content is False: return for email in emails: body = render_full_report_notification(None, content, email, self).content send_html_email_async.delay( title, email, body, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=excel_files)
def _get_and_send_report(self, language, emails): from corehq.apps.reports.views import get_scheduled_report_response, render_full_report_notification with localize(language): title = (_(DEFAULT_REPORT_NOTIF_SUBJECT) if self.email_subject == DEFAULT_REPORT_NOTIF_SUBJECT else self.email_subject) attach_excel = getattr(self, 'attach_excel', False) content, excel_files = get_scheduled_report_response( self.owner, self.domain, self._id, attach_excel=attach_excel) slugs = [r.report_slug for r in self.configs] for email in emails: body = render_full_report_notification(None, content, email, self).content send_html_email_async.delay( title, email, body, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=excel_files, ga_track=True, ga_tracking_info={ 'cd4': self.domain, 'cd10': ', '.join(slugs) }, )
def _send_emails(self, title, report_text, emails, excel_files): from corehq.apps.reports.views import render_full_report_notification email_is_too_large = False for email in emails: body = render_full_report_notification(None, report_text, email, self).content try: self._send_email(title, email, body, excel_files) except Exception as er: if isinstance(er, SMTPSenderRefused) and ( er.smtp_code in LARGE_FILE_SIZE_ERROR_CODES): email_is_too_large = True break else: ScheduledReportLogger.log_email_failure( self, email, body, er) else: ScheduledReportLogger.log_email_success(self, email, body) if email_is_too_large: # TODO: Because different domains may have different size thresholds, # one of the middle addresses could have triggered this, causing us to send # both the original email and the retried email to some users. # This is likely best handled by treating each address separately. ScheduledReportLogger.log_email_size_failure( self, email, emails, body) # The body is too large -- attempt to resend the report as attachments. if excel_files: # If the attachments already exist, just send them self._send_only_attachments(title, emails, excel_files) else: # Otherwise we're forced to trigger a process to create them self._export_report(emails, title)
def _get_and_send_report(self, language, emails): from corehq.apps.reports.views import get_scheduled_report_response, render_full_report_notification with localize(language): title = ( _(DEFAULT_REPORT_NOTIF_SUBJECT) if self.email_subject == DEFAULT_REPORT_NOTIF_SUBJECT else self.email_subject ) attach_excel = getattr(self, 'attach_excel', False) content, excel_files = get_scheduled_report_response( self.owner, self.domain, self._id, attach_excel=attach_excel, send_only_active=True ) # Will be False if ALL the ReportConfigs in the ReportNotification # have a start_date in the future. if content is False: return for email in emails: body = render_full_report_notification(None, content, email, self).content send_html_email_async.delay( title, email, body, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=excel_files)
def _get_and_send_report(self, language, emails): from corehq.apps.reports.views import get_scheduled_report_response, render_full_report_notification with localize(language): title = ( _(DEFAULT_REPORT_NOTIF_SUBJECT) if self.email_subject == DEFAULT_REPORT_NOTIF_SUBJECT else self.email_subject ) attach_excel = getattr(self, "attach_excel", False) content, excel_files = get_scheduled_report_response( self.owner, self.domain, self._id, attach_excel=attach_excel ) slugs = [r.report_slug for r in self.configs] for email in emails: body = render_full_report_notification(None, content, email, self).content send_html_email_async.delay( title, email, body, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=excel_files, ga_track=True, ga_tracking_info={"cd4": self.domain, "cd10": ", ".join(slugs)}, )
def _get_and_send_report(self, language, emails): from corehq.apps.reports.views import get_scheduled_report_response, render_full_report_notification with localize(language): title = (_(DEFAULT_REPORT_NOTIF_SUBJECT) if self.email_subject == DEFAULT_REPORT_NOTIF_SUBJECT else self.email_subject) attach_excel = getattr(self, 'attach_excel', False) try: content, excel_files = get_scheduled_report_response( self.owner, self.domain, self._id, attach_excel=attach_excel, send_only_active=True) # Will be False if ALL the ReportConfigs in the ReportNotification # have a start_date in the future. if content is False: return for email in emails: body = render_full_report_notification( None, content, email, self).content send_html_email_async( title, email, body, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=excel_files, smtp_exception_skip_list=LARGE_FILE_SIZE_ERROR_CODES) except Exception as er: notify_exception( None, message= "Encountered error while generating report or sending email", details={ 'subject': title, 'recipients': str(emails), 'error': er, }) if getattr(er, 'smtp_code', None) in LARGE_FILE_SIZE_ERROR_CODES or type( er) == ESError: # If the email doesn't work because it is too large to fit in the HTML body, # send it as an excel attachment, by creating a mock request with the right data. for report_config in self.configs: mock_request = HttpRequest() mock_request.couch_user = self.owner mock_request.user = self.owner.get_django_user() mock_request.domain = self.domain mock_request.couch_user.current_domain = self.domain mock_request.couch_user.language = self.language mock_request.method = 'GET' mock_request.bypass_two_factor = True mock_query_string_parts = [ report_config.query_string, 'filterSet=true' ] if report_config.is_configurable_report: mock_query_string_parts.append( urlencode(report_config.filters, True)) mock_query_string_parts.append( urlencode(report_config.get_date_range(), True)) mock_request.GET = QueryDict( '&'.join(mock_query_string_parts)) date_range = report_config.get_date_range() start_date = datetime.strptime(date_range['startdate'], '%Y-%m-%d') end_date = datetime.strptime(date_range['enddate'], '%Y-%m-%d') datespan = DateSpan(start_date, end_date) request_data = vars(mock_request) request_data[ 'couch_user'] = mock_request.couch_user.userID request_data['datespan'] = datespan full_request = { 'request': request_data, 'domain': request_data['domain'], 'context': {}, 'request_params': json_request(request_data['GET']) } export_all_rows_task(report_config.report, full_request, emails, title)
def send_email_report(self, recipient_emails, domain, report_slug, report_type, request_data, once, cleaned_data): """ Function invokes send_HTML_email to email the html text report. If the report is too large to fit into email then a download link is sent via email to download report :Parameter recipient_list: list of recipient to whom email is to be sent :Parameter domain: domain name :Parameter report_slug: report slug :Parameter report_type: type of the report :Parameter request_data: Dict containing request data :Parameter once boolean argument specifying whether the report is once off report or scheduled report :Parameter cleaned_data: Dict containing cleaned data from the submitted form """ from corehq.apps.reports.views import _render_report_configs, render_full_report_notification user_id = request_data['couch_user'] couch_user = CouchUser.get_by_user_id(user_id) mock_request = HttpRequest() mock_request.method = 'GET' mock_request.GET = request_data['GET'] config = ReportConfig() # see ReportConfig.query_string() object.__setattr__(config, '_id', 'dummy') config.name = _("Emailed report") config.report_type = report_type config.report_slug = report_slug config.owner_id = user_id config.domain = domain config.start_date = request_data['datespan'].startdate.date() if request_data['datespan'].enddate: config.date_range = 'range' config.end_date = request_data['datespan'].enddate.date() else: config.date_range = 'since' GET = dict(six.iterlists(request_data['GET'])) exclude = ['startdate', 'enddate', 'subject', 'send_to_owner', 'notes', 'recipient_emails'] filters = {} for field in GET: if field not in exclude: filters[field] = GET.get(field) config.filters = filters subject = cleaned_data['subject'] or _("Email report from CommCare HQ") try: content = _render_report_configs( mock_request, [config], domain, user_id, couch_user, True, lang=couch_user.language, notes=cleaned_data['notes'], once=once )[0] body = render_full_report_notification(None, content).content for recipient in recipient_emails: send_HTML_email(subject, recipient, body, email_from=settings.DEFAULT_FROM_EMAIL, smtp_exception_skip_list=LARGE_FILE_SIZE_ERROR_CODES) except Exception as er: notify_exception( None, message="Encountered error while generating report or sending email", details={ 'subject': subject, 'recipients': str(recipient_emails), 'error': er, } ) if getattr(er, 'smtp_code', None) in LARGE_FILE_SIZE_ERROR_CODES or type(er) == ESError: # If the email doesn't work because it is too large to fit in the HTML body, # send it as an excel attachment. report_state = { 'request': request_data, 'request_params': json_request(request_data['GET']), 'domain': domain, 'context': {}, } export_all_rows_task(config.report, report_state, recipient_list=recipient_emails) else: self.retry(exc=er)
def send_email_report(self, recipient_emails, domain, report_slug, report_type, request_data, once, cleaned_data): """ Function invokes send_HTML_email to email the html text report. If the report is too large to fit into email then a download link is sent via email to download report :Parameter recipient_list: list of recipient to whom email is to be sent :Parameter domain: domain name :Parameter report_slug: report slug :Parameter report_type: type of the report :Parameter request_data: Dict containing request data :Parameter once boolean argument specifying whether the report is once off report or scheduled report :Parameter cleaned_data: Dict containing cleaned data from the submitted form """ from corehq.apps.reports.views import _render_report_configs, render_full_report_notification user_id = request_data['couch_user'] couch_user = CouchUser.get_by_user_id(user_id) mock_request = HttpRequest() mock_request.method = 'GET' mock_request.GET = request_data['GET'] config = ReportConfig() # see ReportConfig.query_string() object.__setattr__(config, '_id', 'dummy') config.name = _("Emailed report") config.report_type = report_type config.report_slug = report_slug config.owner_id = user_id config.domain = domain config.start_date = request_data['datespan'].startdate.date() if request_data['datespan'].enddate: config.date_range = 'range' config.end_date = request_data['datespan'].enddate.date() else: config.date_range = 'since' GET = dict(six.iterlists(request_data['GET'])) exclude = [ 'startdate', 'enddate', 'subject', 'send_to_owner', 'notes', 'recipient_emails' ] filters = {} for field in GET: if field not in exclude: filters[field] = GET.get(field) config.filters = filters subject = cleaned_data['subject'] or _("Email report from CommCare HQ") content = _render_report_configs(mock_request, [config], domain, user_id, couch_user, True, lang=couch_user.language, notes=cleaned_data['notes'], once=once)[0] body = render_full_report_notification(None, content).content try: for recipient in recipient_emails: send_HTML_email( subject, recipient, body, email_from=settings.DEFAULT_FROM_EMAIL, smtp_exception_skip_list=LARGE_FILE_SIZE_ERROR_CODES) except Exception as er: if getattr(er, 'smtp_code', None) in LARGE_FILE_SIZE_ERROR_CODES: # If the smtp server rejects the email because of its large size. # Then sends the report download link in the email. report_state = { 'request': request_data, 'request_params': json_request(request_data['GET']), 'domain': domain, 'context': {}, } export_all_rows_task(config.report, report_state, recipient_list=recipient_emails) else: self.retry(exc=er)