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