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