Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/sitewide/hostinghome.py b/sitewide/hostinghome.py
new file mode 100644
index 0000000..4a0a47d
--- /dev/null
+++ b/sitewide/hostinghome.py
@@ -0,0 +1,107 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""A class to display the hosting home page."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import logging
+import ezt
+
+import settings
+from businesslogic import work_env
+from framework import exceptions
+from framework import permissions
+from framework import servlet
+from framework import template_helpers
+from framework import urls
+from project import project_views
+from sitewide import projectsearch
+from sitewide import sitewide_helpers
+
+
+class HostingHome(servlet.Servlet):
+ """HostingHome shows the project list and link to create a project."""
+
+ _PAGE_TEMPLATE = 'sitewide/hosting-home-page.ezt'
+
+ 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.
+ """
+ redirect_msg = self._MaybeRedirectToDomainDefaultProject(mr)
+ logging.info(redirect_msg)
+
+ can_create_project = permissions.CanCreateProject(mr.perms)
+
+ # Kick off the search pipeline, it has its own promises for parallelism.
+ pipeline = projectsearch.ProjectSearchPipeline(mr, self.services)
+
+ # Meanwhile, determine which projects the signed-in user has starred.
+ with work_env.WorkEnv(mr, self.services) as we:
+ starred_projects = we.ListStarredProjects()
+ starred_project_ids = {p.project_id for p in starred_projects}
+
+ # A dict of project id to the user's membership status.
+ project_memberships = {}
+ if mr.auth.user_id:
+ with work_env.WorkEnv(mr, self.services) as we:
+ owned, _archive_owned, member_of, contrib_of = (
+ we.GetUserProjects(mr.auth.effective_ids))
+ project_memberships.update({proj.project_id: 'Owner' for proj in owned})
+ project_memberships.update(
+ {proj.project_id: 'Member' for proj in member_of})
+ project_memberships.update(
+ {proj.project_id: 'Contributor' for proj in contrib_of})
+
+ # Finish the project search pipeline.
+ pipeline.SearchForIDs(domain=mr.request.host)
+ pipeline.GetProjectsAndPaginate(mr.cnxn, urls.HOSTING_HOME)
+ project_ids = [p.project_id for p in pipeline.visible_results]
+ star_count_dict = self.services.project_star.CountItemsStars(
+ mr.cnxn, project_ids)
+
+ # Make ProjectView objects
+ project_view_list = [
+ project_views.ProjectView(
+ p, starred=p.project_id in starred_project_ids,
+ num_stars=star_count_dict.get(p.project_id),
+ membership_desc=project_memberships.get(p.project_id))
+ for p in pipeline.visible_results]
+ return {
+ 'can_create_project': ezt.boolean(can_create_project),
+ 'learn_more_link': settings.learn_more_link,
+ 'projects': project_view_list,
+ 'pagination': pipeline.pagination,
+ }
+
+ def _MaybeRedirectToDomainDefaultProject(self, mr):
+ """If there is a relevant default project, redirect to it."""
+ project_name = settings.domain_to_default_project.get(mr.request.host)
+ if not project_name:
+ return 'No configured default project redirect for this domain.'
+
+ project = None
+ try:
+ project = self.services.project.GetProjectByName(mr.cnxn, project_name)
+ except exceptions.NoSuchProjectException:
+ pass
+
+ if not project:
+ return 'Domain default project %s not found' % project_name
+
+ if not permissions.UserCanViewProject(
+ mr.auth.user_pb, mr.auth.effective_ids, project):
+ return 'User cannot view default project: %r' % project
+
+ project_url = '/p/%s' % project_name
+ self.redirect(project_url, abort=True)
+ return 'Redirected to %r' % project_url