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