示例#1
0
    def ListComments(self, mc, request):
        """Return comments on the specified issue in a response proto."""
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref)
        with work_env.WorkEnv(mc, self.services) as we:
            comments = we.ListIssueComments(issue)
            _, comment_reporters = we.LookupIssueFlaggers(issue)

        with mc.profiler.Phase('making user views'):
            users_involved_in_comments = tracker_bizobj.UsersInvolvedInCommentList(
                comments)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved_in_comments)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            issue_perms = permissions.UpdateIssuePermissions(
                mc.perms, project, issue, mc.auth.effective_ids, config=config)
            converted_comments = converters.ConvertCommentList(
                issue, comments, config, users_by_id, comment_reporters,
                mc.auth.user_id, issue_perms)
            response = issues_pb2.ListCommentsResponse(
                comments=converted_comments)

        return response
示例#2
0
    def HandleRequest(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
        if not mr.start and not mr.num:
            issues = self.services.issue.GetAllIssuesInProject(
                mr.cnxn, mr.project.project_id)
        else:
            local_id_range = range(mr.start, mr.start + mr.num)
            issues = self.services.issue.GetIssuesByLocalIDs(
                mr.cnxn, mr.project.project_id, local_id_range)
        user_id_set = tracker_bizobj.UsersInvolvedInIssues(issues)

        comments_dict = self.services.issue.GetCommentsForIssues(
            mr.cnxn, [issue.issue_id for issue in issues])
        for comment_list in comments_dict.itervalues():
            user_id_set.update(
                tracker_bizobj.UsersInvolvedInCommentList(comment_list))

        starrers_dict = self.services.issue_star.LookupItemsStarrers(
            mr.cnxn, [issue.issue_id for issue in issues])
        for starrer_id_list in starrers_dict.itervalues():
            user_id_set.update(starrer_id_list)

        # The value 0 indicates "no user", e.g., that an issue has no owner.
        # We don't need to create a User row to represent that.
        user_id_set.discard(0)
        email_dict = self.services.user.LookupUserEmails(mr.cnxn, user_id_set)

        issues_json = [
            self._MakeIssueJSON(mr, issue, email_dict,
                                comments_dict.get(issue.issue_id, []),
                                starrers_dict.get(issue.issue_id, []))
            for issue in issues if not issue.deleted
        ]

        json_data = {
            'metadata': {
                'version': 1,
                'when': int(time.time()),
                'who': mr.auth.email,
                'project': mr.project_name,
                'start': mr.start,
                'num': mr.num,
            },
            'issues': issues_json,
            # This list could be derived from the 'issues', but we provide it for
            # ease of processing.
            'emails': email_dict.values(),
        }
        return json_data
  def testUsersInvolvedInCommentList(self):
    self.assertEqual(set(), tracker_bizobj.UsersInvolvedInCommentList([]))

    c1 = tracker_pb2.IssueComment()
    c1.user_id = 111L
    c1.amendments.append(tracker_pb2.Amendment(newvalue='foo'))

    c2 = tracker_pb2.IssueComment()
    c2.user_id = 111L
    c2.amendments.append(tracker_pb2.Amendment(
        added_user_ids=[222L], removed_user_ids=[333L]))

    self.assertEqual({111L},
                     tracker_bizobj.UsersInvolvedInCommentList([c1]))

    self.assertEqual({111L, 222L, 333L},
                     tracker_bizobj.UsersInvolvedInCommentList([c2]))

    self.assertEqual({111L, 222L, 333L},
                     tracker_bizobj.UsersInvolvedInCommentList([c1, c2]))
示例#4
0
  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    if mr.local_id is None:
      self.abort(404, 'no issue specified')
    with work_env.WorkEnv(mr, self.services) as we:
      # Signed in users could edit the issue, so it must be fresh.
      use_cache = not mr.auth.user_id
      issue = we.GetIssueByLocalID(
          mr.project_id, mr.local_id, use_cache=use_cache)

      # We give no explanation of missing issues on the peek page.
      if issue.deleted:
        self.abort(404, 'issue not found')

      star_cnxn = sql.MonorailConnection()
      star_promise = framework_helpers.Promise(
          we.IsIssueStarred, issue, cnxn=star_cnxn)

      config = we.GetProjectConfig(mr.project_id)
      comments = we.ListIssueComments(issue)

    descriptions, visible_comments, cmnt_pagination = PaginateComments(
        mr, issue, comments, config, self.services)

    with mr.profiler.Phase('making user proxies'):
      involved_user_ids = tracker_bizobj.UsersInvolvedInIssues([issue])
      group_ids = self.services.usergroup.DetermineWhichUserIDsAreGroups(
          mr.cnxn, involved_user_ids)
      comment_user_ids = tracker_bizobj.UsersInvolvedInCommentList(
          descriptions + visible_comments)
      users_by_id = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, involved_user_ids,
          comment_user_ids, group_ids=group_ids)
      framework_views.RevealAllEmailsToMembers(mr.auth, mr.project, users_by_id)

    (issue_view, description_views,
     comment_views) = self._MakeIssueAndCommentViews(
         mr, issue, users_by_id, descriptions, visible_comments, config,
         issue_reporters=[], comment_reporters=[])

    with mr.profiler.Phase('getting starring info'):
      starred = star_promise.WaitAndGetValue()
      star_cnxn.Close()
      permit_edit = permissions.CanEditIssue(
          mr.auth.effective_ids, mr.perms, mr.project, issue)

    mr.ComputeColSpec(config)
    restrict_to_known = config.restrict_to_known

    page_perms = self.MakePagePerms(
        mr, issue,
        permissions.CREATE_ISSUE,
        permissions.SET_STAR,
        permissions.EDIT_ISSUE,
        permissions.EDIT_ISSUE_SUMMARY,
        permissions.EDIT_ISSUE_STATUS,
        permissions.EDIT_ISSUE_OWNER,
        permissions.EDIT_ISSUE_CC,
        permissions.DELETE_ISSUE,
        permissions.ADD_ISSUE_COMMENT,
        permissions.DELETE_OWN,
        permissions.DELETE_ANY,
        permissions.VIEW_INBOUND_MESSAGES)
    page_perms.EditIssue = ezt.boolean(permit_edit)

    prevent_restriction_removal = (
        mr.project.only_owners_remove_restrictions and
        not framework_bizobj.UserOwnsProject(
            mr.project, mr.auth.effective_ids))

    cmd_slots, default_slot_num = self.services.features.GetRecentCommands(
        mr.cnxn, mr.auth.user_id, mr.project_id)
    cmd_slot_views = [
        template_helpers.EZTItem(
            slot_num=slot_num, command=command, comment=comment)
        for slot_num, command, comment in cmd_slots]

    previous_locations = self.GetPreviousLocations(mr, issue)

    return {
        'issue_tab_mode': 'issueDetail',
        'issue': issue_view,
        'description': description_views,
        'comments': comment_views,
        'labels': issue.labels,
        'num_detail_rows': len(comment_views) + 4,
        'noisy': ezt.boolean(tracker_helpers.IsNoisy(
            len(comment_views), issue.star_count)),

        'cmnt_pagination': cmnt_pagination,
        'colspec': mr.col_spec,
        'searchtip': 'You can jump to any issue by number',
        'starred': ezt.boolean(starred),

        'pagegen': str(int(time.time() * 1000000)),

        'restrict_to_known': ezt.boolean(restrict_to_known),
        'prevent_restriction_removal': ezt.boolean(
            prevent_restriction_removal),

        'statuses_offer_merge': config.statuses_offer_merge,
        'page_perms': page_perms,
        'cmd_slots': cmd_slot_views,
        'default_slot_num': default_slot_num,
        'quick_edit_submit_url': tracker_helpers.FormatRelativeIssueURL(
            issue.project_name, urls.ISSUE_PEEK + '.do', id=issue.local_id),
        'previous_locations': previous_locations,
        # for template issue-meta-part shared by issuedetail servlet
        'user_remaining_hotlists': [],
        'user_issue_hotlists': [],
        'involved_users_issue_hotlists': [],
        'remaining_issue_hotlists': [],
        }
