Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2493)

Unified Diff: appengine/monorail/registerpages.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/monorail/queue.yaml ('k') | appengine/monorail/search/__init__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/monorail/registerpages.py
diff --git a/appengine/monorail/registerpages.py b/appengine/monorail/registerpages.py
new file mode 100644
index 0000000000000000000000000000000000000000..1fba7d91d5737768aa7245f1d9cdadbd9758cc23
--- /dev/null
+++ b/appengine/monorail/registerpages.py
@@ -0,0 +1,336 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""This file sets up all the urls for monorail pages."""
+
+import logging
+
+import webapp2
+
+import settings
+
+from features import autolink
+from features import cues
+from features import filterrules
+from features import inboundemail
+from features import notify
+from features import savedqueries
+from features import spammodel
+from features import stars
+
+from framework import artifactcollision
+from framework import banned
+from framework import csp_report
+from framework import excessiveactivity
+from framework import reap
+from framework import registerpages_helpers
+from framework import tokenrefresh
+from framework import urls
+
+from project import peopledetail
+from project import peoplelist
+from project import projectadmin
+from project import projectadminadvanced
+from project import projectexport
+from project import projectsummary
+from project import projectupdates
+from project import wikiredirect
+
+from search import backendnonviewable
+from search import backendsearch
+
+from services import cachemanager_svc
+
+from sitewide import custom_404
+from sitewide import groupadmin
+from sitewide import groupcreate
+from sitewide import groupdetail
+from sitewide import grouplist
+from sitewide import hostinghome
+from sitewide import moved
+from sitewide import projectcreate
+from sitewide import userprofile
+from sitewide import userprojects
+from sitewide import usersettings
+from sitewide import userupdates
+
+from tracker import componentcreate
+from tracker import componentdetail
+from tracker import fieldcreate
+from tracker import fielddetail
+from tracker import issueadmin
+from tracker import issueadvsearch
+from tracker import issueattachment
+from tracker import issueattachmenttext
+from tracker import issuebulkedit
+from tracker import issuedetail
+from tracker import issueentry
+from tracker import issuelist
+from tracker import issuelistcsv
+from tracker import issueoptions
+from tracker import issueoriginal
+from tracker import issueexport
+from tracker import issueimport
+from tracker import issuereindex
+from tracker import issuetips
+from tracker import spam
+
+
+class ServletRegistry(object):
+
+ _PROJECT_NAME_REGEX = r'[a-z0-9][-a-z0-9]*[a-z0-9]'
+ _USERNAME_REGEX = r'[-+\w=.%]+(@([a-z0-9]+\.)*[a-z0-9]+)?'
+
+ def __init__(self):
+ self.routes = []
+
+ def _AddRoute(self, path_regex, servlet_class, method, does_write=False):
+ """Add a GET or POST handler to our webapp2 route list.
+
+ Args:
+ path_regex: string with webapp2 URL template regex.
+ servlet_class: a subclass of class Servlet.
+ method: string 'GET' or 'POST'.
+ does_write: True if the servlet could write to the database, we skip
+ registering such servlets when the site is in read_only mode. GET
+ handlers never write. Most, but not all, POST handlers do write.
+ """
+ if settings.read_only and does_write:
+ logging.info('Not registring %r because site is read-only', path_regex)
+ # TODO(jrobbins): register a helpful error page instead.
+ else:
+ self.routes.append(
+ webapp2.Route(path_regex, handler=servlet_class, methods=[method]))
+
+ def _SetupServlets(self, spec_dict, base='', post_does_write=True):
+ """Register each of the given servlets."""
+ for get_uri, servlet_class in spec_dict.items():
+ self._AddRoute(base + get_uri, servlet_class, 'GET')
+ post_uri = get_uri + ('edit.do' if get_uri.endswith('/') else '.do')
+ self._AddRoute(base + post_uri, servlet_class, 'POST',
+ does_write=post_does_write)
+
+ def _SetupProjectServlets(self, spec_dict, post_does_write=True):
+ """Register each of the given servlets in the project URI space."""
+ self._SetupServlets(
+ spec_dict, base='/p/<project_name:%s>' % self._PROJECT_NAME_REGEX,
+ post_does_write=post_does_write)
+
+ def _SetupUserServlets(self, spec_dict, post_does_write=True):
+ """Register each of the given servlets in the user URI space."""
+ self._SetupServlets(
+ spec_dict, base='/u/<viewed_username:%s>' % self._USERNAME_REGEX,
+ post_does_write=post_does_write)
+
+ def _SetupGroupServlets(self, spec_dict, post_does_write=True):
+ """Register each of the given servlets in the user group URI space."""
+ self._SetupServlets(
+ spec_dict, base='/g/<viewed_username:%s>' % self._USERNAME_REGEX,
+ post_does_write=post_does_write)
+
+ def Register(self, services):
+ """Register all the monorail request handlers."""
+ self._RegisterFrameworkHandlers()
+ self._RegisterSitewideHandlers()
+ self._RegisterProjectHandlers()
+ self._RegisterIssueHandlers()
+ self._RegisterRedirects()
+ self._RegisterInboundMail()
+ autolink.RegisterAutolink(services)
+ # Error pages should be the last to register.
+ self._RegisterErrorPages()
+ logging.info('Finished registering monorail handlers.')
+ return self.routes
+
+ def _RegisterProjectHandlers(self):
+ """Register page and form handlers that operate within a project."""
+ self._SetupProjectServlets({
+ urls.ADMIN_INTRO: projectsummary.ProjectSummary,
+ urls.PEOPLE_LIST: peoplelist.PeopleList,
+ urls.PEOPLE_DETAIL: peopledetail.PeopleDetail,
+ urls.PEOPLE_DETAIL_PREFS_JSON: peopledetail.PagePrefs,
+ urls.UPDATES_LIST: projectupdates.ProjectUpdates,
+ urls.ADMIN_META: projectadmin.ProjectAdmin,
+ urls.ADMIN_ADVANCED: projectadminadvanced.ProjectAdminAdvanced,
+ urls.ADMIN_EXPORT: projectexport.ProjectExport,
+ urls.ADMIN_EXPORT_JSON: projectexport.ProjectExportJSON,
+ })
+
+ def _RegisterIssueHandlers(self):
+ """Register page and form handlers for the issue tracker."""
+ self._SetupServlets({
+ # Note: there is both a site-wide and per-project issue list.
+ urls.ISSUE_LIST: issuelist.IssueList,
+
+ # Note: the following are at URLs that are not externaly accessible.
+ urls.BACKEND_SEARCH: backendsearch.BackendSearch,
+ urls.BACKEND_NONVIEWABLE: backendnonviewable.BackendNonviewable,
+ urls.RECOMPUTE_DERIVED_FIELDS_TASK:
+ filterrules.RecomputeDerivedFieldsTask,
+ urls.REINDEX_QUEUE_CRON: filterrules.ReindexQueueCron,
+ urls.NOTIFY_ISSUE_CHANGE_TASK: notify.NotifyIssueChangeTask,
+ urls.NOTIFY_BLOCKING_CHANGE_TASK: notify.NotifyBlockingChangeTask,
+ urls.NOTIFY_BULK_CHANGE_TASK: notify.NotifyBulkChangeTask,
+ urls.OUTBOUND_EMAIL_TASK: notify.OutboundEmailTask,
+ urls.SPAM_DATA_EXPORT_TASK: spammodel.TrainingDataExportTask,
+ })
+
+ self._SetupProjectServlets({
+ urls.ISSUE_LIST: issuelist.IssueList,
+ urls.ISSUE_LIST_CSV: issuelistcsv.IssueListCsv,
+ urls.ISSUE_REINDEX: issuereindex.IssueReindex,
+ urls.ISSUE_DETAIL: issuedetail.IssueDetail,
+ urls.ISSUE_COMMENT_DELETION_JSON: issuedetail.IssueCommentDeletion,
+ urls.ISSUE_ATTACHMENT_DELETION_JSON:
+ issueattachment.IssueAttachmentDeletion,
+ urls.ISSUE_FLAGSPAM_JSON: spam.FlagSpamForm,
+ urls.ISSUE_SETSTAR_JSON: issuedetail.SetStarForm,
+ urls.ISSUE_DELETE_JSON: issuedetail.IssueDeleteForm,
+ urls.ISSUE_ENTRY: issueentry.IssueEntry,
+ urls.ISSUE_OPTIONS_JSON: issueoptions.IssueOptionsJSON,
+ urls.ISSUE_TIPS: issuetips.IssueSearchTips,
+ urls.ISSUE_ATTACHMENT: issueattachment.AttachmentPage,
+ urls.ISSUE_ATTACHMENT_TEXT: issueattachmenttext.AttachmentText,
+ urls.ISSUE_BULK_EDIT: issuebulkedit.IssueBulkEdit,
+ urls.COMPONENT_CHECKNAME_JSON: componentcreate.CheckComponentNameJSON,
+ urls.COMPONENT_CREATE: componentcreate.ComponentCreate,
+ urls.COMPONENT_DETAIL: componentdetail.ComponentDetail,
+ urls.FIELD_CHECKNAME_JSON: fieldcreate.CheckFieldNameJSON,
+ urls.FIELD_CREATE: fieldcreate.FieldCreate,
+ urls.FIELD_DETAIL: fielddetail.FieldDetail,
+ urls.WIKI_LIST: wikiredirect.WikiRedirect,
+ urls.WIKI_PAGE: wikiredirect.WikiRedirect,
+ urls.ADMIN_STATUSES: issueadmin.AdminStatuses,
+ urls.ADMIN_LABELS: issueadmin.AdminLabels,
+ urls.ADMIN_RULES: issueadmin.AdminRules,
+ urls.ADMIN_TEMPLATES: issueadmin.AdminTemplates,
+ urls.ADMIN_COMPONENTS: issueadmin.AdminComponents,
+ urls.ADMIN_VIEWS: issueadmin.AdminViews,
+ urls.ISSUE_ORIGINAL: issueoriginal.IssueOriginal,
+ urls.ISSUE_EXPORT: issueexport.IssueExport,
+ urls.ISSUE_EXPORT_JSON: issueexport.IssueExportJSON,
+ urls.ISSUE_IMPORT: issueimport.IssueImport,
+ urls.SPAM_MODERATION_QUEUE: spam.ModerationQueue,
+ })
+
+ self._SetupUserServlets({
+ urls.SAVED_QUERIES: savedqueries.SavedQueries,
+ })
+
+ # These servlets accept POST, but never write to the database, so they can
+ # still be used when the site is read-only.
+ self._SetupProjectServlets({
+ urls.ISSUE_ADVSEARCH: issueadvsearch.IssueAdvancedSearch,
+ }, post_does_write=False)
+
+ list_redir = registerpages_helpers.MakeRedirectInScope(
+ urls.ISSUE_LIST, 'p')
+ self._SetupProjectServlets({
+ '': list_redir,
+ '/': list_redir,
+ '/issues': list_redir,
+ '/issues/': list_redir,
+ })
+
+ list_redir = registerpages_helpers.MakeRedirect(urls.ISSUE_LIST)
+ self._SetupServlets({
+ '/issues': list_redir,
+ '/issues/': list_redir,
+ })
+
+ def _RegisterFrameworkHandlers(self):
+ """Register page and form handlers for framework functionality."""
+ self._SetupServlets({
+ urls.CSP_REPORT: csp_report.CSPReportPage,
+ urls.TOKEN_REFRESH: tokenrefresh.TokenRefresh,
+
+ # These are only shown to users iff specific conditions are met.
+ urls.NONPROJECT_COLLISION: artifactcollision.ArtifactCollision,
+ urls.EXCESSIVE_ACTIVITY: excessiveactivity.ExcessiveActivity,
+ urls.BANNED: banned.Banned,
+ urls.PROJECT_MOVED: moved.ProjectMoved,
+
+ # These are not externally accessible
+ urls.RAMCACHE_CONSOLIDATE_CRON: cachemanager_svc.RamCacheConsolidate,
+ urls.REAP_CRON: reap.Reap,
+ urls.SPAM_DATA_EXPORT_CRON: spammodel.TrainingDataExport,
+ })
+
+ self._SetupProjectServlets({
+ # Collisions can happen on artifacts within a project or outside.
+ urls.ARTIFACT_COLLISION: artifactcollision.ArtifactCollision,
+ })
+
+ def _RegisterSitewideHandlers(self):
+ """Register page and form handlers that aren't associated with projects."""
+ self._SetupServlets({
+ urls.PROJECT_CREATE: projectcreate.ProjectCreate,
+ urls.CHECK_PROJECT_NAME_JSON: projectcreate.CheckProjectNameJSON,
+ # The user settings page is a site-wide servlet, not under /u/.
+ urls.USER_SETTINGS: usersettings.UserSettings,
+ urls.USER_PROJECTS_JSON: userprojects.ProjectsJsonFeed,
+ urls.HOSTING_HOME: hostinghome.HostingHome,
+ urls.STARS_JSON: stars.SetStarsFeed,
+ urls.CUES_JSON: cues.SetCuesFeed,
+ urls.GROUP_CREATE: groupcreate.GroupCreate,
+ urls.GROUP_LIST: grouplist.GroupList,
+ urls.GROUP_DELETE: grouplist.GroupList,
+ })
+
+ self._SetupUserServlets({
+ urls.USER_PROFILE: userprofile.UserProfile,
+ urls.USER_UPDATES_PROJECTS: userupdates.UserUpdatesProjects,
+ urls.USER_UPDATES_DEVELOPERS: userupdates.UserUpdatesDevelopers,
+ urls.USER_UPDATES_MINE: userupdates.UserUpdatesIndividual,
+ })
+
+ profile_redir = registerpages_helpers.MakeRedirectInScope(
+ urls.USER_PROFILE, 'u')
+ self._SetupUserServlets({'': profile_redir})
+
+ self._SetupGroupServlets({
+ urls.GROUP_DETAIL: groupdetail.GroupDetail,
+ urls.GROUP_ADMIN: groupadmin.GroupAdmin,
+ })
+
+ def _RegisterRedirects(self):
+ """Register redirects among pages inside monorail."""
+ redirect = registerpages_helpers.MakeRedirect('/hosting/')
+ self._SetupServlets({
+ '/hosting': redirect,
+ '/p': redirect,
+ '/p/': redirect,
+ '/u': redirect,
+ '/u/': redirect,
+ '/': redirect,
+ })
+
+ redirect = registerpages_helpers.MakeRedirectInScope(
+ urls.PEOPLE_LIST, 'p')
+ self._SetupProjectServlets({
+ '/people': redirect,
+ '/people/': redirect,
+ })
+
+ redirect = registerpages_helpers.MakeRedirect(urls.GROUP_LIST)
+ self._SetupServlets({'/g': redirect})
+
+ group_redir = registerpages_helpers.MakeRedirectInScope(
+ urls.USER_PROFILE, 'g')
+ self._SetupGroupServlets({'': group_redir})
+
+ def _RegisterInboundMail(self):
+ """Register a handler for inbound email."""
+ self.routes.append(webapp2.Route(
+ '/_ah/mail/<project_addr:.+>',
+ handler=inboundemail.InboundEmail,
+ methods=['POST', 'GET']))
+
+ def _RegisterErrorPages(self):
+ """Register handlers for errors."""
+ self._AddRoute(
+ '/p/<project_name:%s>/<unrecognized:.+>' % self._PROJECT_NAME_REGEX,
+ custom_404.ErrorPage, 'GET')
+
« no previous file with comments | « appengine/monorail/queue.yaml ('k') | appengine/monorail/search/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698