def Handler(self, inbound_email_message, project_addr): """Process an inbound email message.""" msg = inbound_email_message.original email_tasks = self.ProcessMail(msg, project_addr) if email_tasks: notify_helpers.AddAllEmailTasks(email_tasks)
def HandleRequest(self, mr): """Process the task to notify project owners after a filter rule has been deleted. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful for debugging. """ project_id = mr.GetPositiveIntParam('project_id') rules = mr.GetListParam('filter_rules') hostport = mr.GetParam('hostport') params = dict( project_id=project_id, rules=rules, hostport=hostport, ) logging.info('deleted filter rules params are %r', params) project = self.services.project.GetProject(mr.cnxn, project_id) emails_by_id = self.services.user.LookupUserEmails( mr.cnxn, project.owner_ids, ignore_missed=True) tasks = self._MakeRulesDeletedEmailTasks( hostport, project, emails_by_id, rules) notified = notify_helpers.AddAllEmailTasks(tasks) return { 'params': params, 'notified': notified, 'tasks': tasks, }
def HandleRequest(self, mr): """Process the task to process an issue date action. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful just for debugging. The main goal is the side-effect of sending emails. """ issue_id = mr.GetPositiveIntParam('issue_id') hostport = framework_helpers.GetHostPort() issue = self.services.issue.GetIssue(mr.cnxn, issue_id) project = self.services.project.GetProject(mr.cnxn, issue.project_id) config = self.services.config.GetProjectConfig(mr.cnxn, issue.project_id) pings = self._CalculateIssuePings(issue, config) if not pings: logging.warning('Issue %r has no dates to ping afterall?', issue_id) return comment = self._CreatePingComment(mr.cnxn, issue, pings, hostport) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, tracker_bizobj.UsersInvolvedInIssues([issue]), [comment.user_id]) logging.info('users_by_id is %r', users_by_id) tasks = self._MakeEmailTasks(mr.cnxn, issue, project, config, comment, hostport, users_by_id, pings) notified = notify_helpers.AddAllEmailTasks(tasks) return { 'notified': notified, }
def testAddAllEmailTasks(self): notify_helpers.AddAllEmailTasks(tasks=[{ 'to': 'user' }, { 'to': 'user2' }]) tasks = self.taskqueue_stub.get_filtered_tasks( url=urls.OUTBOUND_EMAIL_TASK + '.do') self.assertEqual(2, len(tasks))
def HandleRequest(self, mr): """Process the task to notify users after an approval change. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful just for debugging. The main goal is the side-effect of sending emails. """ send_email = bool(mr.GetIntParam('send_email')) issue_id = mr.GetPositiveIntParam('issue_id') approval_id = mr.GetPositiveIntParam('approval_id') comment_id = mr.GetPositiveIntParam('comment_id') hostport = mr.GetParam('hostport') params = dict( temporary='', hostport=hostport, issue_id=issue_id ) logging.info('approval change params are %r', params) issue, approval_value = self.services.issue.GetIssueApproval( mr.cnxn, issue_id, approval_id, use_cache=False) project = self.services.project.GetProject(mr.cnxn, issue.project_id) config = self.services.config.GetProjectConfig(mr.cnxn, issue.project_id) approval_fd = tracker_bizobj.FindFieldDefByID(approval_id, config) if approval_fd is None: raise exceptions.NoSuchFieldDefException() # GetCommentsForIssue will fill the sequence for all comments, while # other method for getting a single comment will not. # The comment sequence is especially useful for Approval issues with # many comment sections. comment = None all_comments = self.services.issue.GetCommentsForIssue(mr.cnxn, issue_id) for c in all_comments: if c.id == comment_id: comment = c break if not comment: raise exceptions.NoSuchCommentException() field_user_ids = set() relevant_fds = [fd for fd in config.field_defs if not fd.approval_id or fd.approval_id is approval_value.approval_id] for fd in relevant_fds: field_user_ids.update( notify_reasons.ComputeNamedUserIDsToNotify(issue.field_values, fd)) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, [issue.owner_id], approval_value.approver_ids, tracker_bizobj.UsersInvolvedInComment(comment), list(field_user_ids)) tasks = [] if send_email: tasks = self._MakeApprovalEmailTasks( hostport, issue, project, approval_value, approval_fd.field_name, comment, users_by_id, list(field_user_ids), mr.perms) notified = notify_helpers.AddAllEmailTasks(tasks) return { 'params': params, 'notified': notified, 'tasks': tasks, }
def HandleRequest(self, mr): """Process the task to notify users after an issue change. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful just for debugging. The main goal is the side-effect of sending emails. """ issue_id = mr.GetPositiveIntParam('issue_id') if not issue_id: return { 'params': {}, 'notified': [], 'message': 'Cannot proceed without a valid issue ID.', } commenter_id = mr.GetPositiveIntParam('commenter_id') seq_num = mr.seq omit_ids = [commenter_id] hostport = mr.GetParam('hostport') old_owner_id = mr.GetPositiveIntParam('old_owner_id') send_email = bool(mr.GetIntParam('send_email')) comment_id = mr.GetPositiveIntParam('comment_id') params = dict( issue_id=issue_id, commenter_id=commenter_id, seq_num=seq_num, hostport=hostport, old_owner_id=old_owner_id, omit_ids=omit_ids, send_email=send_email, comment_id=comment_id) logging.info('issue change params are %r', params) # TODO(jrobbins): Re-enable the issue cache for notifications after # the stale issue defect (monorail:2514) is 100% resolved. issue = self.services.issue.GetIssue(mr.cnxn, issue_id, use_cache=False) project = self.services.project.GetProject(mr.cnxn, issue.project_id) config = self.services.config.GetProjectConfig(mr.cnxn, issue.project_id) if issue.is_spam: # Don't send email for spam issues. return { 'params': params, 'notified': [], } all_comments = self.services.issue.GetCommentsForIssue( mr.cnxn, issue.issue_id) if comment_id: logging.info('Looking up comment by comment_id') for c in all_comments: if c.id == comment_id: comment = c logging.info('Comment was found by comment_id') break else: raise ValueError('Comment %r was not found' % comment_id) else: logging.info('Looking up comment by seq_num') comment = all_comments[seq_num] # Only issues that any contributor could view sent to mailing lists. contributor_could_view = permissions.CanViewIssue( set(), permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, project, issue) starrer_ids = self.services.issue_star.LookupItemStarrers( mr.cnxn, issue.issue_id) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, tracker_bizobj.UsersInvolvedInIssues([issue]), [old_owner_id], tracker_bizobj.UsersInvolvedInComment(comment), issue.cc_ids, issue.derived_cc_ids, starrer_ids, omit_ids) # Make followup tasks to send emails tasks = [] if send_email: tasks = self._MakeEmailTasks( mr.cnxn, project, issue, config, old_owner_id, users_by_id, all_comments, comment, starrer_ids, contributor_could_view, hostport, omit_ids, mr.perms) notified = notify_helpers.AddAllEmailTasks(tasks) return { 'params': params, 'notified': notified, }
def HandleRequest(self, mr): """Process the task to notify users after an issue blocking change. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful just for debugging. The main goal is the side-effect of sending emails. """ issue_ids = mr.GetIntListParam('issue_ids') hostport = mr.GetParam('hostport') if not issue_ids: return { 'params': {}, 'notified': [], 'message': 'Cannot proceed without a valid issue IDs.', } old_owner_ids = mr.GetIntListParam('old_owner_ids') comment_text = mr.GetParam('comment_text') commenter_id = mr.GetPositiveIntParam('commenter_id') amendments = mr.GetParam('amendments') send_email = bool(mr.GetIntParam('send_email')) params = dict( issue_ids=issue_ids, commenter_id=commenter_id, hostport=hostport, old_owner_ids=old_owner_ids, comment_text=comment_text, send_email=send_email, amendments=amendments) logging.info('bulk edit params are %r', params) issues = self.services.issue.GetIssues(mr.cnxn, issue_ids) # TODO(jrobbins): For cross-project bulk edits, prefetch all relevant # projects and configs and pass a dict of them to subroutines. For # now, all issue must be in the same project. project_id = issues[0].project_id project = self.services.project.GetProject(mr.cnxn, project_id) config = self.services.config.GetProjectConfig(mr.cnxn, project_id) issues = [issue for issue in issues if not issue.is_spam] anon_perms = permissions.GetPermissions(None, set(), project) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, [commenter_id]) ids_in_issues = {} starrers = {} non_private_issues = [] for issue, old_owner_id in zip(issues, old_owner_ids): # TODO(jrobbins): use issue_id consistently rather than local_id. starrers[issue.local_id] = self.services.issue_star.LookupItemStarrers( mr.cnxn, issue.issue_id) named_ids = set() # users named in user-value fields that notify. for fd in config.field_defs: named_ids.update(notify_reasons.ComputeNamedUserIDsToNotify( issue.field_values, fd)) direct, indirect = self.services.usergroup.ExpandAnyUserGroups( mr.cnxn, list(issue.cc_ids) + list(issue.derived_cc_ids) + [issue.owner_id, old_owner_id, issue.derived_owner_id] + list(named_ids)) ids_in_issues[issue.local_id] = set(starrers[issue.local_id]) ids_in_issues[issue.local_id].update(direct) ids_in_issues[issue.local_id].update(indirect) ids_in_issue_needing_views = ( ids_in_issues[issue.local_id] | tracker_bizobj.UsersInvolvedInIssues([issue])) new_ids_in_issue = [user_id for user_id in ids_in_issue_needing_views if user_id not in users_by_id] users_by_id.update( framework_views.MakeAllUserViews( mr.cnxn, self.services.user, new_ids_in_issue)) anon_can_view = permissions.CanViewIssue( set(), anon_perms, project, issue) if anon_can_view: non_private_issues.append(issue) commenter_view = users_by_id[commenter_id] omit_addrs = {commenter_view.email} tasks = [] if send_email: email_tasks = self._BulkEditEmailTasks( mr.cnxn, issues, old_owner_ids, omit_addrs, project, non_private_issues, users_by_id, ids_in_issues, starrers, commenter_view, hostport, comment_text, amendments, config) tasks = email_tasks notified = notify_helpers.AddAllEmailTasks(tasks) return { 'params': params, 'notified': notified, }
def HandleRequest(self, mr): """Process the task to notify users after an issue blocking change. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format which is useful just for debugging. The main goal is the side-effect of sending emails. """ issue_id = mr.GetPositiveIntParam('issue_id') if not issue_id: return { 'params': {}, 'notified': [], 'message': 'Cannot proceed without a valid issue ID.', } commenter_id = mr.GetPositiveIntParam('commenter_id') omit_ids = [commenter_id] hostport = mr.GetParam('hostport') delta_blocker_iids = mr.GetIntListParam('delta_blocker_iids') send_email = bool(mr.GetIntParam('send_email')) params = dict( issue_id=issue_id, commenter_id=commenter_id, hostport=hostport, delta_blocker_iids=delta_blocker_iids, omit_ids=omit_ids, send_email=send_email) logging.info('blocking change params are %r', params) issue = self.services.issue.GetIssue(mr.cnxn, issue_id) if issue.is_spam: return { 'params': params, 'notified': [], } upstream_issues = self.services.issue.GetIssues( mr.cnxn, delta_blocker_iids) logging.info('updating ids %r', [up.local_id for up in upstream_issues]) upstream_projects = tracker_helpers.GetAllIssueProjects( mr.cnxn, upstream_issues, self.services.project) upstream_configs = self.services.config.GetProjectConfigs( mr.cnxn, list(upstream_projects.keys())) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, [commenter_id]) commenter_view = users_by_id[commenter_id] tasks = [] if send_email: for upstream_issue in upstream_issues: one_issue_email_tasks = self._ProcessUpstreamIssue( mr.cnxn, upstream_issue, upstream_projects[upstream_issue.project_id], upstream_configs[upstream_issue.project_id], issue, omit_ids, hostport, commenter_view) tasks.extend(one_issue_email_tasks) notified = notify_helpers.AddAllEmailTasks(tasks) return { 'params': params, 'notified': notified, }