def GatherHelpData(self, mr, page_data): """Return a dict of values to drive on-page user help. Args: mr: common information parsed from the HTTP request. page_data: Dictionary of base and page template data. Returns: A dict of values to drive on-page user help, to be added to page_data. """ help_data = super(IssueList, self).GatherHelpData(mr, page_data) dismissed = [] if mr.auth.user_pb: with work_env.WorkEnv(mr, self.services) as we: userprefs = we.GetUserPrefs(mr.auth.user_id) dismissed = [ pv.name for pv in userprefs.prefs if pv.value == 'true'] if mr.project_id: config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) else: config = tracker_bizobj.MakeDefaultProjectIssueConfig(None) try: _query_ast, is_fulltext_query = searchpipeline.ParseQuery( mr, config, self.services) except query2ast.InvalidQueryError: is_fulltext_query = False query_plus_col_spec = '%r %r' % ( mr.query and mr.query.lower(), mr.col_spec and mr.col_spec.lower()) uses_timestamp_term = any( col_name in query_plus_col_spec for col_name in ('ownermodified', 'statusmodified', 'componentmodified')) if (mr.mode == 'grid' and mr.cells == 'tiles' and len(page_data.get('results', [])) > settings.max_tiles_in_grid and 'showing_ids_instead_of_tiles' not in dismissed): help_data['cue'] = 'showing_ids_instead_of_tiles' elif (_AnyDerivedValues(page_data.get('table_data', [])) and 'italics_mean_derived' not in dismissed): help_data['cue'] = 'italics_mean_derived' elif (uses_timestamp_term and 'issue_timestamps' not in dismissed): help_data['cue'] = 'issue_timestamps' # Note that the following are only offered to signed in users because # otherwise the first one would appear all the time to anon users. elif (mr.auth.user_id and mr.mode != 'grid' and 'dit_keystrokes' not in dismissed): help_data['cue'] = 'dit_keystrokes' elif (mr.auth.user_id and is_fulltext_query and 'stale_fulltext' not in dismissed): help_data['cue'] = 'stale_fulltext' return help_data
def StarUser(self, mc, request): """Star a given user.""" user_id = converters.IngestUserRef(mc.cnxn, request.user_ref, self.services.user) with work_env.WorkEnv(mc, self.services) as we: we.StarUser(user_id, request.starred) star_count = we.GetUserStarCount(user_id) result = users_pb2.StarUserResponse(star_count=star_count) return result
def testProcessSettingsForm_OldStylePrefs(self): """We can set prefs that are stored in the User PB.""" user = self.services.user.TestAddUser('*****@*****.**', 111) post_data = {'obscure_email': 1, 'notify': 1} with work_env.WorkEnv(self.mr, self.services) as we: framework_helpers.UserSettings.ProcessSettingsForm( we, post_data, user) self.assertTrue(user.obscure_email) self.assertTrue(user.notify_issue_change) self.assertFalse(user.notify_starred_ping)
def HandleRequest(self, mr): """Delete users with the emails given in the 'emails' param.""" emails = mr.GetListParam('emails', default_value=[]) assert len(emails) <= MAX_DELETE_USERS_SIZE, ( 'We cannot delete more than %d users at once, current users: %d' % (MAX_DELETE_USERS_SIZE, len(emails))) if len(emails) == 0: logging.info("No user emails found in deletion request") return with work_env.WorkEnv(mr, self.services) as we: we.ExpungeUsers(emails, check_perms=False)
def HandleRequest(self, mr): """Delete users with the emails given in the 'emails' param.""" # TODO(jojwang): monorail:5740, remove default_value when # deleted user_id transition is done. emails = mr.GetListParam( 'emails', default_value=['*****@*****.**']) assert len(emails) <= framework_constants.MAX_DELETE_USERS_SIZE, ( 'We cannot delete more than %d users at once, current users: %d' % (framework_constants.MAX_DELETE_USERS_SIZE, len(emails))) with work_env.WorkEnv(mr, self.services) as we: we.ExpungeUsers(emails, check_perms=False)
def GetUser(self, mc, request): """Return info about the specified user.""" with work_env.WorkEnv(mc, self.services) as we: users, linked_user_ids = we.ListReferencedUsers( [request.user_ref.display_name]) linked_user_views = framework_views.MakeAllUserViews( mc.cnxn, self.services.user, linked_user_ids) with mc.profiler.Phase('converting to response objects'): response_users = converters.ConvertUsers(users, linked_user_views) return response_users[0]
def HandleRequest(self, mr): """Convert Type=Launch issues to new Type=FLT-Launch issues.""" launch = mr.GetParam('launch') if launch == 'delete': return self.UndoConversion(mr) if launch == 'verify': return self.VerifyConversion(mr) project_info = self.FetchAndAssertProjectInfo(mr) # Search for issues: with work_env.WorkEnv(mr, self.services) as we: pipeline = we.ListIssues(project_info.q, ['chromium'], mr.auth.user_id, CONVERT_NUM, CONVERT_START, [], 2, GROUP_BY_SPEC, SORT_SPEC, False) # Convert issues: for possible_stale_issue in pipeline.visible_results: # Note: These approval values and phases from templates will be used # and modified to create approval values and phases for each issue. # We need to create copies for each issue so changes are not carried # over to the conversion of the next issue in the loop. template_avs = self.CreateApprovalCopies( project_info.approval_values) template_phases = self.CreatePhasesCopies(project_info.phases) issue = self.services.issue.GetIssue(mr.cnxn, possible_stale_issue.issue_id, use_cache=False) new_approvals = ConvertLaunchLabels( issue.labels, template_avs, project_info.config.field_defs, project_info.approvals_to_labels) m_fvs = ConvertMLabels(issue.labels, template_phases, project_info.m_target_id, project_info.m_approved_id, project_info.labels_re, project_info.phase_map) people_fvs = self.ConvertPeopleLabels(mr, issue.labels, project_info.pm_fid, project_info.tl_fid, project_info.te_fid, project_info.ux_fid) amendments = self.ExecuteIssueChanges(project_info.config, issue, new_approvals, template_phases, m_fvs + people_fvs) logging.info(amendments) return { 'converted_issues': [issue.local_id for issue in pipeline.visible_results], 'num': len(pipeline.visible_results), }
def DeleteComment(self, mc, request): _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: all_comments = we.ListIssueComments(issue) try: comment = all_comments[request.sequence_num] except IndexError: raise exceptions.NoSuchCommentException() we.DeleteComment(issue, comment, request.delete) return empty_pb2.Empty()
def StarHotlist(self, mc, request): """Star the specified hotlist.""" hotlist_id = converters.IngestHotlistRef(mc.cnxn, self.services.user, self.services.features, request.hotlist_ref) with work_env.WorkEnv(mc, self.services) as we: mc.LookupLoggedInUserPerms(None) we.StarHotlist(hotlist_id, request.starred) star_count = we.GetHotlistStarCount(hotlist_id) result = features_pb2.StarHotlistResponse(star_count=star_count) return result
def FlagComment(self, mc, request): """Flag or unflag the given comment as spam.""" _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: comments = we.ListIssueComments(issue) if request.sequence_num >= len(comments): raise exceptions.InputException('Invalid sequence number.') we.FlagComment(issue, comments[request.sequence_num], request.flag) result = issues_pb2.FlagCommentResponse() return result
def IsIssueStarred(self, mc, request): """Respond true if the signed-in user has starred the specified issue.""" _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: is_starred = we.IsIssueStarred(issue) with mc.profiler.Phase('converting to response objects'): response = issues_pb2.IsIssueStarredResponse() response.is_starred = is_starred return response
def FlagIssues(self, mc, request): """Flag or unflag the given issues as spam.""" if not request.issue_refs: raise exceptions.InputException('Param `issue_refs` empty.') _project, issue_ids, _config = self._GetProjectIssueIDsAndConfig( mc, request.issue_refs) with work_env.WorkEnv(mc, self.services) as we: issues_by_id = we.GetIssuesDict(issue_ids, use_cache=False) we.FlagIssues(list(issues_by_id.values()), request.flag) result = issues_pb2.FlagIssuesResponse() return result
def RerankBlockedOnIssues(self, mc, request): """Rerank the blocked on issues for the given issue ref.""" moved_issue_id, target_issue_id = converters.IngestIssueRefs( mc.cnxn, [request.moved_ref, request.target_ref], self.services) _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref) with work_env.WorkEnv(mc, self.services) as we: we.RerankBlockedOnIssues(issue, moved_issue_id, target_issue_id, request.split_above) with work_env.WorkEnv(mc, self.services) as we: issue = we.GetIssue(issue.issue_id) related_refs = we.GetRelatedIssueRefs([issue]) with mc.profiler.Phase('converting to response objects'): converted_issue_refs = converters.ConvertIssueRefs( issue.blocked_on_iids, related_refs) result = issues_pb2.RerankBlockedOnIssuesResponse( blocked_on_issue_refs=converted_issue_refs) return result
def ListStarredIssues(self, mc, _request): """Return a list of issue ids that the signed-in user has starred.""" with work_env.WorkEnv(mc, self.services) as we: starred_issues = we.ListStarredIssueIDs() starred_issues_dict = we.GetIssueRefs(starred_issues) with mc.profiler.Phase('converting to response objects'): converted_starred_issue_refs = converters.ConvertIssueRefs( starred_issues, starred_issues_dict) response = issues_pb2.ListStarredIssuesResponse( starred_issue_refs=converted_starred_issue_refs) return response
def ProcessFormData(self, mr, post_data): """Process the posted form.""" with work_env.WorkEnv(mr, self.services) as we: framework_helpers.UserSettings.ProcessSettingsForm( we, post_data, mr.auth.user_pb) url = framework_helpers.FormatAbsoluteURL(mr, urls.USER_SETTINGS, include_project=False, saved=1, ts=int(time.time())) return url
def CopyIssue(self, mc, request): """Copy an issue.""" _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: target_project = we.GetProjectByName(request.target_project_name) copied_issue = we.CopyIssue(issue, target_project) result = issues_pb2.CopyIssueResponse( new_issue_ref=converters.ConvertIssueRef(( copied_issue.project_name, copied_issue.local_id))) return result
def AddIssuesToHotlists(self, mc, request): """Add the given issues to the given hotlists.""" hotlist_ids = converters.IngestHotlistRefs(mc.cnxn, self.services.user, self.services.features, request.hotlist_refs) issue_ids = converters.IngestIssueRefs(mc.cnxn, request.issue_refs, self.services) with work_env.WorkEnv(mc, self.services) as we: mc.LookupLoggedInUserPerms(None) we.AddIssuesToHotlists(hotlist_ids, issue_ids, request.note) result = features_pb2.AddIssuesToHotlistsResponse() return result
def DeleteAttachment(self, mc, request): """Mark or unmark the given attachment as deleted.""" _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: comments = we.ListIssueComments(issue) if request.sequence_num >= len(comments): raise exceptions.InputException('Invalid sequence number.') we.DeleteAttachment(issue, comments[request.sequence_num], request.attachment_id, request.delete) result = issues_pb2.DeleteAttachmentResponse() return result
def CreateHotlist(self, mc, request): """Create a new hotlist.""" editor_ids = converters.IngestUserRefs(mc.cnxn, request.editor_refs, self.services.user) issue_ids = converters.IngestIssueRefs(mc.cnxn, request.issue_refs, self.services) with work_env.WorkEnv(mc, self.services) as we: we.CreateHotlist(request.name, request.summary, request.description, editor_ids, issue_ids, request.is_private) result = features_pb2.CreateHotlistResponse() return result
def ListProjectTemplates(self, mc, request): """Return the specific project's templates.""" if not request.project_name: raise exceptions.InputException('Param `project_name` required.') project = self._GetProject(mc, request) with work_env.WorkEnv(mc, self.services) as we: templates = we.ListProjectTemplates(project) with mc.profiler.Phase('converting to response objects'): response = projects_pb2.ListProjectTemplatesResponse( templates=converters.ConvertTemplates(templates)) return response
def testProcessSettingsForm_NewStylePrefs(self): """We can set prefs that are stored in the UserPrefs PB.""" user = self.services.user.TestAddUser('*****@*****.**', 111) post_data = {'restrict_new_issues': 1} with work_env.WorkEnv(self.mr, self.services) as we: framework_helpers.UserSettings.ProcessSettingsForm( we, post_data, user) userprefs = we.GetUserPrefs(111) actual = {upv.name: upv.value for upv in userprefs.prefs} expected = { 'restrict_new_issues': 'true', 'public_issue_notice': 'false', } self.assertEqual(expected, actual)
def StarIssue(self, mc, request): """Star (or unstar) the specified issue.""" _project, issue, _config = self._GetProjectIssueAndConfig( mc, request.issue_ref, use_cache=False) with work_env.WorkEnv(mc, self.services) as we: we.StarIssue(issue, request.starred) # Reload the issue to get the new star count. issue = we.GetIssue(issue.issue_id) with mc.profiler.Phase('converting to response objects'): response = issues_pb2.StarIssueResponse() response.star_count = issue.star_count return response
def GetMemberships(self, mc, request): """Return the user groups for the given user visible to the requester.""" user_id = converters.IngestUserRef(mc.cnxn, request.user_ref, self.services.user) with work_env.WorkEnv(mc, self.services) as we: group_ids = we.GetMemberships(user_id) with mc.profiler.Phase('converting to response objects'): groups_by_id = framework_views.MakeAllUserViews( mc.cnxn, self.services.user, group_ids) group_refs = converters.ConvertUserRefs(group_ids, [], groups_by_id, True) return users_pb2.GetMembershipsResponse(group_refs=group_refs)
def UpdateHotlistIssueNote(self, mc, request): """Update the note for the given issue in the given hotlist.""" hotlist_id = converters.IngestHotlistRef(mc.cnxn, self.services.user, self.services.features, request.hotlist_ref) issue_id = converters.IngestIssueRefs(mc.cnxn, [request.issue_ref], self.services)[0] with work_env.WorkEnv(mc, self.services) as we: project = we.GetProjectByName(request.issue_ref.project_name) mc.LookupLoggedInUserPerms(project) we.UpdateHotlistIssueNote(hotlist_id, issue_id, request.note) result = features_pb2.UpdateHotlistIssueNoteResponse() return result
def ListReferencedUsers(self, mc, request): """Return the list of existing users in a response proto.""" emails = request.emails if request.user_refs: emails = [user_ref.display_name for user_ref in request.user_refs] with work_env.WorkEnv(mc, self.services) as we: users, linked_user_ids = we.ListReferencedUsers(emails) linked_user_views = framework_views.MakeAllUserViews( mc.cnxn, self.services.user, linked_user_ids) with mc.profiler.Phase('converting to response objects'): response_users = converters.ConvertUsers(users, linked_user_views) response = users_pb2.ListReferencedUsersResponse(users=response_users) return response
def ListHotlistIssues(self, mc, request): """Get the issues on the specified hotlist.""" # TODO(ehmaldonado): This probably doesn't work, since we need to check # the permissions for each issue in their own project, and we're not doing # that. hotlist_id = converters.IngestHotlistRef(mc.cnxn, self.services.user, self.services.features, request.hotlist_ref) with work_env.WorkEnv(mc, self.services) as we: hotlist_items = we.GetHotlist(hotlist_id).items issue_ids = [item.issue_id for item in hotlist_items] issues = we.GetIssuesDict(issue_ids) projects = we.GetProjectsByName( [issue.project_name for issue in issues.values()]) configs = we.GetProjectConfigs( [project.project_id for project in projects.values()]) configs = { project.project_name: configs[project.project_id] for project in projects.values() } related_refs = we.GetRelatedIssueRefs(iter(issues.values())) with mc.profiler.Phase('making user views'): users_involved = set(item.adder_id for item in hotlist_items) users_involved.update( tracker_bizobj.UsersInvolvedInIssues(iter(issues.values()))) users_by_id = framework_views.MakeAllUserViews( mc.cnxn, self.services.user, users_involved) framework_views.RevealAllEmailsToMembers(mc.auth, None, users_by_id) hotlist_items = [ hotlist_item for hotlist_item in hotlist_items if hotlist_item.issue_id in issues ] start, max_items = converters.IngestPagination(request.pagination) pagination = paginate.ArtifactPagination(hotlist_items, max_items, start, None, None) result = features_pb2.ListHotlistIssuesResponse(items=[ converters.ConvertHotlistItem(hotlist_item, issues, users_by_id, related_refs, configs) for hotlist_item in pagination.visible_results ]) return result
def _GetIssueAndComment(self, mr): """Wait on retriving the specified issue and issue comment.""" if mr.seq is None: self.abort(404, 'comment not specified') with work_env.WorkEnv(mr, self.services) as we: issue = self.services.issue.GetIssueByLocalID( mr.cnxn, mr.project_id, mr.local_id) comments = we.ListIssueComments(issue) try: comment = comments[mr.seq] except IndexError: self.abort(404, 'comment not found') return issue, comment
def PredictComponent(self, mc, request): """Predict the component of an issue based on the given text.""" with work_env.WorkEnv(mc, self.services) as we: project = we.GetProjectByName(request.project_name) config = we.GetProjectConfig(project.project_id) component_ref = None component_id = component_helpers.PredictComponent(request.text, config) if component_id: component_ref = converters.ConvertComponentRef( component_id, config) result = features_pb2.PredictComponentResponse( component_ref=component_ref) return result
def setUp(self): self.cnxn = 'fake cnxn' self.services = service_manager.Services( config=fake.ConfigService(), issue=fake.IssueService(), user=fake.UserService(), project=fake.ProjectService(), issue_star=fake.IssueStarService(), spam=fake.SpamService()) self.services.project.TestAddProject('proj', project_id=789) self.mr = testing_helpers.MakeMonorailRequest() self.mr.auth.user_id = 111 self.mr.auth.effective_ids = {111} self.mr.me_user_id = 111 self.work_env = work_env.WorkEnv(self.mr, self.services, 'Testing phase')
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" page_data = { 'user_tab_mode': 'st3', 'logged_in_user_pb': template_helpers.PBProxy(mr.auth.user_pb), # When on /hosting/settings, the logged-in user is the viewed user. 'viewed_user': mr.auth.user_view, 'offer_saved_queries_subtab': ezt.boolean(True), 'viewing_self': ezt.boolean(True), } with work_env.WorkEnv(mr, self.services) as we: settings_user_prefs = we.GetUserPrefs(mr.auth.user_id) page_data.update( framework_helpers.UserSettings.GatherUnifiedSettingsPageData( mr.auth.user_id, mr.auth.user_view, mr.auth.user_pb, settings_user_prefs)) return page_data