示例#5
0
    def ListActivities(self, mc, request):
        """Return issue activities by a specified user in a response proto."""
        converted_user = converters.IngestUserRef(mc.cnxn, request.user_ref,
                                                  self.services.user)
        user = self.services.user.GetUser(mc.cnxn, converted_user)
        comments = self.services.issue.GetIssueActivity(
            mc.cnxn, user_ids={request.user_ref.user_id})
        issues = self.services.issue.GetIssues(mc.cnxn,
                                               {c.issue_id
                                                for c in comments})
        project_dict = tracker_helpers.GetAllIssueProjects(
            mc.cnxn, issues, self.services.project)
        config_dict = self.services.config.GetProjectConfigs(
            mc.cnxn, list(project_dict.keys()))
        allowed_issues = tracker_helpers.FilterOutNonViewableIssues(
            mc.auth.effective_ids, user, project_dict, config_dict, issues)
        issue_dict = {issue.issue_id: issue for issue in allowed_issues}
        comments = [c for c in comments if c.issue_id in issue_dict]

        users_by_id = framework_views.MakeAllUserViews(
            mc.cnxn, self.services.user, [request.user_ref.user_id],
            tracker_bizobj.UsersInvolvedInCommentList(comments))
        for project in project_dict.values():
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        issues_by_project = {}
        for issue in allowed_issues:
            issues_by_project.setdefault(issue.project_id, []).append(issue)

        # A dictionary {issue_id: perms} of the PermissionSet for the current user
        # on each of the issues.
        issue_perms_dict = {}
        # A dictionary {comment_id: [reporter_id]} of users who have reported the
        # comment as spam.
        comment_reporters = {}
        for project_id, project_issues in issues_by_project.items():
            mc.LookupLoggedInUserPerms(project_dict[project_id])
            issue_perms_dict.update({
                issue.issue_id: permissions.UpdateIssuePermissions(
                    mc.perms,
                    project_dict[issue.project_id],
                    issue,
                    mc.auth.effective_ids,
                    config=config_dict[issue.project_id])
                for issue in project_issues
            })

            with work_env.WorkEnv(mc, self.services) as we:
                project_issue_reporters = we.LookupIssuesFlaggers(
                    project_issues)
                for _, issue_comment_reporters in project_issue_reporters.values(
                ):
                    comment_reporters.update(issue_comment_reporters)

        with mc.profiler.Phase('converting to response objects'):
            converted_comments = []
            for c in comments:
                issue = issue_dict.get(c.issue_id)
                issue_perms = issue_perms_dict.get(c.issue_id)
                result = converters.ConvertComment(
                    issue, c, config_dict.get(issue.project_id), users_by_id,
                    comment_reporters.get(c.id, []),
                    {c.id: 1} if c.is_description else {}, mc.auth.user_id,
                    issue_perms)
                converted_comments.append(result)
            converted_issues = [
                issue_objects_pb2.IssueSummary(project_name=issue.project_name,
                                               local_id=issue.local_id,
                                               summary=issue.summary)
                for issue in allowed_issues
            ]
            response = issues_pb2.ListActivitiesResponse(
                comments=converted_comments, issue_summaries=converted_issues)

        return response
