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