blob: b7449354fc75e762583efcf8450741cf15c6af5b [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""A class to display the hosting home page."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11import logging
12import ezt
13
14import settings
15from businesslogic import work_env
16from framework import exceptions
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020017from framework import flaskservlet
Copybara854996b2021-09-07 19:36:02 +000018from framework import permissions
Copybara854996b2021-09-07 19:36:02 +000019from framework import urls
20from project import project_views
21from sitewide import projectsearch
Copybara854996b2021-09-07 19:36:02 +000022
23
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020024class HostingHome(flaskservlet.FlaskServlet):
Copybara854996b2021-09-07 19:36:02 +000025 """HostingHome shows the project list and link to create a project."""
26
27 _PAGE_TEMPLATE = 'sitewide/hosting-home-page.ezt'
28
29 def GatherPageData(self, mr):
30 """Build up a dictionary of data values to use when rendering the page.
31
32 Args:
33 mr: commonly used info parsed from the request.
34
35 Returns:
36 Dict of values used by EZT for rendering the page.
37 """
38 redirect_msg = self._MaybeRedirectToDomainDefaultProject(mr)
39 logging.info(redirect_msg)
40
41 can_create_project = permissions.CanCreateProject(mr.perms)
42
43 # Kick off the search pipeline, it has its own promises for parallelism.
44 pipeline = projectsearch.ProjectSearchPipeline(mr, self.services)
45
46 # Meanwhile, determine which projects the signed-in user has starred.
47 with work_env.WorkEnv(mr, self.services) as we:
48 starred_projects = we.ListStarredProjects()
49 starred_project_ids = {p.project_id for p in starred_projects}
50
51 # A dict of project id to the user's membership status.
52 project_memberships = {}
53 if mr.auth.user_id:
54 with work_env.WorkEnv(mr, self.services) as we:
55 owned, _archive_owned, member_of, contrib_of = (
56 we.GetUserProjects(mr.auth.effective_ids))
57 project_memberships.update({proj.project_id: 'Owner' for proj in owned})
58 project_memberships.update(
59 {proj.project_id: 'Member' for proj in member_of})
60 project_memberships.update(
61 {proj.project_id: 'Contributor' for proj in contrib_of})
62
63 # Finish the project search pipeline.
64 pipeline.SearchForIDs(domain=mr.request.host)
65 pipeline.GetProjectsAndPaginate(mr.cnxn, urls.HOSTING_HOME)
66 project_ids = [p.project_id for p in pipeline.visible_results]
67 star_count_dict = self.services.project_star.CountItemsStars(
68 mr.cnxn, project_ids)
69
70 # Make ProjectView objects
71 project_view_list = [
72 project_views.ProjectView(
73 p, starred=p.project_id in starred_project_ids,
74 num_stars=star_count_dict.get(p.project_id),
75 membership_desc=project_memberships.get(p.project_id))
76 for p in pipeline.visible_results]
77 return {
78 'can_create_project': ezt.boolean(can_create_project),
79 'learn_more_link': settings.learn_more_link,
80 'projects': project_view_list,
81 'pagination': pipeline.pagination,
82 }
83
84 def _MaybeRedirectToDomainDefaultProject(self, mr):
85 """If there is a relevant default project, redirect to it."""
86 project_name = settings.domain_to_default_project.get(mr.request.host)
87 if not project_name:
88 return 'No configured default project redirect for this domain.'
89
90 project = None
91 try:
92 project = self.services.project.GetProjectByName(mr.cnxn, project_name)
93 except exceptions.NoSuchProjectException:
94 pass
95
96 if not project:
97 return 'Domain default project %s not found' % project_name
98
99 if not permissions.UserCanViewProject(
100 mr.auth.user_pb, mr.auth.effective_ids, project):
101 return 'User cannot view default project: %r' % project
102
103 project_url = '/p/%s' % project_name
104 self.redirect(project_url, abort=True)
105 return 'Redirected to %r' % project_url
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200106
107 def GetOldHostingHome(self, **kwargs):
108 return self.handler(**kwargs)