示例#6
0
    def HandleRequest(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
        if mr.query or mr.can != 1:
            with work_env.WorkEnv(mr, self.services) as we:
                url_params = []
                pipeline = we.ListIssues(mr.query, [mr.project.project_name],
                                         mr.auth.user_id, mr.num, mr.start,
                                         url_params, mr.can, mr.group_by_spec,
                                         mr.sort_spec, False)
            issues = pipeline.allowed_results
        # no user query and mr.can == 1 (we want all issues)
        elif not mr.start and not mr.num:
            issues = self.services.issue.GetAllIssuesInProject(
                mr.cnxn, mr.project.project_id)
        else:
            local_id_range = list(range(mr.start, mr.start + mr.num))
            issues = self.services.issue.GetIssuesByLocalIDs(
                mr.cnxn, mr.project.project_id, local_id_range)

        user_id_set = tracker_bizobj.UsersInvolvedInIssues(issues)

        comments_dict = self.services.issue.GetCommentsForIssues(
            mr.cnxn, [issue.issue_id for issue in issues])
        for comment_list in comments_dict.values():
            user_id_set.update(
                tracker_bizobj.UsersInvolvedInCommentList(comment_list))

        starrers_dict = self.services.issue_star.LookupItemsStarrers(
            mr.cnxn, [issue.issue_id for issue in issues])
        for starrer_id_list in starrers_dict.values():
            user_id_set.update(starrer_id_list)

        # The value 0 indicates "no user", e.g., that an issue has no owner.
        # We don't need to create a User row to represent that.
        user_id_set.discard(0)
        email_dict = self.services.user.LookupUserEmails(mr.cnxn,
                                                         user_id_set,
                                                         ignore_missed=True)

        issues_json = [
            self._MakeIssueJSON(mr, issue, email_dict,
                                comments_dict.get(issue.issue_id, []),
                                starrers_dict.get(issue.issue_id, []))
            for issue in issues if not issue.deleted
        ]

        json_data = {
            'metadata': {
                'version': 1,
                'when': int(time.time()),
                'who': mr.auth.email,
                'project': mr.project_name,
                'start': mr.start,
                'num': mr.num,
            },
            'issues': issues_json,
            # This list could be derived from the 'issues', but we provide it for
            # ease of processing.
            'emails': list(email_dict.values()),
        }
        return json_data