]> git.ipfire.org Git - people/jschlag/pbs.git/blame - src/web/__init__.py
Move mirror templates into own subdirectory
[people/jschlag/pbs.git] / src / web / __init__.py
CommitLineData
9137135a 1#!/usr/bin/python
a90bd9b0 2# encoding: utf-8
9137135a
MT
3
4import logging
51db04b0 5import multiprocessing
9137135a
MT
6import os.path
7import tornado.httpserver
8import tornado.locale
9import tornado.options
10import tornado.web
11
57859ebc 12from .. import Backend
4b9167ef 13from ..decorators import *
57859ebc 14
2c909128 15from . import handlers_api
9137135a 16
2c909128
MT
17from .handlers import *
18from .ui_modules import *
35c46db4 19
9137135a 20# Enable logging
97144eb5 21tornado.options.define("debug", default=False, help="Run in debug mode", type=bool)
9137135a
MT
22tornado.options.parse_command_line()
23
24class Application(tornado.web.Application):
754243af 25 def __init__(self, **_settings):
9137135a 26 settings = dict(
97144eb5 27 debug = tornado.options.options.debug,
2b229cb1 28 gzip = True,
9137135a 29 login_url = "/login",
027a662e
MT
30 template_path = TEMPLATESDIR,
31 static_path = STATICDIR,
9137135a 32 ui_modules = {
f6e6ff79
MT
33 "Text" : TextModule,
34 "Modal" : ModalModule,
35
36 "Footer" : FooterModule,
37
38 # Logging
39 "Log" : LogModule,
40 "LogEntry" : LogEntryModule,
41 "LogEntryComment" : LogEntryCommentModule,
42
f96eb5ed
MT
43 # Builders
44 "BuildersLoad" : BuildersLoadModule,
45
f6e6ff79
MT
46 "BuildHeadline" : BuildHeadlineModule,
47 "BuildStateWarnings" : BuildStateWarningsModule,
48
49 "BugsTable" : BugsTableModule,
50 "BuildLog" : BuildLogModule,
51 "BuildOffset" : BuildOffsetModule,
52 "BuildTable" : BuildTableModule,
4b1e87c4
MT
53
54 # Changelog
55 "Changelog" : ChangelogModule,
56 "ChangelogEntry" : ChangelogEntryModule,
57
6e63ed49
MT
58 # Jobs
59 "JobsList" : JobsListModule,
eedc6432 60 "JobsStatus" : JobsStatusModule,
6e63ed49 61
5669a87f
MT
62 # Packages
63 "PackagesDependencyTable" : PackagesDependencyTableModule,
64
b9d096e0 65 "CommitMessage" : CommitMessageModule,
f6e6ff79 66 "CommitsTable" : CommitsTableModule,
3c7e0537
MT
67 "JobsBoxes" : JobsBoxesModule,
68 "JobState" : JobStateModule,
f6e6ff79 69 "JobsTable" : JobsTableModule,
f6e6ff79
MT
70 "CommentsTable" : CommentsTableModule,
71 "FilesTable" : FilesTableModule,
72 "LogTable" : LogTableModule,
73 "LogFilesTable" : LogFilesTableModule,
74 "Maintainer" : MaintainerModule,
75 "PackagesTable" : PackagesTableModule,
76 "PackageTable2" : PackageTable2Module,
77 "PackageHeader" : PackageHeaderModule,
78 "PackageFilesTable" : PackageFilesTableModule,
79 "RepositoryTable" : RepositoryTableModule,
80 "RepoActionsTable" : RepoActionsTableModule,
81 "SourceTable" : SourceTableModule,
82 "UpdatesTable" : UpdatesTableModule,
83 "UsersTable" : UsersTableModule,
84 "WatchersSidebarTable" : WatchersSidebarTableModule,
cd870d0a 85
eedc6432
MT
86 "HeadingDate" : HeadingDateModule,
87
cd870d0a
MT
88 "SelectLocale" : SelectLocaleModule,
89 "SelectTimezone" : SelectTimezoneModule,
9137135a 90 },
bc293d03 91 ui_methods = {
a90bd9b0 92 "format_eta" : self.format_eta,
bc293d03
MT
93 "format_time" : self.format_time,
94 },
9137135a
MT
95 xsrf_cookies = True,
96 )
754243af 97 settings.update(_settings)
9137135a
MT
98
99 # Load translations.
2b5a3b4d 100 tornado.locale.load_gettext_translations(LOCALEDIR, PACKAGE_NAME)
9137135a 101
754243af 102 tornado.web.Application.__init__(self, [
9137135a
MT
103 # Entry site that lead the user to index
104 (r"/", IndexHandler),
105
106 # Handle all the users logins/logouts/registers and stuff.
107 (r"/login", LoginHandler),
108 (r"/logout", LogoutHandler),
109 (r"/register", RegisterHandler),
f6e6ff79
MT
110 (r"/password-recovery", PasswordRecoveryHandler),
111
112 # User profiles
9137135a 113 (r"/users", UsersHandler),
f6e6ff79
MT
114 (r"/user/impersonate", UserImpersonateHandler),
115 (r"/user/(\w+)/passwd", UserPasswdHandler),
116 (r"/user/(\w+)/delete", UserDeleteHandler),
117 (r"/user/(\w+)/edit", UserEditHandler),
118 (r"/user/(\w+)/activate", ActivationHandler),
9137135a 119 (r"/user/(\w+)", UserHandler),
9137135a 120 (r"/profile", UserHandler),
f6e6ff79 121 (r"/profile/builds", UsersBuildsHandler),
9137135a
MT
122
123 # Packages
124 (r"/packages", PackageListHandler),
f6e6ff79 125 (r"/package/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", PackageDetailHandler),
01197c1d 126 (r"/package/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/download(.*)", PackageFileDownloadHandler),
de4e09a5 127 (r"/package/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/view(.*)", PackageFileViewHandler),
d22eae24 128 (r"/package/([\w\-\+]+)", PackageNameHandler),
a15d6139 129 (r"/package/([\w\-\+]+)/builds/scratch", PackageScratchBuildsHandler),
bc293d03 130 (r"/package/([\w\-\+]+)/builds/times", PackageBuildsTimesHandler),
d22eae24
MT
131 (r"/package/([\w\-\+]+)/changelog", PackageChangelogHandler),
132 (r"/package/([\w\-\+]+)/properties", PackagePropertiesHandler),
9137135a
MT
133
134 # Files
135 (r"/file/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", FileDetailHandler),
136
137 # Builds
f6e6ff79 138 (r"/builds", BuildsHandler),
9137135a 139 (r"/builds/filter", BuildFilterHandler),
f6e6ff79 140 (r"/builds/queue", BuildQueueHandler),
62c7e7cd
MT
141 (r"/builds/comments", BuildsCommentsHandler),
142 (r"/builds/comments/(\w+)", BuildsCommentsHandler),
9137135a 143 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", BuildDetailHandler),
f6e6ff79
MT
144 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/bugs", BuildBugsHandler),
145 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/manage", BuildManageHandler),
146 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/comment", BuildDetailCommentHandler),
147 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/priority", BuildPriorityHandler),
148 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/state", BuildStateHandler),
149 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/watch", BuildWatchersAddHandler),
150 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/watchers", BuildWatchersHandler),
151 (r"/build/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/delete", BuildDeleteHandler),
152
153 # Jobs
9177f86a
MT
154 (r"/jobs", JobsIndexHandler),
155 (r"/jobs/filter", JobsFilterHandler),
f6e6ff79
MT
156 (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", JobDetailHandler),
157 (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/abort", JobAbortHandler),
158 (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/buildroot", JobBuildrootHandler),
159 (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/schedule", JobScheduleHandler),
9137135a
MT
160
161 # Builders
162 (r"/builders", BuilderListHandler),
163 (r"/builder/new", BuilderNewHandler),
f6e6ff79
MT
164 (r"/builder/([A-Za-z0-9\-\.]+)/enable", BuilderEnableHander),
165 (r"/builder/([A-Za-z0-9\-\.]+)/disable", BuilderDisableHander),
166 (r"/builder/([A-Za-z0-9\-\.]+)/delete", BuilderDeleteHandler),
167 (r"/builder/([A-Za-z0-9\-\.]+)/edit", BuilderEditHandler),
168 (r"/builder/([A-Za-z0-9\-\.]+)/renew", BuilderRenewPassphraseHandler),
9137135a
MT
169 (r"/builder/([A-Za-z0-9\-\.]+)", BuilderDetailHandler),
170
9137135a 171 # Distributions
f6e6ff79
MT
172 (r"/distros", DistributionListHandler),
173 (r"/distro/([A-Za-z0-9\-\.]+)", DistributionDetailHandler),
174
175 # XXX THOSE URLS ARE DEPRECATED
9137135a
MT
176 (r"/distribution/delete/([A-Za-z0-9\-\.]+)", DistributionDetailHandler),
177 (r"/distribution/edit/([A-Za-z0-9\-\.]+)", DistributionEditHandler),
f6e6ff79
MT
178
179 (r"/distro/([A-Za-z0-9\-\.]+)/repo/([A-Za-z0-9\-]+)",
180 RepositoryDetailHandler),
181 (r"/distro/([A-Za-z0-9\-\.]+)/repo/([A-Za-z0-9\-]+)\.repo",
182 RepositoryConfHandler),
183 (r"/distro/([A-Za-z0-9\-\.]+)/repo/([A-Za-z0-9\-]+)/mirrorlist",
184 RepositoryMirrorlistHandler),
185 (r"/distro/([A-Za-z0-9\-\.]+)/repo/([A-Za-z0-9\-]+)/edit",
186 RepositoryEditHandler),
187
188 (r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)",
189 DistroSourceDetailHandler),
190 (r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)/commits",
191 DistroSourceCommitsHandler),
192 (r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)/([\w]{40})",
193 DistroSourceCommitDetailHandler),
194 (r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)/([\w]{40})/reset",
195 DistroSourceCommitResetHandler),
196
197 (r"/distro/([A-Za-z0-9\-\.]+)/update/create",
198 DistroUpdateCreateHandler),
199 (r"/distro/([A-Za-z0-9\-\.]+)/update/(\d+)/(\d+)",
200 DistroUpdateDetailHandler),
201
202 # Updates
203 (r"/updates", UpdatesHandler),
204
205 # Mirrors
206 (r"/mirrors", MirrorListHandler),
207 (r"/mirror/new", MirrorNewHandler),
208 (r"/mirror/([A-Za-z0-9\-\.]+)/delete", MirrorDeleteHandler),
209 (r"/mirror/([A-Za-z0-9\-\.]+)/edit", MirrorEditHandler),
210 (r"/mirror/([A-Za-z0-9\-\.]+)", MirrorDetailHandler),
211
212 # Key management
213 (r"/keys", KeysListHandler),
214 (r"/key/import", KeysImportHandler),
215 (r"/key/([A-Z0-9]+)", KeysDownloadHandler),
216 (r"/key/([A-Z0-9]+)/delete", KeysDeleteHandler),
217
218 # Statistics
219 (r"/statistics", StatisticsMainHandler),
9137135a
MT
220
221 # Documents
222 (r"/documents", DocsIndexHandler),
223 (r"/documents/builds", DocsBuildsHandler),
224 (r"/documents/users", DocsUsersHandler),
f6e6ff79 225 (r"/documents/what-is-the-pakfire-build-service", DocsWhatsthisHandler),
9137135a
MT
226
227 # Search
228 (r"/search", SearchHandler),
229
f6e6ff79
MT
230 # Uploads
231 (r"/uploads", UploadsHandler),
9137135a
MT
232
233 # Log
234 (r"/log", LogHandler),
9137135a 235
20d7f5eb
MT
236 # Sessions
237 (r"/sessions", SessionsHandler),
238
35c46db4
MT
239 # API handlers
240 (r"/api/packages/autocomplete", handlers_api.ApiPackagesAutocomplete),
754243af 241 ], **settings)
9137135a
MT
242
243 logging.info("Successfully initialied application")
244
4b9167ef
MT
245 @lazy_property
246 def backend(self):
247 """
248 Backend connection
249 """
250 return Backend()
f6e6ff79 251
9137135a
MT
252 def __del__(self):
253 logging.info("Shutting down application")
254
255 @property
256 def ioloop(self):
257 return tornado.ioloop.IOLoop.instance()
258
259 def shutdown(self, *args):
260 logging.debug("Caught shutdown signal")
261 self.ioloop.stop()
262
51db04b0 263 def run(self, port=7001):
9137135a
MT
264 logging.debug("Going to background")
265
9137135a
MT
266 http_server = tornado.httpserver.HTTPServer(self, xheaders=True)
267
268 # If we are not running in debug mode, we can actually run multiple
269 # frontends to get best performance out of our service.
51db04b0 270 if self.settings.get("debug", False):
9137135a 271 http_server.listen(port)
51db04b0
MT
272 else:
273 cpu_count = multiprocessing.cpu_count()
274
275 http_server.bind(port)
276 http_server.start(num_processes=cpu_count)
9137135a 277
f6e6ff79
MT
278 # All requests should be done after 60 seconds or they will be killed.
279 self.ioloop.set_blocking_log_threshold(60)
280
9137135a
MT
281 self.ioloop.start()
282
283 def reload(self):
284 logging.debug("Caught reload signal")
bc293d03
MT
285
286 ## UI methods
287
a90bd9b0
MT
288 def format_eta(self, handler, (s, stddev)):
289 if s is None:
290 _ = handler.locale.translate
291 return _("Unknown")
292
293 if s < 0:
294 s = 0
295
747786f1 296 return u"%s ± %s" % (
a90bd9b0 297 self.format_time(handler, s),
96a1c465 298 self.format_time_short(handler, stddev / 2),
a90bd9b0
MT
299 )
300
7514d7dc 301 def format_time(self, handler, s, shorter=False):
bc293d03
MT
302 _ = handler.locale.translate
303
304 hrs, s = divmod(s, 3600)
305 min, s = divmod(s, 60)
306
307 if s >= 30:
308 min += 1
309
7514d7dc
MT
310 if shorter and not hrs:
311 return _("%(min)d min") % { "min" : min }
312
bc293d03 313 return _("%(hrs)d:%(min)02d hrs") % {"hrs" : hrs, "min" : min}
a90bd9b0
MT
314
315 def format_time_short(self, handler, s):
316 _ = handler.locale.translate
317
318 hrs = s / 3600
319 if hrs >= 1:
320 return _("%dh") % hrs
321
322 min = s / 60
323 if min >= 1:
324 return _("%dm") % min
325
326 return _("%ds") % s