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