def testGetURLOfHotlist(self): cnxn = 'fake cnxn' user = self.services.user.TestAddUser('*****@*****.**', 432) user.obscure_email = False hotlist1 = self.services.features.TestAddHotlist('hotlist1', hotlist_id=123, owner_ids=[432]) url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist1, self.services.user) self.assertEqual('/u/[email protected]/hotlists/hotlist1', url) url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist1, self.services.user, url_for_token=True) self.assertEqual('/u/432/hotlists/hotlist1', url) user.obscure_email = True url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist1, self.services.user) self.assertEqual('/u/432/hotlists/hotlist1', url) # Test that a Hotlist without an owner has an empty URL. hotlist_unowned = self.services.features.TestAddHotlist('hotlist2', hotlist_id=234, owner_ids=[]) url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist_unowned, self.services.user) self.assertFalse(url)
def ProcessChangeOwnership(self, mr, post_data): new_owner_id_set = project_helpers.ParseUsernames( mr.cnxn, self.services.user, post_data.get('changeowners')) remain_as_editor = post_data.get('becomeeditor') == 'on' if len(new_owner_id_set) != 1: mr.errors.transfer_ownership = ( 'Please add one valid user email.') else: new_owner_id = new_owner_id_set.pop() if self.services.features.LookupHotlistIDs( mr.cnxn, [mr.hotlist.name], [new_owner_id]): mr.errors.transfer_ownership = ( 'This user already owns a hotlist with the same name') if mr.errors.AnyErrors(): self.PleaseCorrect( mr, initial_new_owner_username=post_data.get('changeowners'), open_dialog=ezt.boolean(True)) else: old_and_new_owner_ids = [new_owner_id] + mr.hotlist.owner_ids (_, editor_ids, follower_ids) = hotlist_helpers.MembersWithoutGivenIDs( mr.hotlist, old_and_new_owner_ids) if remain_as_editor and mr.hotlist.owner_ids: editor_ids.append(mr.hotlist.owner_ids[0]) self.services.features.UpdateHotlistRoles( mr.cnxn, mr.hotlist_id, [new_owner_id], editor_ids, follower_ids) hotlist = self.services.features.GetHotlist(mr.cnxn, mr.hotlist_id) hotlist_url = hotlist_helpers.GetURLOfHotlist( mr.cnxn, hotlist, self.services.user) return framework_helpers.FormatAbsoluteURL( mr,'%s%s' % (hotlist_url, urls.HOTLIST_PEOPLE), saved=1, ts=int(time.time()), include_project=False)
def _ComputeBackToListURL(mr, issue, config, hotlist, services): """Construct a URL to return the user to the place that they came from.""" if hotlist: back_to_list_url = hotlist_helpers.GetURLOfHotlist( mr.cnxn, hotlist, services.user) else: back_to_list_url = tracker_helpers.FormatIssueListURL( mr, config, cursor='%s:%d' % (issue.project_name, issue.local_id)) return back_to_list_url
def _GatherHotlists(self, mr): """Return a dict of hotlist names the current user is involved in.""" with self.profiler.Phase('GetUserHotlists'): user_hotlists = self.services.features.GetHotlistsByUserID( mr.cnxn, mr.auth.user_id) user_starred_hids = self.services.hotlist_star.LookupStarredItemIDs( mr.cnxn, mr.auth.user_id) user_starred_hotlists, _ = self.services.features.GetHotlistsByID( mr.cnxn, user_starred_hids) recently_visited_hids = self.services.user.GetRecentlyVisitedHotlists( mr.cnxn, mr.auth.user_id) recently_visited_hotlists, _ = self.services.features.GetHotlistsByID( mr.cnxn, [hid for hid in recently_visited_hids]) hotlists_dict = { 'ownerof': [(h.name, hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user)) for h in user_hotlists if mr.auth.user_id in h.owner_ids], 'editorof': [(h.name, hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user)) for h in user_hotlists if mr.auth.user_id in h.editor_ids], 'starred_hotlists': [(h.name, hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user)) for h in user_starred_hotlists.values() if permissions.CanViewHotlist(mr.auth.effective_ids, h) and h not in user_hotlists], 'visited_hotlists': [(recently_visited_hotlists[hid].name, hotlist_helpers.GetURLOfHotlist(mr.cnxn, recently_visited_hotlists[hid], self.services.user)) for hid in recently_visited_hids if recently_visited_hotlists[hid] not in user_hotlists and hid not in user_starred_hids], 'user': mr.auth.email } return hotlists_dict
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" if mr.auth.user_id: self.services.user.AddVisitedHotlist( mr.cnxn, mr.auth.user_id, mr.hotlist_id) all_members = (mr.hotlist.owner_ids + mr.hotlist.editor_ids + mr.hotlist.follower_ids) hotlist_url = hotlist_helpers.GetURLOfHotlist( mr.cnxn, mr.hotlist, self.services.user) with self.profiler.Phase('gathering members on this page'): users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, all_members) framework_views.RevealAllEmailsToMembers(mr, users_by_id) untrusted_user_group_proxies = [] # TODO(jojwang): implement FindUntrustedGroups() with self.profiler.Phase('making member views'): owner_views = self._MakeMemberViews(mr, mr.hotlist.owner_ids, users_by_id) editor_views = self._MakeMemberViews(mr, mr.hotlist.editor_ids, users_by_id) follower_views = self._MakeMemberViews(mr, mr.hotlist.follower_ids, users_by_id) all_member_views = owner_views + editor_views + follower_views pagination = paginate.ArtifactPagination( mr, all_member_views, MEMBERS_PER_PAGE,'%s%s' % ( hotlist_url, urls.HOTLIST_PEOPLE)) offer_membership_editing = permissions.CanAdministerHotlist( mr.auth.effective_ids, mr.hotlist) newly_added_views = [mv for mv in all_member_views if str(mv.user.user_id) in mr.GetParam('new', [])] return { 'is_hotlist': ezt.boolean(True), 'untrusted_user_groups': untrusted_user_group_proxies, 'pagination': pagination, 'initial_add_members': '', 'subtab_mode': None, 'initially_expand_form': ezt.boolean(False), 'newly_added_views': newly_added_views, 'offer_membership_editing': ezt.boolean(offer_membership_editing), 'total_num_owners': len(mr.hotlist.owner_ids), 'check_abandonment': ezt.boolean(True), 'initial_new_owner_username': '', 'placeholder': 'new-owner-username', 'open_dialog': ezt.boolean(False), 'viewing_user_page': ezt.boolean(True), }
def GetTableViewData(self, mr): """EZT template values to render a Table View of issues. Args: mr: commonly used info parsed from the request. Returns: Dictionary of page data for rendering of the Table View. """ table_data, table_related_dict = hotlist_helpers.CreateHotlistTableData( mr, mr.hotlist.items, self.services) columns = mr.col_spec.split() ordered_columns = [ template_helpers.EZTItem(col_index=i, name=col) for i, col in enumerate(columns) ] table_view_data = { 'table_data': table_data, 'panels': [template_helpers.EZTItem(ordered_columns=ordered_columns)], 'cursor': mr.cursor or mr.preview, 'preview': mr.preview, 'default_colspec': features_constants.DEFAULT_COL_SPEC, 'default_results_per_page': 10, 'preview_on_hover': (settings.enable_quick_edit and mr.auth.user_pb.preview_on_hover), # token must be generated using url with userid to accommodate # multiple urls for one hotlist 'edit_hotlist_token': xsrf.GenerateToken( mr.auth.user_id, hotlist_helpers.GetURLOfHotlist(mr.cnxn, mr.hotlist, self.services.user, url_for_token=True) + '.do'), 'add_local_ids': '', 'placeholder': _INITIAL_ADD_ISSUES_MESSAGE, 'add_issues_selected': ezt.boolean(False), 'col_spec': '' } table_view_data.update(table_related_dict) return table_view_data
def ProcessFormData(self, mr, post_data): """Process the posted form.""" permit_edit = permissions.CanAdministerHotlist( mr.auth.effective_ids, mr.hotlist) if not permit_edit: raise permissions.PermissionException( 'User is not permitted to edit hotlist membership') hotlist_url = hotlist_helpers.GetURLOfHotlist( mr.cnxn, mr.hotlist, self.services.user) if 'addbtn' in post_data: return self.ProcessAddMembers(mr, post_data, hotlist_url) elif 'removebtn' in post_data: return self.ProcessRemoveMembers(mr, post_data, hotlist_url) elif 'changeowners' in post_data: return self.ProcessChangeOwnership(mr, post_data)
def ProcessFormData(self, mr, post_data): if post_data.get('deletestate') == 'true': hotlist_helpers.RemoveHotlist(mr.cnxn, mr.hotlist_id, self.services) return framework_helpers.FormatAbsoluteURL(mr, '/u/%s/hotlists' % mr.auth.email, saved=1, ts=int(time.time()), include_project=False) hotlist_view_url = hotlist_helpers.GetURLOfHotlist( mr.cnxn, mr.hotlist, self.services.user) current_col_spec = post_data.get('current_col_spec') default_url = framework_helpers.FormatAbsoluteURL( mr, hotlist_view_url, include_project=False, colspec=current_col_spec) sorting.InvalidateArtValuesKeys( mr.cnxn, [hotlist_item.issue_id for hotlist_item in mr.hotlist.items]) if post_data.get('remove') == 'true': project_and_local_ids = post_data.get('remove_local_ids') else: project_and_local_ids = post_data.get('add_local_ids') if not project_and_local_ids: return default_url selected_iids = [] if project_and_local_ids: pattern = re.compile(features_constants.ISSUE_INPUT_REGEX) if pattern.match(project_and_local_ids): issue_refs_tuples = [ (pair.split(':')[0].strip(), int(pair.split(':')[1].strip())) for pair in project_and_local_ids.split(',') if pair.strip() ] project_names = { project_name for (project_name, _) in issue_refs_tuples } projects_dict = self.services.project.GetProjectsByName( mr.cnxn, project_names) selected_iids, _misses = self.services.issue.ResolveIssueRefs( mr.cnxn, projects_dict, mr.project_name, issue_refs_tuples) if (not selected_iids ) or len(issue_refs_tuples) > len(selected_iids): mr.errors.issues = _MSG_ISSUES_NOT_FOUND # TODO(jojwang): give issues that were not found. else: mr.errors.issues = _MSG_INVALID_ISSUES_INPUT try: with work_env.WorkEnv(mr, self.services) as we: selected_issues = we.GetIssuesDict(selected_iids) except exceptions.NoSuchIssueException: mr.errors.issues = _MSG_ISSUES_NOT_FOUND if len(selected_issues) < len(selected_iids): mr.errors.issues = _MSG_ISSUES_NOT_VIEWABLE # TODO(jojwang): fix: when there are errors, hidden column come back on # the .do page but go away once the errors are fixed and the form # is submitted again if mr.errors.AnyErrors(): self.PleaseCorrect(mr, add_local_ids=project_and_local_ids, add_issues_selected=ezt.boolean(True), col_spec=current_col_spec) else: with work_env.WorkEnv(mr, self.services) as we: if post_data.get('remove') == 'true': we.RemoveIssuesFromHotlists([mr.hotlist_id], selected_iids) else: we.AddIssuesToHotlists([mr.hotlist_id], selected_iids, '') return framework_helpers.FormatAbsoluteURL( mr, hotlist_view_url, saved=1, ts=int(time.time()), include_project=False, colspec=current_col_spec)
def ProcessFormData(self, mr, post_data): """Process the hotlist create form. Args: mr: commonly used info parsed from the request. post_data: The post_data dict for the current request. Returns: String URL to redirect the user to after processing. """ hotlist_name = post_data.get('hotlistname') if not hotlist_name: mr.errors.hotlistname = _MSG_MISSING_HOTLIST_NAME elif not framework_bizobj.IsValidHotlistName(hotlist_name): mr.errors.hotlistname = _MSG_INVALID_HOTLIST_NAME summary = post_data.get('summary') if not summary: mr.errors.summary = _MSG_MISSING_HOTLIST_SUMMARY description = post_data.get('description', '') editors = post_data.get('editors', '') editor_ids = [] if editors: editor_emails = [email.strip() for email in editors.split(',')] try: editor_dict = self.services.user.LookupUserIDs( mr.cnxn, editor_emails) editor_ids = editor_dict.values() except user_svc.NoSuchUserException: mr.errors.editors = _MSG_INVALID_MEMBERS_INPUT # In case the logged-in user specifies themselves as an editor, ignore it. editor_ids = [eid for eid in editor_ids if eid != mr.auth.user_id] is_private = post_data.get('is_private') if not mr.errors.AnyErrors(): try: hotlist = self.services.features.CreateHotlist( mr.cnxn, hotlist_name, summary, description, owner_ids=[mr.auth.user_id], editor_ids=editor_ids, is_private=(is_private == 'yes'), ts=int(time.time())) except features_svc.HotlistAlreadyExists: mr.errors.hotlistname = _MSG_HOTLIST_NAME_NOT_AVAIL if mr.errors.AnyErrors(): self.PleaseCorrect(mr, initial_name=hotlist_name, initial_summary=summary, initial_description=description, initial_editors=editors, initial_privacy=is_private) else: return framework_helpers.FormatAbsoluteURL( mr, hotlist_helpers.GetURLOfHotlist(mr.cnxn, hotlist, self.services.user), include_project=False)
def HandleRequest(self, mr): project_names = [] refs = [] for issue_ref in mr.issue_refs: issue_split = issue_ref.split(':') project_names.append(issue_split[0]) refs.append((issue_split[0], int(issue_split[1]))) ref_projects = self.services.project.GetProjectsByName( mr.cnxn, project_names) # TODO(jojwang): a default_project_name can be passed in for adding an issue # via the issuedetail page default_project_name = '' selected_iids, misses = self.services.issue.ResolveIssueRefs( mr.cnxn, ref_projects, default_project_name, refs) added_tuples = [(issue_id, mr.auth.user_id, int(time.time()), '') for issue_id in selected_iids] if not mr.hotlist_ids: hotlist_name = 'Hotlist-1' count = 1 taken_names = [ h.name for h in self.services.features.GetHotlistsByUserID( mr.cnxn, mr.auth.user_id) ] while hotlist_name in taken_names: count += 1 hotlist_name = 'Hotlist-%d' % count hotlist = self.services.features.CreateHotlist( mr.cnxn, hotlist_name, 'Hotlist of bulk added issues', '', [mr.auth.user_id], [], issue_ids=selected_iids) hotlist_ids = [hotlist.hotlist_id] else: hotlist_ids = mr.hotlist_ids self.services.features.AddIssuesToHotlists(mr.cnxn, hotlist_ids, added_tuples) missed = [] for miss in misses: project_name = self.services.project.GetProject( mr.cnxn, miss[0]).project_name missed.append(('%s:%d' % (project_name, miss[1]))) added_hotlist_pbs = [ self.services.features.GetHotlist(mr.cnxn, hotlist_id) for hotlist_id in hotlist_ids ] user_issue_hotlists = list( set( self.services.features.GetHotlistsByUserID( mr.cnxn, mr.auth.user_id)) & set( self.services.features.GetHotlistsByIssueID( mr.cnxn, selected_iids[0]))) all_hotlist_urls = [ hotlist_helpers.GetURLOfHotlist(mr.cnxn, hotlist, self.services.user) for hotlist in user_issue_hotlists ] all_hotlist_names = [hotlist.name for hotlist in user_issue_hotlists] return { 'addedHotlistIDs': hotlist_ids, # hotlist_ids issues were added to or new hotlist's id 'missed': missed, # missed issues 'addedHotlistNames': [h.name for h in added_hotlist_pbs], # hotlist names issues were added to or new hotlist's name 'allHotlistNames': all_hotlist_names, # user's hotlists' names 'allHotlistUrls': all_hotlist_urls } # user's hotlists' urls