def TestSecsAgo(secs_ago, expected, expected_days_only): test_time = now - secs_ago actual = timestr.FormatRelativeDate(test_time, clock=lambda: now) self.assertEquals(actual, expected) actual_days_only = timestr.FormatRelativeDate(test_time, clock=lambda: now, days_only=True) self.assertEquals(actual_days_only, expected_days_only)
def __init__(self, timestamp, days_only=False): values = [] if timestamp: date_str = timestr.FormatRelativeDate(timestamp, days_only=days_only) if not date_str: date_str = timestr.FormatAbsoluteDate(timestamp) values = [date_str] TableCell.__init__(self, CELL_TYPE_UNFILTERABLE, values)
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" viewed_user = mr.viewed_user_auth.user_pb if viewed_user.email_bounce_timestamp: last_bounce_str = timestr.FormatRelativeDate( viewed_user.email_bounce_timestamp, days_only=True) last_bounce_str = last_bounce_str or 'Less than 2 days ago' else: last_bounce_str = None page_data = { 'user_tab_mode': 'st2', 'last_bounce_str': last_bounce_str, } return page_data
def GetUserAvailability(user, is_group=False): """Return (str, str) that explains why the user might not be available.""" if not user.user_id: return None, None if user.banned: return 'Banned', 'banned' if user.vacation_message: return user.vacation_message, 'none' if user.email_bounce_timestamp: return 'Email to this user bounced', 'none' # No availability shown for user groups, or addresses that are # likely to be mailing lists. if is_group or (user.email and '-' in user.email): return None, None if not user.last_visit_timestamp: return 'User never visited', 'never' secs_ago = int(time.time()) - user.last_visit_timestamp last_visit_str = timestr.FormatRelativeDate(user.last_visit_timestamp, days_only=True) if secs_ago > 30 * framework_constants.SECS_PER_DAY: return 'Last visit > 30 days ago', 'none' if secs_ago > 15 * framework_constants.SECS_PER_DAY: return ('Last visit %s' % last_visit_str), 'unsure' return None, None
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" viewed_user = mr.viewed_user_auth.user_pb if self.services.usergroup.GetGroupSettings( mr.cnxn, mr.viewed_user_auth.user_id): url = framework_helpers.FormatAbsoluteURL(mr, '/g/%s/' % viewed_user.email, include_project=False) self.redirect(url, abort=True) # Show group page instead. with work_env.WorkEnv(mr, self.services) as we: project_lists = we.GetUserProjects( mr.viewed_user_auth.effective_ids) (visible_ownership, visible_archived, visible_membership, visible_contrib) = project_lists with mr.profiler.Phase('Getting user groups'): group_settings = self.services.usergroup.GetAllGroupSettings( mr.cnxn, mr.viewed_user_auth.effective_ids) member_ids, owner_ids = self.services.usergroup.LookupAllMembers( mr.cnxn, list(group_settings.keys())) friend_project_ids = [] # TODO(issue 4202): implement this. visible_group_ids = [] for group_id in group_settings: if permissions.CanViewGroupMembers(mr.perms, mr.auth.effective_ids, group_settings[group_id], member_ids[group_id], owner_ids[group_id], friend_project_ids): visible_group_ids.append(group_id) user_group_views = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, visible_group_ids) user_group_views = sorted(list(user_group_views.values()), key=lambda ugv: ugv.email) with mr.profiler.Phase('Getting linked accounts'): linked_parent = None linked_children = [] linked_views = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, [viewed_user.linked_parent_id], viewed_user.linked_child_ids) if viewed_user.linked_parent_id: linked_parent = linked_views[viewed_user.linked_parent_id] if viewed_user.linked_child_ids: linked_children = [ linked_views[child_id] for child_id in viewed_user.linked_child_ids ] offer_unlink = (mr.auth.user_id == viewed_user.user_id or mr.auth.user_id in linked_views) incoming_invite_users = [] outgoing_invite_users = [] possible_parent_accounts = [] can_edit_invites = mr.auth.user_id == mr.viewed_user_auth.user_id display_link_invites = can_edit_invites or mr.auth.user_pb.is_site_admin # TODO(jrobbins): allow site admin to edit invites for other users. if display_link_invites: with work_env.WorkEnv(mr, self.services, phase='Getting link invites'): incoming_invite_ids, outgoing_invite_ids = we.GetPendingLinkedInvites( user_id=viewed_user.user_id) invite_views = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, incoming_invite_ids, outgoing_invite_ids) incoming_invite_users = [ invite_views[uid] for uid in incoming_invite_ids ] outgoing_invite_users = [ invite_views[uid] for uid in outgoing_invite_ids ] possible_parent_accounts = _ComputePossibleParentAccounts( we, mr.viewed_user_auth.user_view, linked_parent, linked_children) viewed_user_display_name = framework_views.GetViewedUserDisplayName(mr) with work_env.WorkEnv(mr, self.services) as we: starred_projects = we.ListStarredProjects( viewed_user_id=mr.viewed_user_auth.user_id) logged_in_starred = we.ListStarredProjects() logged_in_starred_pids = {p.project_id for p in logged_in_starred} starred_user_ids = self.services.user_star.LookupStarredItemIDs( mr.cnxn, mr.viewed_user_auth.user_id) starred_user_dict = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, starred_user_ids) starred_users = list(starred_user_dict.values()) starred_users_json = json.dumps( [uv.display_name for uv in starred_users]) is_user_starred = self._IsUserStarred(mr.cnxn, mr.auth.user_id, mr.viewed_user_auth.user_id) if viewed_user.last_visit_timestamp: last_visit_str = timestr.FormatRelativeDate( viewed_user.last_visit_timestamp, days_only=True) last_visit_str = last_visit_str or 'Less than 2 days ago' else: last_visit_str = 'Never' if viewed_user.email_bounce_timestamp: last_bounce_str = timestr.FormatRelativeDate( viewed_user.email_bounce_timestamp, days_only=True) last_bounce_str = last_bounce_str or 'Less than 2 days ago' else: last_bounce_str = None can_ban = permissions.CanBan(mr, self.services) viewed_user_is_spammer = viewed_user.banned.lower() == 'spam' viewed_user_may_be_spammer = not viewed_user_is_spammer all_projects = self.services.project.GetAllProjects(mr.cnxn) for project_id in all_projects: project = all_projects[project_id] viewed_user_perms = permissions.GetPermissions( viewed_user, mr.viewed_user_auth.effective_ids, project) if (viewed_user_perms != permissions.EMPTY_PERMISSIONSET and viewed_user_perms != permissions.USER_PERMISSIONSET): viewed_user_may_be_spammer = False ban_token = None ban_spammer_token = None if mr.auth.user_id and can_ban: form_token_path = mr.request.path + 'ban.do' ban_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path) form_token_path = mr.request.path + 'banSpammer.do' ban_spammer_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path) page_data = { 'user_tab_mode': 'st2', 'viewed_user_display_name': viewed_user_display_name, 'viewed_user_may_be_spammer': ezt.boolean(viewed_user_may_be_spammer), 'viewed_user_is_spammer': ezt.boolean(viewed_user_is_spammer), 'viewed_user_is_banned': ezt.boolean(viewed_user.banned), 'owner_of_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_ownership ], 'committer_of_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_membership ], 'contributor_to_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_contrib ], 'owner_of_archived_projects': [project_views.ProjectView(p) for p in visible_archived], 'starred_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in starred_projects ], 'starred_users': starred_users, 'starred_users_json': starred_users_json, 'is_user_starred': ezt.boolean(is_user_starred), 'viewing_user_page': ezt.boolean(True), 'last_visit_str': last_visit_str, 'last_bounce_str': last_bounce_str, 'vacation_message': viewed_user.vacation_message, 'can_ban': ezt.boolean(can_ban), 'ban_token': ban_token, 'ban_spammer_token': ban_spammer_token, 'user_groups': user_group_views, 'linked_parent': linked_parent, 'linked_children': linked_children, 'incoming_invite_users': incoming_invite_users, 'outgoing_invite_users': outgoing_invite_users, 'possible_parent_accounts': possible_parent_accounts, 'can_edit_invites': ezt.boolean(can_edit_invites), 'offer_unlink': ezt.boolean(offer_unlink), } viewed_user_prefs = None if mr.perms.HasPerm(permissions.EDIT_OTHER_USERS, None, None): with work_env.WorkEnv(mr, self.services) as we: viewed_user_prefs = we.GetUserPrefs( mr.viewed_user_auth.user_id) user_settings = ( framework_helpers.UserSettings.GatherUnifiedSettingsPageData( mr.auth.user_id, mr.viewed_user_auth.user_view, viewed_user, viewed_user_prefs)) page_data.update(user_settings) return page_data
def GetGridViewData(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. """ mr.ComputeColSpec(mr.hotlist) starred_iid_set = set( self.services.issue_star.LookupStarredItemIDs( mr.cnxn, mr.auth.user_id)) issues_list = self.services.issue.GetIssues( mr.cnxn, [hotlist_issue.issue_id for hotlist_issue in mr.hotlist.items]) allowed_issues = hotlist_helpers.FilterIssues(mr, issues_list, self.services) issue_and_hotlist_users = tracker_bizobj.UsersInvolvedInIssues( allowed_issues or []).union(features_bizobj.UsersInvolvedInHotlists([mr.hotlist])) users_by_id = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, issue_and_hotlist_users) hotlist_issues_project_ids = hotlist_helpers.GetAllProjectsOfIssues( [issue for issue in issues_list]) config_list = hotlist_helpers.GetAllConfigsOfProjects( mr.cnxn, hotlist_issues_project_ids, self.services) harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list) limit = settings.max_issues_in_grid grid_limited = len(allowed_issues) > limit lower_cols = mr.col_spec.lower().split() grid_x = (mr.x or harmonized_config.default_x_attr or '--').lower() grid_y = (mr.y or harmonized_config.default_y_attr or '--').lower() lower_cols.append(grid_x) lower_cols.append(grid_y) related_iids = set() for issue in allowed_issues: if 'blockedon' in lower_cols: related_iids.update(issue.blocked_on_iids) if 'blocking' in lower_cols: related_iids.update(issue.blocking_iids) if 'mergedinto' in lower_cols: related_iids.add(issue.merged_into) related_issues_list = self.services.issue.GetIssues( mr.cnxn, list(related_iids)) related_issues = { issue.issue_id: issue for issue in related_issues_list } hotlist_context_dict = { hotlist_issue.issue_id: { 'adder_id': hotlist_issue.adder_id, 'date_added': timestr.FormatRelativeDate(hotlist_issue.date_added), 'note': hotlist_issue.note } for hotlist_issue in mr.hotlist.items } grid_view_data = grid_view_helpers.GetGridViewData( mr, allowed_issues, harmonized_config, users_by_id, starred_iid_set, grid_limited, related_issues, hotlist_context_dict=hotlist_context_dict) url_params = [(name, mr.GetParam(name)) for name in framework_helpers.RECOGNIZED_PARAMS] # We are passing in None for the project_name in ArtifactPagination # because we are not operating under any project. grid_view_data.update({ 'pagination': paginate.ArtifactPagination( allowed_issues, mr.GetPositiveIntParam( 'num', features_constants.DEFAULT_RESULTS_PER_PAGE), mr.GetPositiveIntParam('start'), None, urls.HOTLIST_ISSUES, total_count=len(allowed_issues), url_params=url_params) }) return grid_view_data
def __init__(self, project_name, comment_pb, users_by_id, autolink, all_referenced_artifacts, mr, issue, effective_ids=None): """Get IssueComment PB and make its fields available as attrs. Args: project_name: Name of the project this issue belongs to. comment_pb: Comment protocol buffer. users_by_id: dict mapping user_ids to UserViews, including the user that entered the comment, and any changed participants. autolink: utility object for automatically linking to other issues, git revisions, etc. all_referenced_artifacts: opaque object with details of referenced artifacts that is needed by autolink. mr: common information parsed from the HTTP request. issue: Issue PB for the issue that this comment is part of. effective_ids: optional set of int user IDs for the comment author. """ super(IssueCommentView, self).__init__(comment_pb) self.id = comment_pb.id self.creator = users_by_id[comment_pb.user_id] # TODO(jrobbins): this should be based on the issue project, not the # request project for non-project views and cross-project. if mr.project: self.creator_role = framework_helpers.GetRoleName( effective_ids or {self.creator.user_id}, mr.project) else: self.creator_role = None time_tuple = time.localtime(comment_pb.timestamp) self.date_string = timestr.FormatAbsoluteDate( comment_pb.timestamp, old_format=timestr.MONTH_DAY_YEAR_FMT) self.date_relative = timestr.FormatRelativeDate(comment_pb.timestamp) self.date_tooltip = time.asctime(time_tuple) self.date_yyyymmdd = timestr.FormatAbsoluteDate( comment_pb.timestamp, recent_format=timestr.MONTH_DAY_YEAR_FMT, old_format=timestr.MONTH_DAY_YEAR_FMT) self.text_runs = _ParseTextRuns(comment_pb.content) if autolink and not comment_pb.deleted_by: self.text_runs = autolink.MarkupAutolinks( mr, self.text_runs, all_referenced_artifacts) self.attachments = [ AttachmentView(attachment, project_name) for attachment in comment_pb.attachments ] self.amendments = sorted( [ AmendmentView(amendment, users_by_id, mr.project_name) for amendment in comment_pb.amendments ], key=lambda amendment: amendment.field_name.lower()) # Treat comments from banned users as being deleted. self.is_deleted = (comment_pb.deleted_by or (self.creator and self.creator.banned)) self.can_delete = False # TODO(jrobbins): pass through config to get granted permissions. perms = permissions.UpdateIssuePermissions(mr.perms, mr.project, issue, mr.auth.effective_ids) if mr.auth.user_id and mr.project: self.can_delete = permissions.CanDeleteComment( comment_pb, self.creator, mr.auth.user_id, perms) self.visible = permissions.CanViewComment(comment_pb, self.creator, mr.auth.user_id, perms)
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" viewed_user = mr.viewed_user_auth.user_pb if self.services.usergroup.GetGroupSettings( mr.cnxn, mr.viewed_user_auth.user_id): url = framework_helpers.FormatAbsoluteURL(mr, '/g/%s/' % viewed_user.email, include_project=False) self.redirect(url, abort=True) # Show group page instead. with self.profiler.Phase('GetUserProjects'): project_lists = sitewide_helpers.GetUserProjects( mr.cnxn, self.services, mr.auth.user_pb, mr.auth.effective_ids, mr.viewed_user_auth.effective_ids) (visible_ownership, visible_archived, visible_membership, visible_contrib) = project_lists viewed_user_display_name = framework_views.GetViewedUserDisplayName(mr) with self.profiler.Phase('GetStarredProjects'): starred_projects = sitewide_helpers.GetViewableStarredProjects( mr.cnxn, self.services, mr.viewed_user_auth.user_id, mr.auth.effective_ids, mr.auth.user_pb) logged_in_starred_pids = [] if mr.auth.user_id: logged_in_starred_pids = self.services.project_star.LookupStarredItemIDs( mr.cnxn, mr.auth.user_id) starred_user_ids = self.services.user_star.LookupStarredItemIDs( mr.cnxn, mr.viewed_user_auth.user_id) starred_user_dict = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, starred_user_ids) starred_users = starred_user_dict.values() is_user_starred = self._IsUserStarred(mr.cnxn, mr.auth.user_id, mr.viewed_user_auth.user_id) if viewed_user.last_visit_timestamp: last_visit_str = timestr.FormatRelativeDate( viewed_user.last_visit_timestamp, days_only=True) last_visit_str = last_visit_str or 'Less than 2 days ago' else: last_visit_str = 'Never' if viewed_user.email_bounce_timestamp: last_bounce_str = timestr.FormatRelativeDate( viewed_user.email_bounce_timestamp, days_only=True) last_bounce_str = last_bounce_str or 'Less than 2 days ago' else: last_bounce_str = None can_ban = permissions.CanBan(mr, self.services) viewed_user_is_spammer = viewed_user.banned.lower() == 'spam' viewed_user_may_be_spammer = not viewed_user_is_spammer all_projects = self.services.project.GetAllProjects(mr.cnxn) for project_id in all_projects: project = all_projects[project_id] viewed_user_perms = permissions.GetPermissions( viewed_user, mr.viewed_user_auth.effective_ids, project) if (viewed_user_perms != permissions.EMPTY_PERMISSIONSET and viewed_user_perms != permissions.USER_PERMISSIONSET): viewed_user_may_be_spammer = False ban_token = None ban_spammer_token = None if mr.auth.user_id and can_ban: form_token_path = mr.request.path + 'ban.do' ban_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path) form_token_path = mr.request.path + 'banSpammer.do' ban_spammer_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path) page_data = { 'user_tab_mode': 'st2', 'viewed_user_display_name': viewed_user_display_name, 'viewed_user_may_be_spammer': ezt.boolean(viewed_user_may_be_spammer), 'viewed_user_is_spammer': ezt.boolean(viewed_user_is_spammer), 'viewed_user_is_banned': ezt.boolean(viewed_user.banned), 'viewed_user_ignore_action_limits': (ezt.boolean(viewed_user.ignore_action_limits)), 'owner_of_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_ownership ], 'committer_of_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_membership ], 'contributor_to_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in visible_contrib ], 'owner_of_archived_projects': [project_views.ProjectView(p) for p in visible_archived], 'starred_projects': [ project_views.ProjectView(p, starred=p.project_id in logged_in_starred_pids) for p in starred_projects ], 'starred_users': starred_users, 'is_user_starred': ezt.boolean(is_user_starred), 'viewing_user_page': ezt.boolean(True), 'last_visit_str': last_visit_str, 'last_bounce_str': last_bounce_str, 'vacation_message': viewed_user.vacation_message, 'can_ban': ezt.boolean(can_ban), 'ban_token': ban_token, 'ban_spammer_token': ban_spammer_token } settings = framework_helpers.UserSettings.GatherUnifiedSettingsPageData( mr.auth.user_id, mr.viewed_user_auth.user_view, viewed_user) page_data.update(settings) return page_data