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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « appengine/monorail/queue.yaml ('k') | appengine/monorail/search/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered 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 """This file sets up all the urls for monorail pages."""
7
8 import logging
9
10 import webapp2
11
12 import settings
13
14 from features import autolink
15 from features import cues
16 from features import filterrules
17 from features import inboundemail
18 from features import notify
19 from features import savedqueries
20 from features import spammodel
21 from features import stars
22
23 from framework import artifactcollision
24 from framework import banned
25 from framework import csp_report
26 from framework import excessiveactivity
27 from framework import reap
28 from framework import registerpages_helpers
29 from framework import tokenrefresh
30 from framework import urls
31
32 from project import peopledetail
33 from project import peoplelist
34 from project import projectadmin
35 from project import projectadminadvanced
36 from project import projectexport
37 from project import projectsummary
38 from project import projectupdates
39 from project import wikiredirect
40
41 from search import backendnonviewable
42 from search import backendsearch
43
44 from services import cachemanager_svc
45
46 from sitewide import custom_404
47 from sitewide import groupadmin
48 from sitewide import groupcreate
49 from sitewide import groupdetail
50 from sitewide import grouplist
51 from sitewide import hostinghome
52 from sitewide import moved
53 from sitewide import projectcreate
54 from sitewide import userprofile
55 from sitewide import userprojects
56 from sitewide import usersettings
57 from sitewide import userupdates
58
59 from tracker import componentcreate
60 from tracker import componentdetail
61 from tracker import fieldcreate
62 from tracker import fielddetail
63 from tracker import issueadmin
64 from tracker import issueadvsearch
65 from tracker import issueattachment
66 from tracker import issueattachmenttext
67 from tracker import issuebulkedit
68 from tracker import issuedetail
69 from tracker import issueentry
70 from tracker import issuelist
71 from tracker import issuelistcsv
72 from tracker import issueoptions
73 from tracker import issueoriginal
74 from tracker import issueexport
75 from tracker import issueimport
76 from tracker import issuereindex
77 from tracker import issuetips
78 from tracker import spam
79
80
81 class ServletRegistry(object):
82
83 _PROJECT_NAME_REGEX = r'[a-z0-9][-a-z0-9]*[a-z0-9]'
84 _USERNAME_REGEX = r'[-+\w=.%]+(@([a-z0-9]+\.)*[a-z0-9]+)?'
85
86 def __init__(self):
87 self.routes = []
88
89 def _AddRoute(self, path_regex, servlet_class, method, does_write=False):
90 """Add a GET or POST handler to our webapp2 route list.
91
92 Args:
93 path_regex: string with webapp2 URL template regex.
94 servlet_class: a subclass of class Servlet.
95 method: string 'GET' or 'POST'.
96 does_write: True if the servlet could write to the database, we skip
97 registering such servlets when the site is in read_only mode. GET
98 handlers never write. Most, but not all, POST handlers do write.
99 """
100 if settings.read_only and does_write:
101 logging.info('Not registring %r because site is read-only', path_regex)
102 # TODO(jrobbins): register a helpful error page instead.
103 else:
104 self.routes.append(
105 webapp2.Route(path_regex, handler=servlet_class, methods=[method]))
106
107 def _SetupServlets(self, spec_dict, base='', post_does_write=True):
108 """Register each of the given servlets."""
109 for get_uri, servlet_class in spec_dict.items():
110 self._AddRoute(base + get_uri, servlet_class, 'GET')
111 post_uri = get_uri + ('edit.do' if get_uri.endswith('/') else '.do')
112 self._AddRoute(base + post_uri, servlet_class, 'POST',
113 does_write=post_does_write)
114
115 def _SetupProjectServlets(self, spec_dict, post_does_write=True):
116 """Register each of the given servlets in the project URI space."""
117 self._SetupServlets(
118 spec_dict, base='/p/<project_name:%s>' % self._PROJECT_NAME_REGEX,
119 post_does_write=post_does_write)
120
121 def _SetupUserServlets(self, spec_dict, post_does_write=True):
122 """Register each of the given servlets in the user URI space."""
123 self._SetupServlets(
124 spec_dict, base='/u/<viewed_username:%s>' % self._USERNAME_REGEX,
125 post_does_write=post_does_write)
126
127 def _SetupGroupServlets(self, spec_dict, post_does_write=True):
128 """Register each of the given servlets in the user group URI space."""
129 self._SetupServlets(
130 spec_dict, base='/g/<viewed_username:%s>' % self._USERNAME_REGEX,
131 post_does_write=post_does_write)
132
133 def Register(self, services):
134 """Register all the monorail request handlers."""
135 self._RegisterFrameworkHandlers()
136 self._RegisterSitewideHandlers()
137 self._RegisterProjectHandlers()
138 self._RegisterIssueHandlers()
139 self._RegisterRedirects()
140 self._RegisterInboundMail()
141 autolink.RegisterAutolink(services)
142 # Error pages should be the last to register.
143 self._RegisterErrorPages()
144 logging.info('Finished registering monorail handlers.')
145 return self.routes
146
147 def _RegisterProjectHandlers(self):
148 """Register page and form handlers that operate within a project."""
149 self._SetupProjectServlets({
150 urls.ADMIN_INTRO: projectsummary.ProjectSummary,
151 urls.PEOPLE_LIST: peoplelist.PeopleList,
152 urls.PEOPLE_DETAIL: peopledetail.PeopleDetail,
153 urls.PEOPLE_DETAIL_PREFS_JSON: peopledetail.PagePrefs,
154 urls.UPDATES_LIST: projectupdates.ProjectUpdates,
155 urls.ADMIN_META: projectadmin.ProjectAdmin,
156 urls.ADMIN_ADVANCED: projectadminadvanced.ProjectAdminAdvanced,
157 urls.ADMIN_EXPORT: projectexport.ProjectExport,
158 urls.ADMIN_EXPORT_JSON: projectexport.ProjectExportJSON,
159 })
160
161 def _RegisterIssueHandlers(self):
162 """Register page and form handlers for the issue tracker."""
163 self._SetupServlets({
164 # Note: there is both a site-wide and per-project issue list.
165 urls.ISSUE_LIST: issuelist.IssueList,
166
167 # Note: the following are at URLs that are not externaly accessible.
168 urls.BACKEND_SEARCH: backendsearch.BackendSearch,
169 urls.BACKEND_NONVIEWABLE: backendnonviewable.BackendNonviewable,
170 urls.RECOMPUTE_DERIVED_FIELDS_TASK:
171 filterrules.RecomputeDerivedFieldsTask,
172 urls.REINDEX_QUEUE_CRON: filterrules.ReindexQueueCron,
173 urls.NOTIFY_ISSUE_CHANGE_TASK: notify.NotifyIssueChangeTask,
174 urls.NOTIFY_BLOCKING_CHANGE_TASK: notify.NotifyBlockingChangeTask,
175 urls.NOTIFY_BULK_CHANGE_TASK: notify.NotifyBulkChangeTask,
176 urls.OUTBOUND_EMAIL_TASK: notify.OutboundEmailTask,
177 urls.SPAM_DATA_EXPORT_TASK: spammodel.TrainingDataExportTask,
178 })
179
180 self._SetupProjectServlets({
181 urls.ISSUE_LIST: issuelist.IssueList,
182 urls.ISSUE_LIST_CSV: issuelistcsv.IssueListCsv,
183 urls.ISSUE_REINDEX: issuereindex.IssueReindex,
184 urls.ISSUE_DETAIL: issuedetail.IssueDetail,
185 urls.ISSUE_COMMENT_DELETION_JSON: issuedetail.IssueCommentDeletion,
186 urls.ISSUE_ATTACHMENT_DELETION_JSON:
187 issueattachment.IssueAttachmentDeletion,
188 urls.ISSUE_FLAGSPAM_JSON: spam.FlagSpamForm,
189 urls.ISSUE_SETSTAR_JSON: issuedetail.SetStarForm,
190 urls.ISSUE_DELETE_JSON: issuedetail.IssueDeleteForm,
191 urls.ISSUE_ENTRY: issueentry.IssueEntry,
192 urls.ISSUE_OPTIONS_JSON: issueoptions.IssueOptionsJSON,
193 urls.ISSUE_TIPS: issuetips.IssueSearchTips,
194 urls.ISSUE_ATTACHMENT: issueattachment.AttachmentPage,
195 urls.ISSUE_ATTACHMENT_TEXT: issueattachmenttext.AttachmentText,
196 urls.ISSUE_BULK_EDIT: issuebulkedit.IssueBulkEdit,
197 urls.COMPONENT_CHECKNAME_JSON: componentcreate.CheckComponentNameJSON,
198 urls.COMPONENT_CREATE: componentcreate.ComponentCreate,
199 urls.COMPONENT_DETAIL: componentdetail.ComponentDetail,
200 urls.FIELD_CHECKNAME_JSON: fieldcreate.CheckFieldNameJSON,
201 urls.FIELD_CREATE: fieldcreate.FieldCreate,
202 urls.FIELD_DETAIL: fielddetail.FieldDetail,
203 urls.WIKI_LIST: wikiredirect.WikiRedirect,
204 urls.WIKI_PAGE: wikiredirect.WikiRedirect,
205 urls.ADMIN_STATUSES: issueadmin.AdminStatuses,
206 urls.ADMIN_LABELS: issueadmin.AdminLabels,
207 urls.ADMIN_RULES: issueadmin.AdminRules,
208 urls.ADMIN_TEMPLATES: issueadmin.AdminTemplates,
209 urls.ADMIN_COMPONENTS: issueadmin.AdminComponents,
210 urls.ADMIN_VIEWS: issueadmin.AdminViews,
211 urls.ISSUE_ORIGINAL: issueoriginal.IssueOriginal,
212 urls.ISSUE_EXPORT: issueexport.IssueExport,
213 urls.ISSUE_EXPORT_JSON: issueexport.IssueExportJSON,
214 urls.ISSUE_IMPORT: issueimport.IssueImport,
215 urls.SPAM_MODERATION_QUEUE: spam.ModerationQueue,
216 })
217
218 self._SetupUserServlets({
219 urls.SAVED_QUERIES: savedqueries.SavedQueries,
220 })
221
222 # These servlets accept POST, but never write to the database, so they can
223 # still be used when the site is read-only.
224 self._SetupProjectServlets({
225 urls.ISSUE_ADVSEARCH: issueadvsearch.IssueAdvancedSearch,
226 }, post_does_write=False)
227
228 list_redir = registerpages_helpers.MakeRedirectInScope(
229 urls.ISSUE_LIST, 'p')
230 self._SetupProjectServlets({
231 '': list_redir,
232 '/': list_redir,
233 '/issues': list_redir,
234 '/issues/': list_redir,
235 })
236
237 list_redir = registerpages_helpers.MakeRedirect(urls.ISSUE_LIST)
238 self._SetupServlets({
239 '/issues': list_redir,
240 '/issues/': list_redir,
241 })
242
243 def _RegisterFrameworkHandlers(self):
244 """Register page and form handlers for framework functionality."""
245 self._SetupServlets({
246 urls.CSP_REPORT: csp_report.CSPReportPage,
247 urls.TOKEN_REFRESH: tokenrefresh.TokenRefresh,
248
249 # These are only shown to users iff specific conditions are met.
250 urls.NONPROJECT_COLLISION: artifactcollision.ArtifactCollision,
251 urls.EXCESSIVE_ACTIVITY: excessiveactivity.ExcessiveActivity,
252 urls.BANNED: banned.Banned,
253 urls.PROJECT_MOVED: moved.ProjectMoved,
254
255 # These are not externally accessible
256 urls.RAMCACHE_CONSOLIDATE_CRON: cachemanager_svc.RamCacheConsolidate,
257 urls.REAP_CRON: reap.Reap,
258 urls.SPAM_DATA_EXPORT_CRON: spammodel.TrainingDataExport,
259 })
260
261 self._SetupProjectServlets({
262 # Collisions can happen on artifacts within a project or outside.
263 urls.ARTIFACT_COLLISION: artifactcollision.ArtifactCollision,
264 })
265
266 def _RegisterSitewideHandlers(self):
267 """Register page and form handlers that aren't associated with projects."""
268 self._SetupServlets({
269 urls.PROJECT_CREATE: projectcreate.ProjectCreate,
270 urls.CHECK_PROJECT_NAME_JSON: projectcreate.CheckProjectNameJSON,
271 # The user settings page is a site-wide servlet, not under /u/.
272 urls.USER_SETTINGS: usersettings.UserSettings,
273 urls.USER_PROJECTS_JSON: userprojects.ProjectsJsonFeed,
274 urls.HOSTING_HOME: hostinghome.HostingHome,
275 urls.STARS_JSON: stars.SetStarsFeed,
276 urls.CUES_JSON: cues.SetCuesFeed,
277 urls.GROUP_CREATE: groupcreate.GroupCreate,
278 urls.GROUP_LIST: grouplist.GroupList,
279 urls.GROUP_DELETE: grouplist.GroupList,
280 })
281
282 self._SetupUserServlets({
283 urls.USER_PROFILE: userprofile.UserProfile,
284 urls.USER_UPDATES_PROJECTS: userupdates.UserUpdatesProjects,
285 urls.USER_UPDATES_DEVELOPERS: userupdates.UserUpdatesDevelopers,
286 urls.USER_UPDATES_MINE: userupdates.UserUpdatesIndividual,
287 })
288
289 profile_redir = registerpages_helpers.MakeRedirectInScope(
290 urls.USER_PROFILE, 'u')
291 self._SetupUserServlets({'': profile_redir})
292
293 self._SetupGroupServlets({
294 urls.GROUP_DETAIL: groupdetail.GroupDetail,
295 urls.GROUP_ADMIN: groupadmin.GroupAdmin,
296 })
297
298 def _RegisterRedirects(self):
299 """Register redirects among pages inside monorail."""
300 redirect = registerpages_helpers.MakeRedirect('/hosting/')
301 self._SetupServlets({
302 '/hosting': redirect,
303 '/p': redirect,
304 '/p/': redirect,
305 '/u': redirect,
306 '/u/': redirect,
307 '/': redirect,
308 })
309
310 redirect = registerpages_helpers.MakeRedirectInScope(
311 urls.PEOPLE_LIST, 'p')
312 self._SetupProjectServlets({
313 '/people': redirect,
314 '/people/': redirect,
315 })
316
317 redirect = registerpages_helpers.MakeRedirect(urls.GROUP_LIST)
318 self._SetupServlets({'/g': redirect})
319
320 group_redir = registerpages_helpers.MakeRedirectInScope(
321 urls.USER_PROFILE, 'g')
322 self._SetupGroupServlets({'': group_redir})
323
324 def _RegisterInboundMail(self):
325 """Register a handler for inbound email."""
326 self.routes.append(webapp2.Route(
327 '/_ah/mail/<project_addr:.+>',
328 handler=inboundemail.InboundEmail,
329 methods=['POST', 'GET']))
330
331 def _RegisterErrorPages(self):
332 """Register handlers for errors."""
333 self._AddRoute(
334 '/p/<project_name:%s>/<unrecognized:.+>' % self._PROJECT_NAME_REGEX,
335 custom_404.ErrorPage, 'GET')
336
OLDNEW
« 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