def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" available_access_levels = project_helpers.BuildProjectAccessOptions( mr.project) offer_access_level = len(available_access_levels) > 1 access_view = project_views.ProjectAccessView(mr.project.access) return { 'admin_tab_mode': self.ADMIN_TAB_META, 'initial_summary': mr.project.summary, 'initial_project_home': mr.project.home_page, 'initial_docs_url': mr.project.docs_url, 'initial_source_url': mr.project.source_url, 'initial_logo_gcs_id': mr.project.logo_gcs_id, 'initial_logo_file_name': mr.project.logo_file_name, 'logo_view': tracker_views.LogoView(mr.project), 'initial_description': mr.project.description, 'issue_notify': mr.project.issue_notify_address, 'process_inbound_email': ezt.boolean( mr.project.process_inbound_email), 'email_from_addr': emailfmt.FormatFromAddr(mr.project), 'only_owners_remove_restrictions': ezt.boolean( mr.project.only_owners_remove_restrictions), 'only_owners_see_contributors': ezt.boolean( mr.project.only_owners_see_contributors), 'offer_access_level': ezt.boolean(offer_access_level), 'initial_access': access_view, 'available_access_levels': available_access_levels, }
def testServiceAccountCommenter(self): johndoe_bot = '*****@*****.**' commenter_view = framework_views.StuffUserView(111L, johndoe_bot, True) self.assertEqual( ('johndoe via monorail <*****@*****.**>'), emailfmt.FormatFromAddr(self.project, commenter_view=commenter_view, reveal_addr=False))
def testObscuredCommenter(self): commenter_view = framework_views.StuffUserView(111, '*****@*****.**', True) self.assertEqual( u'u\u2026 via monorail <*****@*****.**>', emailfmt.FormatFromAddr(self.project, commenter_view=commenter_view, reveal_addr=False))
def _FormatBulkIssuesEmail( self, dest_email, issues, users_by_id, commenter_view, hostport, comment_text, amendments, config, project, is_member): """Format an email to one user listing many issues.""" from_addr = emailfmt.FormatFromAddr( project, commenter_view=commenter_view, reveal_addr=is_member, can_reply_to=False) subject, body = self._FormatBulkIssues( issues, users_by_id, commenter_view, hostport, comment_text, amendments, config) body = notify_helpers._TruncateBody(body) return dict(from_addr=from_addr, to=dest_email, subject=subject, body=body)
def testBodySelection_NonMember(self): """We send non-members the email body that is indented for non-members.""" email_task = notify_helpers._MakeEmailWorkItem( notify_reasons.AddrPerm(False, '*****@*****.**', self.member, REPLY_NOT_ALLOWED, user_pb2.UserPrefs()), ['reason'], self.issue, 'body link-only', 'body non', 'body mem', self.project, 'example.com', self.commenter_view, self.detail_url) self.assertEqual('*****@*****.**', email_task['to']) self.assertEqual('Issue 1234 in proj1: summary', email_task['subject']) self.assertIn('body non', email_task['body']) self.assertEqual( emailfmt.FormatFromAddr(self.project, commenter_view=self.commenter_view, can_reply_to=False), email_task['from_addr']) self.assertEqual(emailfmt.NoReplyAddress(), email_task['reply_to'])
def _MakeRulesDeletedEmailTasks(self, hostport, project, emails_by_id, rules): rules_url = framework_helpers.FormatAbsoluteURLForDomain( hostport, project.project_name, urls.ADMIN_RULES) email_data = { 'project_name': project.project_name, 'rules': rules, 'rules_url': rules_url, } logging.info(email_data) subject = '%s Project: Deleted Filter Rules' % project.project_name email_body = self.email_template.GetResponse(email_data) body = notify_helpers._TruncateBody(email_body) email_tasks = [] for rid in project.owner_ids: from_addr = emailfmt.FormatFromAddr( project, reveal_addr=True, can_reply_to=False) dest_email = emails_by_id.get(rid) email_tasks.append( dict(from_addr=from_addr, to=dest_email, subject=subject, body=body)) return email_tasks
def testNoCommenterWithNoReply(self): self.assertEqual( settings.send_noreply_email_as, emailfmt.FormatFromAddr(self.project, can_reply_to=False))
def testNoCommenter(self): self.assertEqual(settings.send_email_as, emailfmt.FormatFromAddr(self.project))
def _MakeApprovalEmailTasks( self, hostport, issue, project, approval_value, approval_name, comment, users_by_id, user_ids_from_fields, perms): """Formulate emails to be sent.""" # TODO(jojwang): avoid need to make MonorailRequest and autolinker # for comment_view OR make make tracker_views._ParseTextRuns public # and only pass text_runs to email_data. mr = monorailrequest.MonorailRequest(self.services) mr.project_name = project.project_name mr.project = project mr.perms = perms autolinker = autolink.Autolink() approval_url = framework_helpers.IssueCommentURL( hostport, project, issue.local_id, seq_num=comment.sequence) comment_view = tracker_views.IssueCommentView( project.project_name, comment, users_by_id, autolinker, {}, mr, issue) domain_url = framework_helpers.FormatAbsoluteURLForDomain( hostport, project.project_name, '/issues/') commenter_view = users_by_id[comment.user_id] email_data = { 'domain_url': domain_url, 'approval_url': approval_url, 'comment': comment_view, 'issue_local_id': issue.local_id, 'summary': issue.summary, } subject = '%s Approval: %s (Issue %s)' % ( approval_name, issue.summary, issue.local_id) email_body = self.email_template.GetResponse(email_data) body = notify_helpers._TruncateBody(email_body) recipient_ids = self._GetApprovalEmailRecipients( approval_value, comment, issue, user_ids_from_fields, omit_ids=[comment.user_id]) direct, indirect = self.services.usergroup.ExpandAnyGroupEmailRecipients( mr.cnxn, recipient_ids) # group ids were found in recipient_ids. # Re-set recipient_ids to remove group_ids if indirect: recipient_ids = set(direct + indirect) users_by_id.update(framework_views.MakeAllUserViews( mr.cnxn, self.services.user, indirect)) # already contains direct # TODO(jojwang): monorail:3588, refine email contents based on direct # and indirect user_ids returned. email_tasks = [] for rid in recipient_ids: # TODO(jojwang): monorail:3588, add reveal_addr based on # recipient member status from_addr = emailfmt.FormatFromAddr( project, commenter_view=commenter_view, can_reply_to=False) dest_email = users_by_id[rid].email email_tasks.append( dict(from_addr=from_addr, to=dest_email, subject=subject, body=body) ) return email_tasks
def _MakeEmailWorkItem(addr_perm, reasons, issue, body_for_non_members, body_for_members, project, hostport, commenter_view, detail_url, seq_num=None, subject_prefix=None, compact_subject_prefix=None): """Make one email task dict for one user, includes a detailed reason.""" subject_format = ((subject_prefix or 'Issue ') + '%(local_id)d in %(project_name)s: %(summary)s') if addr_perm.user and addr_perm.user.email_compact_subject: subject_format = ((compact_subject_prefix or '') + '%(project_name)s:%(local_id)d: %(summary)s') subject = subject_format % { 'local_id': issue.local_id, 'project_name': issue.project_name, 'summary': issue.summary, } footer = _MakeNotificationFooter(reasons, addr_perm.reply_perm, hostport) if isinstance(footer, unicode): footer = footer.encode('utf-8') if addr_perm.is_member: logging.info('got member %r, sending body for members', addr_perm.address) body = _TruncateBody(body_for_members) + footer else: logging.info('got non-member %r, sending body for non-members', addr_perm.address) body = _TruncateBody(body_for_non_members) + footer logging.info('sending message footer:\n%r', footer) can_reply_to = (addr_perm.reply_perm != notify_reasons.REPLY_NOT_ALLOWED and project.process_inbound_email) from_addr = emailfmt.FormatFromAddr(project, commenter_view=commenter_view, reveal_addr=addr_perm.is_member, can_reply_to=can_reply_to) if can_reply_to: reply_to = '%s@%s' % (project.project_name, emailfmt.MailDomain()) else: reply_to = emailfmt.NoReplyAddress() refs = emailfmt.GetReferences( addr_perm.address, subject, seq_num, '%s@%s' % (project.project_name, emailfmt.MailDomain())) # We use markup to display a convenient link that takes users directly to the # issue without clicking on the email. html_body = None # cgi.escape the body and additionally escape single quotes which are # occassionally used to contain HTML attributes and event handler # definitions. html_escaped_body = cgi.escape(body, quote=1).replace("'", ''') template = HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE if addr_perm.user and not addr_perm.user.email_view_widget: template = HTML_BODY_WITHOUT_GMAIL_ACTION_TEMPLATE html_body = template % { 'url': detail_url, 'body': _AddHTMLTags(html_escaped_body.decode('utf-8')), } return dict(to=addr_perm.address, subject=subject, body=body, html_body=html_body, from_addr=from_addr, reply_to=reply_to, references=refs)
footer = _MakeNotificationFooter(reasons, reply_perm, hostport) if isinstance(footer, unicode): footer = footer.encode('utf-8') if recipient_is_member: logging.info('got member %r, sending body for members', to_addr) body = _TruncateBody(body_for_members) + footer else: logging.info('got non-member %r, sending body for non-members', to_addr) body = _TruncateBody(body_for_non_members) + footer logging.info('sending message footer:\n%r', footer) can_reply_to = (reply_perm != notify_reasons.REPLY_NOT_ALLOWED and project.process_inbound_email) from_addr = emailfmt.FormatFromAddr(project, commenter_view=commenter_view, reveal_addr=recipient_is_member, can_reply_to=can_reply_to) if can_reply_to: reply_to = '%s@%s' % (project.project_name, emailfmt.MailDomain()) else: reply_to = emailfmt.NoReplyAddress() refs = emailfmt.GetReferences( to_addr, subject, seq_num, '%s@%s' % (project.project_name, emailfmt.MailDomain())) # We use markup to display a convenient link that takes users directly to the # issue without clicking on the email. html_body = None # cgi.escape the body and additionally escape single quotes which are # occassionally used to contain HTML attributes and event handler # definitions. html_escaped_body = cgi.escape(body, quote=1).replace("'", ''')