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